Repository navigation
fix(cli): keep squad nap from trimming history into an uncommittable archive - #2350
Conversation
…archive History compression appended the older sections of history.md to history-archive.md and rewrote history.md without the checks decision archival has. With .squad/ excluded from git, the new archive is ignored, so the trim committed and the archived sections never did. compressHistory now follows the same rules as archiveDecisions: - Rule 1: refuse when history.md would be committed but its archive could not be (isCommittableDestination). A .squad/ ignored as a whole still compresses, since nothing there reaches a commit; - Rule 2: rewrite history.md only after the archive gained every archived section, counted the same way the sections were split; nothing to archive means nothing to trim. Closes github#2349
🟡 Impact Analysis — PR #2350Risk tier: 🟡 MEDIUM 📊 Summary
🎯 Risk Factors
📦 Modules Affectedroot (1 file)
squad-cli (1 file)
tests (1 file)
This report is generated automatically for every PR. See #733 for details. |
🏗️ Architectural Review
Automated architectural review — informational only. |
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 2 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | No Copilot review threads |
| ❌ | CI passing | 15 check(s) still running |
Files Changed (3 files, +171 −6)
| File | +/− |
|---|---|
.changeset/nap-history-archive-guard.md |
+5 −0 |
packages/squad-cli/src/cli/core/nap.ts |
+52 −6 |
test/cli/nap-archival-safety.test.ts |
+114 −0 |
Total: +171 −6
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
|
About the bootstrap-area warning: this PR doesn't change any imports in |
What
squad naphistory compression now follows the same safety rules as decision archival. It won't trim ahistory.mdthat git will commit into ahistory-archive.mdthat git can't commit, and it rewriteshistory.mdonly after checking that the archive gained every archived section.Why
Closes #2349
With
.squad/excluded from git (the #1783 setup), nap appended the older sections to a new, ignoredhistory-archive.mdand trimmed the trackedhistory.md. The trim got committed and the archive didn't: in the repro, 5 of 12 sections were left after a normalgit add -ucommit, while nap reported success. Once #2322 lands,squad napis the only thing that compacts history, so this matters more (Tamir raised it on #2322).How
All in
packages/squad-cli/src/cli/core/nap.ts, incompressHistory. The comments refer toarchiveDecisionsso the two stay together.history.mdwould be committed but its archive couldn't be:isCommittableDestination(history) && !isCommittableDestination(archive). The action saysHistory compression refused: …and nothing is written..squad/is ignored as a whole and was never committed,history.mdis ignored too and there's nothing to lose. A destination-only check would refuse every compression in that setup (there's a test for it). I left decision archival as it is.##headings and compare them with the count before plus the archived sections. On a mismatch, abort and leavehistory.mduntouched./^##\s/match that splits the sections, so a##line inside a fence counts the same way on both sides.runNapandrunNapSyncpass the repo root the same wayarchiveDecisionsderives it (path.dirname(squadDir)).Dry runs are unchanged, matching decisions: the checks run only when files are written.
Testing
New tests in
test/cli/nap-archival-safety.test.ts, with real git repos, counting sections in the committed tree:.squad/excluded and no archive yet, no section is lost across a commit;history.mdis unchanged, no archive is created, andgit statusis clean;.squad/ignored as a whole and never committed, it still compresses;.squad/not excluded, it compresses normally.Results:
nap.tschange reverted, the first two fail. The others pass both ways, because they guard normal compression.nap-archival-safety,nap,cli/doctorandstate/archival: 145 passed.npm run lint: clean. ESLint on the changed files: 0 errors..changeset/nap-history-archive-guard.md, cli patch)PR Readiness Checklist
Branch & Commit
dev(notmain)dev(c3f54c2)Build & Test
npm run lintpassesDocs
Breaking Changes
None. Nap now refuses a compression that would have lost sections at the next commit, and reports it.
Waivers
None.