Skip to content

refactor: Drop Last Updated column — idempotent 2-column memory indexes (ugde)#446

Open
sahil-noon wants to merge 5 commits into
mainfrom
260625-ugde-memory-index-drop-date-column
Open

refactor: Drop Last Updated column — idempotent 2-column memory indexes (ugde)#446
sahil-noon wants to merge 5 commits into
mainfrom
260625-ugde-memory-index-drop-date-column

Conversation

@sahil-noon

Copy link
Copy Markdown
Collaborator

Meta

ID Type Confidence Plan Review
ugde refactor 4.9/5.0 19/19 tasks, 22/22 acceptance ✓ ✓ 3 cycles

Pipeline: intake ✓ → apply ✓ → review ✓ → hydrate ✓ → ship → review-pr

Impact:
impl: +200/−141 (net +59)
tests: +103/−127 (net +-24)
total: +303/−268 (net +35) ← excludes fab/, docs/

Summary

fab memory-index was emitting a 3-column domain index table with a "Last Updated" cell computed from git log author dates (HEAD/branch-relative). Because git log -1 -- <file> is stable only for a fixed HEAD, regenerating the same index on a different branch (or after a rebase) projects a different date snapshot for unchanged files — causing content-identical indexes to diverge. This violated Constitution III (Idempotent Operations) and was the root cause of loom PR #1846's "lots of date-only changes" pattern.

This PR fixes the problem by dropping the "Last Updated" column entirely: domain indexes are now 2-column (| File | Description |), making them a pure function of file names and descriptions — genuinely branch-independent and idempotent. Dated, change-attributed history continues to live in the per-folder freeze-on-write log.md, which is the correct home for per-entry timestamps. Bumps kit version to 2.7.0 with a migration guide that re-baselines existing repos.

