Context
PR #78 shipped burn archive build | rebuild | status but deliberately left vacuum off for the foundation PR:
burn archive vacuum (one-liner; trivial to add when needed).
Issue #40 lists vacuum in the proposed command set:
burn archive vacuum — runs SQLite maintenance if needed.
Over time, archive.sqlite accumulates free pages from INSERT OR REPLACE churn (every stamp re-fold rewrites turn rows; rebuild drops + recreates rows). Without periodic VACUUM, the on-disk file grows beyond what the row count implies. On a developer laptop this is fine for months; on a long-running CI/orchestration host it eventually becomes worth the one-shot reclaim.
Proposal
- Add a
vacuumArchive() function to packages/ledger/src/archive.ts that opens the archive, runs VACUUM, and reports before/after file size.
- Add a
burn archive vacuum subcommand in packages/cli/src/commands/archive.ts that calls it and prints a one-line summary (or JSON via --json):
archive: vacuumed 12.3 MB -> 4.1 MB (reclaimed 8.2 MB)
- Acquire the same lock the build path uses so we don't
VACUUM mid-build.
- No-op gracefully if the archive doesn't exist (print a hint to run
burn archive build first).
Tests:
- Vacuum reduces file size after a build/rebuild churn.
- Concurrent
vacuum + build serialize via the lock without corruption.
- Vacuum on a missing archive exits cleanly with a hint.
--json shape: { before_bytes, after_bytes, reclaimed_bytes }.
Acceptance criteria
Out of scope
- Auto-vacuum heuristics (e.g. vacuum after N rebuilds). Manual command first; automation later if measurements justify it.
- Schema changes.
Refs
Context
PR #78 shipped
burn archive build | rebuild | statusbut deliberately leftvacuumoff for the foundation PR:Issue #40 lists
vacuumin the proposed command set:Over time,
archive.sqliteaccumulates free pages fromINSERT OR REPLACEchurn (every stamp re-fold rewrites turn rows; rebuild drops + recreates rows). Without periodicVACUUM, the on-disk file grows beyond what the row count implies. On a developer laptop this is fine for months; on a long-running CI/orchestration host it eventually becomes worth the one-shot reclaim.Proposal
vacuumArchive()function topackages/ledger/src/archive.tsthat opens the archive, runsVACUUM, and reports before/after file size.burn archive vacuumsubcommand inpackages/cli/src/commands/archive.tsthat calls it and prints a one-line summary (or JSON via--json):VACUUMmid-build.burn archive buildfirst).Tests:
vacuum+buildserialize via the lock without corruption.--jsonshape:{ before_bytes, after_bytes, reclaimed_bytes }.Acceptance criteria
burn archive vacuumexists, documented in command help, and has unit + CLI tests.--json) includes before/after sizes.Out of scope
Refs
burn archive(#40) #78 (Derived analytics archive: materialize the ledger into a local queryable store #40 follow-up)