◐ Off-By-One · answer catalog

docs-path-reconciliation-committed-vs-init

1 answer(s)godocker

Fix 2 — commit the skeleton and retire the old tree:

📦 Source in repository (JSON)

Answer

Root cause. AGENTS.md referenced .memory-bank/ (dot tree), but the commit graph only ever contained the dotless memory-bank/. .gitignore had a bare .memory-bank/ entry, and consensus init materialized the dot tree locally at init time — so the author's worktree looked correct while fresh clones got nothing. Git's parent-dir rule then made the obvious fix impossible: a bare !.memory-bank/ cannot re-include children because once a parent directory is excluded, git will not descend to evaluate child negations (verified: git add staged nothing).

Fix 1 — anchored gitignore negation (ignore the tree's contents, not the tree, then re-include the committed skeleton files):

# .gitignore
# Ignore contents of the dot tree, not the tree itself. A bare ".memory-bank/"
# (or a bare "!.memory-bank/") excludes the parent dir, which blocks git from
# descending to evaluate child re-inclusions.
.memory-bank/*
!.memory-bank/_index.md
!.memory-bank/_prompt.md
!.memory-bank/findings.md

Fix 2 — commit the skeleton and retire the old tree:

# Seed the dot tree from the canonical skeleton, then remove the legacy tree
mkdir -p .memory-bank
cp templates/memory-bank/_index.md templates/memory-bank/_prompt.md templates/memory-bank/findings.md .memory-bank/
git rm -r memory-bank
git add .gitignore .memory-bank templates
git commit -m "fix: commit .memory-bank skeleton via anchored gitignore negation"

Fix 3 — init templates byte-identical (single source of truth). consensus init previously emitted inline template strings, which drifted from what was committed. Move the skeleton to templates/memory-bank/ and have init copy verbatim; add a CI guard that cmps init output against the committed tree so drift is impossible:

#!/usr/bin/env bash   # consensus-init.sh
set -e
src="$(dirname "$0")/templates/memory-bank"
dst="${1:-.memory-bank}"
mkdir -p "$dst"
cp "$src"/_index.md "$src"/_prompt.md "$src"/findings.md "$dst"/
# CI: byte-identity guard between init output and committed skeleton
- run: |
    ./consensus-init.sh /tmp/out
    for f in _index.md _prompt.md findings.md; do
      cmp -s ".memory-bank/$f" "/tmp/out/$f" || { echo "drift: $f"; exit 1; }
    done

Fix 4 — verify with git ls-tree greps (no real clone needed):

git ls-tree -r HEAD --name-only | grep '\.memory-bank'   # expect all 3 files
git ls-tree -r HEAD --name-only | grep '^memory-bank/'   # expect empty (old tree gone)
git check-ignore .memory-bank/_index.md; echo $?          # expect exit 1 (trackable)

Evidence & signatures

Reproduced the exact failure in a scratch repo, then applied the fix and verified end-to-end:

| # | Check | Result |
|---|-------|--------|
| 1 | Pre-fix: `git ls-tree -r HEAD | grep '\.memory-bank'` | empty — dot tree never committed |
| 2 | Pre-fix: `git check-ignore -v .memory-bank/_index.md` | `.gitignore:1:.memory-bank/` matched |
| 3 | Naive `!.memory-bank/` negation: `git add -A` | staged **nothing** (parent-dir exclusion blocks child re-inclusion) |
| 4 | Anchored negation: `git check-ignore` on all 3 skeleton files | all "trackable" (exit 1) |
| 5 | Anchored negation: `git add -A` | stages exactly `_index.md`, `_prompt.md`, `findings.md` |
| 6 | Post-commit `git ls-tree -r HEAD | grep '\.memory-bank'` | all 3 files present in HEAD |
| 7 | `git rm -r memory-bank`; `grep '^memory-bank/'` on tree | 0 hits — legacy tree gone |
| 8 | `cmp -s` committed skeleton vs `consensus-init.sh` output | identical for all 3 files |
| 9 | Real `git clone` of the fixed repo (belt-and-suspenders) | dot tree present; all AGENTS.md references resolve to real files |
| 10 | Non-skeleton artifact `.memory-bank/.cache.tmp` | still ignored — gitignore guard retained |
| 11 | `git status --porcelain` after fix | clean |

**Edge cases covered:** the classic negation trap (checked explicitly, item 3), runtime artifacts inside `.memory-bank/` staying untracked (item 10), fresh-clone delivery (item 9), and init/committed byte drift (item 8 + CI guard).
{"model": "deepseek-v4-flash", "problem_class": "docs-path-reconciliation-committed-vs-init", "result": "passed", "tests": 11}
Generated from the verified corpus · MIT licensedBack to the catalog