Wires the user-facing surface of the machine-wide token roll-up (executable CLI
shipped in B2b-2, d664b70). The campaign report (Step 2) now renders rollUp.tokens:
the headline machine-wide always-loaded total split into the shared global layer
(paid once, every repo) + per-repo deltas, plus a ranked 'most expensive repos'
table. New mode 'refresh-tokens' (Step 6) documents the human-approved live sweep —
idempotent, skips unreadable repos, names any skipped so the bill's coverage stays
honest (Verifiseringsplikt).
Shapes documented carefully: rollUp.tokens.{sharedGlobal,perRepoDelta,machineWide}
are flat number maps; byRepo[] is the ranked {name,path,always,...} list. campaign-cli
already emitted rollUp.tokens (B2a) — no reader change; this is rendering only.
commands/campaign.md (73 lines) is the primary doc; README + CLAUDE.md campaign rows
get the matching one-line summary. Markdown-only → suite unchanged at 1198 green;
campaign command stays judgment-driven (not byte-stable).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes Block 4 (4b backlog + 4c export/execution). Asymmetric: plan
export is new testable code; execution is pure reuse of the existing
per-repo implement/rollback (no new execution machinery), per the plan's
"reuse existing backup/rollback".
Plan export ("planer følger arbeidsstedet"):
- scanners/lib/campaign-export.mjs (pure, now injected, 8 tests):
planExportPath(repo,sessionId) -> <repo>/docs/config-audit-plan-<sessionId>.md
(sessionId-keyed so same-day re-audits never collide);
buildPlanExportDocument({...,now}) -> provenance header + verbatim plan.
- scanners/campaign-export-cli.mjs (-cli, read-only by default, 10 tests):
--repo resolves the repo's linked session, reads its action-plan.md,
assembles the doc, emits {exportable,problems,targetPath,document}. Two
gates -> exit 1 advisory: no-session-linked / no-action-plan. Writes the
file ONLY under opt-in --write (byte-faithful copy; the LLM never re-types
a 200-line plan). --sessions-dir override for hermetic tests; exit 0/1/3.
Command: commands/campaign.md gains an `export <path>` mode (Step 6:
preview -> approve -> --write), then routes the user to the existing
/config-audit implement (backup + verify) + rollback + set-status
implemented. Nothing auto-written (Verifiseringsplikt).
Byte-stable: lib + -cli + command-doc only -> scanner count stays 15,
agents 7, commands 21 (export is a mode, not a new command), SC-5 +
backcompat suite untouched. suite 1150->1168. Block 4a (migrateLedger)
still deferred to the first breaking schema change.
Docs: CLAUDE.md section + badge 1150->1168/65->67 files; README badge +
campaign row + Testing prose (fixed stale 1055/59 -> true 1168/67).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes the THIN machine-wide campaign surface (ledger + roll-up + status).
The write half of the campaign motor, mirroring how knowledge-refresh gates
register writes:
- scanners/campaign-write-cli.mjs (-cli → NOT a scanner; 11 tests): init/add/
set-status, each a thin wrapper over the invariant-enforcing lib transforms
(createLedger/addRepo/setRepoStatus) + saveLedger — path-normalization/dedup,
idempotent add, status-lifecycle guard and updatedDate bump never hand-rolled.
init refuses to clobber an existing/corrupt ledger (exit 1, file untouched);
add auto-inits + reports added vs skipped; set-status takes --findings/--session.
Deterministic: --reference-date is the only clock read, injected as `now`.
Exit 0=write, 1=advisory no-op, 3=error.
- commands/campaign.md (opus, no Web): thin orchestrator — always reports first
(read-only campaign-cli), then proposes init/add/set-status and invokes ONE
write-CLI subcommand only on explicit human approval (Verifiseringsplikt; never
hand-edits the JSON). add --discover finds git repos under a root to pick from.
Not byte-stable (own command, outside snapshot suite) like /config-audit optimize
+ knowledge-refresh. Both CLIs are -cli → scanner count stays 15, snapshot suite
untouched. commands 20→21, suite 1127→1138 (+11), test files 64→65.
Docs: CLAUDE.md §campaign-write-cli + command table + Testing badge; README
commands badge 20→21 + table row; help.md + router wiring.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>