feat(campaign): cross-repo prioritized backlog (v5.7 Fase 2 Block 4b)

buildBacklog(ledger) pure transform + read-only campaign-cli payload field
+ command rendering. The single machine-wide pick-list: per-repo (the ledger
tracks severity counts, not individual findings), severity-weighted
(SEVERITY_WEIGHTS c1000/h100/m10/l1), deterministic tie-break, excludes
implemented/pending/zero-finding repos.

No schema change, no new scanner -> scanner count stays 15, snapshot/backcompat
byte-stable. suite 1138->1150 (lib +9, campaign-cli +3). README badge 1091+->1150+.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-06-23 02:44:21 +02:00
commit 49833aded8
7 changed files with 263 additions and 10 deletions

View file

@ -20,9 +20,9 @@ Every mutation — creating the ledger, adding a repo, changing a status — is
and applied **only on explicit approval**, by invoking one deterministic write-CLI subcommand.
The command never hand-edits the ledger JSON.
This is the **THIN** campaign surface (ledger + roll-up + status). Cross-repo backlog
prioritization and execution are a later block — this command does not run audits or apply
fixes itself; it tracks where each repo stands.
This is the **THIN** campaign surface (ledger + roll-up + status + a cross-repo prioritized
backlog to pick from). Execution is a later block — this command does not run audits or apply
fixes itself; it tracks where each repo stands and shows what to tackle next.
## Two CLIs back this command
@ -65,8 +65,10 @@ attempt a write over a corrupt ledger.)
Read `~/.claude/config-audit/sessions/campaign-report.json` with the Read tool (per the UX
rules — never show the raw JSON). It has `initialized`, `repos[]` (each: `path, name, status,
sessionId, findingsBySeverity, updatedDate`), and `rollUp {totalRepos, byStatus, bySeverity,
reposWithFindings}`.
sessionId, findingsBySeverity, updatedDate`), `rollUp {totalRepos, byStatus, bySeverity,
reposWithFindings}`, and `backlog[]` — the single cross-repo prioritized work list (each:
`path, name, status, findingsBySeverity, totalFindings, weightedScore, rank`), already sorted
DESC by severity (most critical work first).
Present it as two short tables:
@ -84,6 +86,19 @@ Present it as two short tables:
| Repo | Status | Findings (C/H/M/L) | Last updated |
|------|--------|--------------------|--------------|
**Prioritized backlog** — the one cross-repo list to pick from, highest-severity work first.
Render `backlog[]` in `rank` order (it is already sorted); omit this table entirely when the
backlog is empty (nothing outstanding — say "Backlog clear — no outstanding findings across
tracked repos."). Implemented repos and repos with no known findings are deliberately absent.
| # | Repo | Status | Findings (C/H/M/L) | Total |
|---|------|--------|--------------------|-------|
After it, point the user at the top item: "Highest priority: **`<name>`** (`<status>`) — pick it
with `/config-audit` (audit), `/config-audit plan`, or `/config-audit implement` in that repo,
then record progress here with `set-status`." The backlog is a **pick-list**, not an executor —
this command does not run audits or fixes (that is the later execution block).
If `initialized` is false, say so plainly: "No campaign yet. Run `/config-audit campaign init`
to start one." Then — if the mode was `init` or `add` — continue to that step (those bootstrap
a campaign); for `report`/`set-status` on an uninitialized ledger, stop after this message.
@ -173,5 +188,6 @@ Tailor to where the campaign stands:
and `knowledge-refresh`).
- The `-cli` suffix keeps both CLIs out of the scan-orchestrator, so the scanner count and the
byte-stable snapshot suite are unaffected.
- **THIN scope:** ledger + roll-up + status only. Cross-repo backlog prioritization and execution
are a later block — this command tracks state, it does not run audits or apply fixes.
- **THIN scope:** ledger + roll-up + status + a read-only cross-repo prioritized backlog. The
backlog is a derived pick-list (`buildBacklog`, severity-weighted); execution is a later block —
this command tracks state and shows what to tackle next, it does not run audits or apply fixes.