Repository navigation
Description
Summary
When \stateBackend\ is \ wo-layer\ or \orphan, .squad/decisions.md\ and .squad/agents/*/history.md\ are owned by the \squad-state\ orphan branch. The pre-commit hook (\install-hooks.ts:110-127) refuses to commit them, but they can still be staged via \git add ., \git add -A, IDE \stage all\ gestures, or \git commit -am. The user then hits the pre-commit refusal and has to manually recover (see #1226 / PR #1227 for the documented recovery flow).
Proposal: add those paths to .gitignore\ automatically when the backend is \ wo-layer\ or \orphan, and remove them when switching back to \local. The pre-commit hook stays — defense in depth.
Behavior
| From | To | .gitignore\ action |
|---|---|---|
| init or migrate → \local\ | local | no-op (current behavior preserved) |
| init or migrate → \orphan\ | orphan | add marker block |
| init or migrate → \ wo-layer\ | two-layer | add marker block |
| orphan ↔ two-layer | (either) | no-op |
| orphan/two-layer → \local\ | local | remove marker block |
Entries added (delimited by marker comments so the block can be reliably removed):
\\
Squad: state owned by squad-state branch (two-layer/orphan backend)
.squad/decisions.md
.squad/agents/*/history.md
/Squad: state owned by squad-state branch
\\
Rationale
- Defense in depth. The pre-commit hook is a runtime guard; .gitignore\ is a configuration guard. Together they make the wrong thing actually hard to do.
- Removes the failure mode. Users won't stage these files via \git add .\ / IDE gestures → no pre-commit refusal → no recovery needed.
- Architecturally consistent. Under two-layer, on-disk copies are caches; caches belong in .gitignore\ (same logic as the existing .squad/.cache/\ entry).
- Atomic add/remove. The marker comments make the block trivially findable for the symmetric remove when switching backends.
Out of scope
- The pre-commit hook STAYS (it still catches \git add --force\ and edge cases).
- \local\ backend behavior is unchanged.
Acceptance criteria
- \initSquad({stateBackend: 'two-layer'})\ writes the marker block to .gitignore\
- \initSquad({stateBackend: 'orphan'})\ writes the marker block to .gitignore\
- \initSquad({stateBackend: 'local'})\ does NOT write the marker block (current behavior preserved)
- \squad upgrade --state-backend two-layer\ from local backend adds the block
- \squad upgrade --state-backend orphan\ from local backend adds the block
- \squad upgrade --state-backend local\ from two-layer/orphan removes the block
- Idempotent — running upgrade twice doesn't duplicate entries
- Round-trip (add then remove) leaves .gitignore\ byte-identical (modulo trailing newline)
- Unit + integration tests cover all of the above
- Documentation updated (\state-backends.md\ and \ roubleshooting.md\ — coordinate with PR docs(state-backends): document pre-commit hook, post-upgrade flow, and recovery #1227)
- Changeset added
Related
- Issue docs: state-backends upgrade flow misses pre-commit hook, file reappearance, and recovery #1226 + PR docs(state-backends): document pre-commit hook, post-upgrade flow, and recovery #1227 — documents the current pre-commit recovery flow; this issue makes that recovery flow rarely needed
Activity
fix(state-backend): conditional .gitignore entries for two-layer/orph…
fix(state-backend): conditional .gitignore entries for two-layer/orph…