diff --git a/CLAUDE.md b/CLAUDE.md index bdb48ad..f9e5474 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,7 @@ Analyzes and optimizes Claude Code configuration across three pillars: | `/config-audit plugin-health` | Audit plugin structure, frontmatter, cross-plugin coherence | | `/config-audit whats-active` | Read-only inventory of plugins, skills, MCP, hooks, CLAUDE.md active for a repo (with token estimates) | | `/config-audit knowledge-refresh` | Keep the best-practices register fresh — deterministic stale check (sources older than ~90d) + web candidate poll (CC changelog + Anthropic blog); **human-approved writes only** (Verifiseringsplikt). The "living" half of the knowledge base. Web/judgment-driven, **not byte-stable** | -| `/config-audit campaign` | Machine-wide audit campaign — durable ledger ABOVE sessions: per-repo lifecycle (pending→audited→planned→implemented) + machine-wide roll-up by severity + cross-repo prioritized backlog + plan **export** (drop a planned repo's plan into its own `docs/`), resumable across sessions. Read-only report (campaign-cli) + **human-approved** writes via deterministic write/export CLIs. THIN: tracks+routes state, reuses existing implement/rollback for execution. Judgment-driven, **not byte-stable** | +| `/config-audit campaign` | Machine-wide audit campaign — durable ledger ABOVE sessions: per-repo lifecycle (pending→audited→planned→implemented) + machine-wide roll-up by severity + **machine-wide always-loaded token bill** (`refresh-tokens` live cross-repo sweep — shared global layer counted once + per-repo deltas) + cross-repo prioritized backlog + plan **export** (drop a planned repo's plan into its own `docs/`), resumable across sessions. Read-only report (campaign-cli) + **human-approved** writes via deterministic write/export CLIs. THIN: tracks+routes state, reuses existing implement/rollback for execution. Judgment-driven, **not byte-stable** | | `/config-audit discover` | Run discovery phase only | | `/config-audit analyze` | Run analysis phase only | | `/config-audit interview` | Gather user preferences (opt-in) | diff --git a/README.md b/README.md index 8e03ea0..628407e 100644 --- a/README.md +++ b/README.md @@ -293,7 +293,7 @@ Your team configuration changes over time. Track it: | `/config-audit plugin-health` | Audit plugin structure, frontmatter, cross-plugin coherence | | `/config-audit whats-active` | Read-only inventory of plugins, skills, MCP, hooks, CLAUDE.md active for a repo (with token estimates) | | `/config-audit knowledge-refresh` | Keep the best-practices register fresh — flag stale entries (sources older than ~90d) + poll for new/changed Claude Code practices; **human-approved writes only** (Verifiseringsplikt). Deterministic stale core + web candidate poll | -| `/config-audit campaign` | Machine-wide audit campaign — durable ledger above sessions tracking each repo's lifecycle (pending → audited → planned → implemented) + a machine-wide roll-up by severity + a single **cross-repo prioritized backlog** to pick from (severity-weighted) + plan **export** (drop a planned repo's plan into its own `docs/`), resumable across sessions; **human-approved writes only** (read-only report + deterministic write/export CLIs). Execution reuses the existing `/config-audit implement` + `rollback` | +| `/config-audit campaign` | Machine-wide audit campaign — durable ledger above sessions tracking each repo's lifecycle (pending → audited → planned → implemented) + a machine-wide roll-up by severity + a **machine-wide always-loaded token bill** (`refresh-tokens` live cross-repo sweep — the shared global layer counted once + per-repo deltas, ranked "most expensive repos") + a single **cross-repo prioritized backlog** to pick from (severity-weighted) + plan **export** (drop a planned repo's plan into its own `docs/`), resumable across sessions; **human-approved writes only** (read-only report + deterministic write/export CLIs). Execution reuses the existing `/config-audit implement` + `rollback` | | `/config-audit discover` | Run discovery phase only | | `/config-audit analyze` | Run analysis phase only | | `/config-audit interview` | Set preferences for action plan _(optional)_ | diff --git a/commands/campaign.md b/commands/campaign.md index dbcecf0..134e5a1 100644 --- a/commands/campaign.md +++ b/commands/campaign.md @@ -1,7 +1,7 @@ --- name: config-audit:campaign description: Machine-wide audit campaign — track which repos are pending/audited/planned/implemented across sessions, with a machine-wide roll-up. Human-approved writes only. -argument-hint: "[init | add ... | set-status | export ]" +argument-hint: "[init | add ... | set-status | refresh-tokens | export ]" allowed-tools: Read, Write, Edit, Bash, Glob model: opus --- @@ -31,9 +31,12 @@ reinvent it. - **Read (report):** `scanners/campaign-cli.mjs` — loads + validates the ledger, emits the repo list + roll-up + backlog. Never writes. -- **Write (mutate):** `scanners/campaign-write-cli.mjs` — `init` / `add` / `set-status`, each a - thin wrapper over the invariant-enforcing lib transforms + save. Invoked **only** after the - user approves a specific action. +- **Write (mutate):** `scanners/campaign-write-cli.mjs` — `init` / `add` / `set-status` / + `refresh-tokens`, each a thin wrapper over the invariant-enforcing lib transforms + save. + Invoked **only** after the user approves a specific action. `refresh-tokens` is the live + cross-repo token sweep: it runs the manifest's always-loaded accounting across every tracked + repo and folds the result into the machine-wide token bill (shared global layer counted once + + per-repo deltas). - **Export:** `scanners/campaign-export-cli.mjs` — `--repo ` resolves the repo's linked session, reads its `action-plan.md`, and assembles a `docs/config-audit-plan-.md`. Read-only (a preview) by default; it writes the file **only** under `--write`, which is @@ -55,6 +58,7 @@ From `$ARGUMENTS`, pick the mode: - `add ...` → add one or more repo paths. - `add --discover ` → find git repos under `` and let the user pick which to add. - `set-status ` → transition a tracked repo (`status` ∈ pending/audited/planned/implemented). +- `refresh-tokens` → live cross-repo token sweep: compute the machine-wide always-loaded bill. - `export ` → export a planned repo's action plan into that repo's own `docs/`. - `help` → show this surface and stop. @@ -75,8 +79,8 @@ 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`), `rollUp {totalRepos, byStatus, bySeverity, -reposWithFindings}`, and `backlog[]` — the single cross-repo prioritized work list (each: +sessionId, findingsBySeverity, tokens, updatedDate`), `rollUp {totalRepos, byStatus, bySeverity, +reposWithFindings, tokens}`, 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). @@ -109,6 +113,30 @@ with `/config-audit` (audit), `/config-audit plan`, or `/config-audit implement` 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). +**Machine-wide token bill** — render from `rollUp.tokens` (the whole-machine always-loaded +accounting). Note the shape: `sharedGlobal`, `perRepoDelta`, and `machineWide` are flat +`{always, onDemand, external, unknown}` number maps; `byRepo[]` is `{name, path, always, +onDemand, external}` already sorted DESC by always-loaded cost; `reposWithTokens` is the count. + +If `reposWithTokens` is `0`, no sweep has run yet — say: "No token bill yet — run +`/config-audit campaign refresh-tokens` to compute the machine-wide always-loaded cost." and +omit the table. Otherwise lead with the headline and the once-vs-delta split: + +> **Always-loaded every turn, machine-wide: ~`machineWide.always` tokens** — `sharedGlobal.always` +> paid once (global config + installed plugins, in *every* repo) + `perRepoDelta.always` across +> `reposWithTokens` repos' own project config. + +Then the **most expensive repos** (their per-repo delta — what each adds beyond the shared layer): + +| # | Repo | Always-loaded delta | +|---|------|---------------------| +| 1 | `` | `` | + +Add one plain-language line so the number is actionable, e.g. "The shared global layer is the +biggest lever — trim `~/.claude/CLAUDE.md`, the global agent listing, or rarely-used plugins +to cut cost in every repo at once." The bill reflects the **last** sweep; re-run +`refresh-tokens` after config changes. + 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. @@ -175,7 +203,30 @@ node ${CLAUDE_PLUGIN_ROOT}/scanners/campaign-write-cli.mjs set-status /dev/null; echo $? +``` + +Exit **0** = swept (or nothing to sweep — a benign no-op on an empty campaign), **3** = no/corrupt +ledger. Read the result: `swept[]` (repos accounted for), `skipped[]` (each `{path, reason}`), and +the refreshed `rollUp.tokens`. Re-render the **Machine-wide token bill** (Step 2) with the new +numbers. If anything was skipped, name those repos plainly so the user knows the bill omits them +(honest coverage — Verifiseringsplikt). + +### Step 7 (mode `export`): Export a repo's plan to its own `docs/` — preview, approve, write "Planer følger arbeidsstedet": a planned repo's action plan belongs in **that repo's** `docs/`, not buried in a session dir. This step copies it there, byte-faithfully. @@ -216,7 +267,7 @@ Confirm: "Plan exported to ``." Then hand off to the **existing** ex > applies the plan, and verifies. To **undo**: `/config-audit rollback`. When done, record it: > `/config-audit campaign set-status implemented`. -### Step 7: Next steps +### Step 8: Next steps Tailor to where the campaign stands: @@ -229,6 +280,8 @@ Tailor to where the campaign stands: repo's own `docs/`, then `/config-audit implement` there to execute it (backup + verify)." - **Backlog has items:** point at the top backlog repo and the natural next verb for its status (audit → plan → export → implement). +- **No token bill yet (or config changed):** "`/config-audit campaign refresh-tokens` to compute + the machine-wide always-loaded cost — the shared global layer is the biggest lever." - Always: the campaign survives this session — re-run `/config-audit campaign` anytime to see the machine-wide picture. @@ -244,7 +297,9 @@ Tailor to where the campaign stands: and `knowledge-refresh`). - The `-cli` suffix keeps all three CLIs out of the scan-orchestrator, so the scanner count and the byte-stable snapshot suite are unaffected. -- **THIN scope:** ledger + roll-up + status + a cross-repo prioritized backlog + plan export. +- **THIN scope:** ledger + roll-up (findings + machine-wide token bill) + status + a cross-repo + prioritized backlog + plan export. The token sweep reuses the manifest's existing always-loaded + accounting per repo — it does not reinvent measurement, only aggregates it machine-wide. Execution is **not** reinvented here — `export` drops a planned repo's plan into its own `docs/` (a durable record), and the user runs the existing `/config-audit implement` (backup + apply + verify) + `/config-audit rollback` to execute and undo. This command tracks state and routes the