Skip to content

squad nap can trim a tracked history.md into a history-archive.md that git never commits #2349

Closed

Description

@joslat

squad nap compresses an agent's history.md once it passes 15 KB. It appends the older ## sections to history-archive.md and rewrites history.md with the rest (compressHistory, packages/squad-cli/src/cli/core/nap.ts:160-259). Unlike decision archival, it never checks where the archive lands or whether the append worked.

When .squad/ is excluded from git through .git/info/exclude (the setup behind #1783), a new history-archive.md is ignored while history.md is tracked. The trim stages with git add -u but the archive doesn't, so after the next commit the archived sections are gone from the repo. git status shows only the modified history.md.

Repro

This uses the same setup test/cli/nap-archival-safety.test.ts uses for decisions. I committed a repo with .squad/agents/fenster/history.md (12 sections, over 15 KB), added .squad/ to .git/info/exclude, and ran squad nap:

  • nap reports Compressed fenster/history.md: kept 5 entries, archived 7;
  • git status --porcelain shows only M .squad/agents/fenster/history.md;
  • after git add -u && git commit, 5 of the 12 sections are left in the repo.

archiveDecisions has had both guards since #1792 (nap.ts:446-480). Rule 1 refuses a destination that can't be committed (isCommittableDestination), and Rule 2 verifies the append before trimming the source. With #2325, squad doctor now flags broken archive pointers after the fact; this change would stop nap from creating the problem in the first place.

It matters more once #2322 lands, because squad nap then becomes the only thing that compacts history. Tamir pointed it out in his review of that PR.

Proposal

Give compressHistory the same two rules, with one difference from decisions: refuse only when history.md itself would be committed. If .squad/ is ignored as a whole (nothing tracked), there's nothing to lose, and refusing would just stop nap from ever compressing. Decision archival refuses in that case today; I'd leave that alone here.

I have a PR ready.

Activity

  1. added a commit that references this issue on Oct 28, 2026
    c5e2c83
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions