diff --git a/.squad/agents/fenster/history.md b/.squad/agents/fenster/history.md index 02adfaac7..1276508e5 100644 --- a/.squad/agents/fenster/history.md +++ b/.squad/agents/fenster/history.md @@ -711,3 +711,16 @@ px tsx), it logs a test-mode warning but still validates config — useful for d - The squad-main-guard blocks ALL `.squad/` paths from protected branches — this is correct. Runtime state must be prevented at the commit stage, not the guard stage. - `.gitignore` is first-line defense (prevents staging new files) but doesn't help for already-tracked files. The `git reset HEAD` in the Scribe instruction is the belt-and-suspenders fix. - Four runtime state paths to always exclude: `orchestration-log/`, `log/`, `decisions/inbox/`, `sessions/` +### 2026-03-06: Fix version stamp overwrite during upgrade (#195) +**Requested by:** Brady (via issue #195, reported by @dnoriegagoodwin) +**PR:** #212 + +Root cause: `TEMPLATE_MANIFEST` loop in `upgrade.ts` includes `squad.agent.md` with `overwriteOnUpgrade: true`. The loop runs *after* `stampVersion()` writes the correct version, overwriting the stamped file with the raw template (`0.0.0-source`). Result: version never persists, `isAlreadyCurrent` never passes, all 30+ files re-copied on every upgrade. + +**Fix (1 line):** Added `&& f.source !== 'squad.agent.md'` to the manifest filter. `squad.agent.md` is already handled explicitly with copy + `stampVersion()` earlier in the function. + +**Test added:** Regression test verifying stamp survives the manifest loop and second upgrade reports "already current". + +## Learnings +- When a file needs post-copy transformation (like `stampVersion`), it must be excluded from bulk-copy loops that would overwrite the transformation. Any manifest with `overwriteOnUpgrade: true` that includes a file handled by explicit copy+transform is a race condition. +- The beta `index.js` doesn't use `TEMPLATE_MANIFEST` — it copies files individually with inline `stampVersion()` calls, so this bug only exists in the TypeScript CLI path. diff --git a/.squad/decisions/inbox/fenster-version-stamp-fix.md b/.squad/decisions/inbox/fenster-version-stamp-fix.md new file mode 100644 index 000000000..88554c06a --- /dev/null +++ b/.squad/decisions/inbox/fenster-version-stamp-fix.md @@ -0,0 +1,6 @@ +### Fix: squad.agent.md excluded from TEMPLATE_MANIFEST upgrade loop +**By:** Fenster (Core Dev) +**PR:** #212 (Closes #195) +**What:** `squad.agent.md` is now excluded from the `TEMPLATE_MANIFEST.filter(f => f.overwriteOnUpgrade)` loop in `upgrade.ts`. It is already handled explicitly with copy + `stampVersion()` earlier in the function. +**Why:** The manifest loop overwrites the version-stamped file with the raw template, resetting the version to `0.0.0-source`. This caused `isAlreadyCurrent` to never pass and all 30+ files to be re-copied on every upgrade. +**Impact:** Any future manifest entries that require post-copy transformation must also be excluded from the bulk loop and handled individually.