Skip to content

feat: archive closed deferred-work entries so the ledger stays proportional to open work #706

Description

@jackmcintyre

Proposal: a bmad-loop archive command (or sweep sub-mode) that moves closed deferred-work entries out of the live ledger into a sibling archive file, keeping the live ledger small without losing the record.

Problem

The deferred-work ledger is append-only by design, which is right: DW- ids get cited across specs, decisions and story artifacts, so entries are annotated status: done in place rather than deleted. But nothing ever bounds the file, and on a multi-epic repo the cost curve is steep.

Real numbers from one repo:

  • Ledger size: ~369 KB (369,304 bytes)
  • Total entries: 216
  • Closed (status: done): 88 (41%)
  • Still open: 128

Every consequence is felt per-session, per-story:

  • Dev and review sessions are instructed to grep the ledger, never read it whole — the file is too large to load into context, which means agents work from search hits rather than the full record.
  • The sweep's TRIAGE pass scans the whole ledger even though closed entries are never actionable; 41% of the scan is dead weight today and the fraction only grows.
  • The repo's own header has to warn that the file is huge and that line references recorded in it go stale — friction every new session pays.

Selection flags exist or are proposed elsewhere (#651 sweep --only / --min-severity), but those choose which open entries to act on; they do not address the file's size.

Proposed behaviour

bmad-loop archive [--before <date>] [--dry-run]
  • Moves every status: done <date> entry whose close date is before the cutoff into an archive file beside the ledger (e.g. deferred-work-archive.md, or date-stamped parts).

  • Leaves a one-line stub in the live ledger per archived entry — enough to keep the DW- id greppable and any cross-references resolvable, e.g.:

    ### DW-35: CLOSED — waitlist addresses were captured nowhere (done 2026-08-04, archived 2026-08-24 → deferred-work-archive.md)
    
  • Deterministic Python, no LLM involvement — pure ledger parsing, same family as the existing migration/validation code paths.

Constraints the implementation must respect

  1. Commit boundary. Closure happens at the commit boundary (the closes_deferred mechanism). Archiving should respect the same boundary discipline — an archive pass must not run mid-story on a ledger a dev session may rewrite.
  2. Validator compatibility. The sweep's triage validator enforces the field vocabulary strictly (a malformed entry halts the run). Whatever stub form an archived entry leaves behind must still parse, or the validator must be taught to skip stubs.
  3. Id resolution. closes_deferred: [DW-5] declarations and prose citations across the repo must keep resolving after archiving — the stub line is what guarantees this, so the id and close date should survive in it.
  4. Idempotence and dry-run. Re-running archives nothing new; --dry-run prints the partition without writing, consistent with other read-then-write commands.

Benefit

Every long-running repo using the ledger hits this curve — the append-only design guarantees growth, and multi-epic runs accumulate closed entries faster than they retire open ones. Archiving keeps the live ledger proportional to outstanding work rather than to all history, which is the part sessions and sweeps actually need in view. It strengthens the human-AI loop in the same direction as the ledger itself: a smaller, accurate live file is one an agent can be trusted to read rather than grep.

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