Changes

  • Go renderer (src/go/fab/internal/memoryindex/memoryindex.go): RenderDomain drops the third column; removes now-dead date plumbing (FileEntry.LastUpdated, gitDates.byPath, (*gitDates).lookup, gitLastUpdated) while keeping the batched git log pass (still needed by log.md generation)
  • --check parser + classifier (indexparse.go, loss.go): updated to expect 2-column domain rows so tombstone/description/grouping detection continues to work after the format change
  • CLI help text (src/go/fab/cmd/fab/memory_index.go): removed references to "stamping Last Updated from git" in the Long description and tier-1 example
  • Tests (internal/memoryindex/*_test.go): golden fixtures, render tests, and loss tests updated to 2-column format per Constitution VII (tests conform to spec)
  • Specs + kit-reference mirrors (docs/specs/fkf.md, src/kit/reference/fkf.md, docs/specs/templates.md, docs/specs/skills/SPEC-*.md): updated to remove 3-column domain table references, reword git-date claims, and align with the new 2-column contract
  • Memory docs (docs/memory/**): 5 domain index.md files regenerated in 2-column form; 7 prose files updated to reflect the change
  • Version bump: src/kit/VERSION → 2.7.0; new migration src/kit/migrations/2.6.6-to-2.7.0.md with re-baseline instructions
  • git-pr sub-step 3a-bis: retained in the skill spec but narrowed — the post-commit refresh is now a no-op for indexes (content-only; no date to re-stamp); log.md remains the only file that may change on regen

Dogfooding note

fab-kit's own docs/memory/**/index.md files are committed in 2-column form (built from this PR's source). The installed 2.6.6 binary would regenerate them as 3-column until 2.7.0 is released and installed — do not run fab memory-index on this branch with the 2.6.6 binary, as it will corrupt the deliverable.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes fab memory-index branch-independent and idempotent by removing the domain/sub-domain index “Last Updated” column (a HEAD-relative git log projection) and updating the renderer, --check parsing/classification, tests, and documentation/migrations accordingly.

Changes:

  • Drop the third “Last Updated” column from generated domain/sub-domain index tables and remove the now-dead date plumbing from the index path in Go.
  • Update --check parsing/classification and refresh all related unit/golden tests for the 2-column format (while remaining tolerant of legacy 3-column rows).
  • Sweep specs/skills/memory docs, regenerate committed docs/memory/**/index.md files to 2-column format, and add a 2.6.6→2.7.0 migration + version bump.

Reviewed changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/memory/_shared/index.md Regenerated domain index to 2-column format and removed git-date note.
docs/memory/pipeline/index.md Regenerated domain index to 2-column format and removed git-date note.
docs/memory/distribution/kit-architecture.md Updated architecture prose to reflect dateless indexes + git pass serving log.md only.
docs/memory/distribution/migrations.md Cataloged the new 2.6.6→2.7.0 migration and updated frontmatter description.
docs/memory/pipeline/execution-skills.md Narrowed /git-pr 3a-bis rationale to log.md (index no longer date-driven) and updated hydrate text.
docs/memory/distribution/index.md Regenerated domain index to 2-column format and removed git-date note.
docs/memory/memory-docs/hydrate-generate.md Updated guidance to describe dateless index regeneration.
docs/memory/memory-docs/hydrate.md Updated index ownership + maintenance prose to remove index date sourcing claims.
docs/memory/memory-docs/index.md Regenerated domain index to 2-column format and removed git-date note.
docs/memory/memory-docs/templates.md Updated templates/prose to describe content-only indexes and git pass usage for log.md.
docs/memory/pipeline/schemas.md Updated schema prose to remove byPath/index-date projection and describe commitsByPath only.
docs/memory/runtime/index.md Regenerated domain index to 2-column format and removed git-date note.
docs/specs/templates.md Updated spec templates/examples and rationale to remove “Last Updated” column.
docs/specs/fkf.md Updated FKF spec to define dateless domain/sub-domain indexes and adjust conformance wording.
docs/specs/skills/SPEC-docs-reorg-memory.md Updated SPEC mirror to remove “Last Updated” references and clarify dateless index behavior.
docs/specs/skills/SPEC-git-pr.md Updated SPEC mirror rationale for 3a-bis to be log.md-only.
fab/changes/260625-ugde-memory-index-drop-date-column/.history.jsonl Added change audit trail.
fab/changes/260625-ugde-memory-index-drop-date-column/.status.yaml Added pipeline status metadata for the change.
fab/changes/260625-ugde-memory-index-drop-date-column/intake.md Added intake artifact documenting rationale, scope, and sweep class.
fab/changes/260625-ugde-memory-index-drop-date-column/plan.md Added plan artifact with requirements/tasks/acceptance for the refactor + migration.
src/go/fab/cmd/fab/memory_index.go Updated CLI help text to describe content-only indexes and remove index git-stamping references.
src/go/fab/internal/memoryindex/golden_test.go Updated golden render expectations for 2-column domain indexes.
src/go/fab/internal/memoryindex/indexparse.go Updated parser doc comment to match 2-column domain rows while ignoring trailing cells.
src/go/fab/internal/memoryindex/loss.go Updated classifier doc comment to remove “refreshed date” from benign drift examples.
src/go/fab/internal/memoryindex/loss_test.go Updated loss-classifier fixtures/tests to 2-column domain rows and added legacy-row tolerance test.
src/go/fab/internal/memoryindex/memoryindex.go Dropped LastUpdated column rendering and removed index-only date plumbing; kept batched git pass for log.md.
src/go/fab/internal/memoryindex/memoryindex_test.go Updated renderer/gather/git-log tests for dateless indexes and collapsed parseGitLog signature.
src/kit/VERSION Bumped kit version to 2.7.0.
src/kit/migrations/2.6.6-to-2.7.0.md Added migration guide to re-baseline existing repos to 2-column index format.
src/kit/reference/fkf.md Updated normative reference mirror of FKF to match dateless index contract.
src/kit/skills/_cli-fab.md Updated CLI reference docs for fab memory-index to remove index date behavior and narrow git-pass usage.
src/kit/skills/docs-hydrate-memory.md Updated skill prose to remove index “Last Updated” guidance and git-date sourcing claims for indexes.
src/kit/skills/fab-continue.md Updated skill prose to remove “Last Updated” references in regeneration guidance.
src/kit/skills/git-pr.md Narrowed 3a-bis rationale to log.md and updated failure-mode description accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +56
( cd "$probe" && fab memory-index >/dev/null 2>&1 )
if grep -q 'Last Updated' "$probe/docs/memory/probe/index.md" 2>/dev/null; then
echo 'Aborted: this migration needs fab >= 2.7.0 (the two-column memory index). Upgrade the binary first: brew upgrade fab-kit.'
rm -rf "$probe"
exit 1
fi

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — the probe now aborts when the generated index is missing too, not only when it contains a Last Updated header: added an explicit [ ! -f … ] guard before the grep -q, so a binary that errors and writes nothing aborts the migration instead of silently continuing. This now matches the prose note directly below the snippet. (27a3bde)

Comment on lines 46 to 50
"and classifies drift by severity in the exit code: 0 = clean, 1 = benign " +
"drift (regen changes content but destroys nothing — all log.md / FKF " +
"drift (regen changes content but destroys nothing — an improved " +
"description:, all log.md / FKF " +
"frontmatter drift is benign; for log.md a benign FAIL means the committed " +
"log is missing a projected attributable (file-base, change-id) entry, or a " +

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — reworded the --check tier-1 help text to read "— e.g. an improved description:, or any log.md / FKF frontmatter drift", which removes the comma-splice run-on and backticks description: as inline code. (27a3bde)

@sahil-noon sahil-noon marked this pull request as ready for review June 25, 2026 11:04
sahil87 and others added 5 commits June 25, 2026 16:37
… indexes (ugde)

fab memory-index previously emitted a 3-column index table whose "Last Updated"
cell was computed from git commit dates (HEAD/branch-relative). This caused
content-identical indexes to differ across concurrent or un-rebased branches
(e.g., loom PR #1846), breaking idempotency and creating spurious diffs.

Fix: strip the "Last Updated" column entirely. Indexes are now 2-column
(File | Description). The dated history stays in log.md, which is the
correct home for per-entry timestamps. A 2.7.0 migration re-baselines
existing repos. Sub-step 3a-bis in git-pr is retained but narrowed to
log.md-only (index refresh is still a no-op when nothing drifted).

Includes: Go implementation + tests, spec/memory updates, VERSION bump to
2.7.0, migration guide, and change artifacts for 260625-ugde.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The rebase placed the change's own commit in history, so fab memory-index
projects its per-folder log.md entries (the post-commit projection 3a-bis
normally captures at ship). Generated with the 2.7.0 (2-column) binary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sahil87 sahil87 force-pushed the 260625-ugde-memory-index-drop-date-column branch from a325a66 to 2e737e9 Compare June 25, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants