config-audit/commands/optimize.md
Kjell Tore Guttormsen e9921d3c9d feat(optimize): add --subtract, the subtraction axis, behind a deterministic floor
Every command so far asked an addition question — what to add, what to move,
what it costs. Nothing asked what is no longer earning its always-loaded rent.
This adds that axis as a fourth lensCheck on the existing hybrid motor rather
than a new scanner or a 22nd command: the measured payoff (~18% of one file)
justifies a mode, not machinery.

It is the only lens that proposes REMOVING config, so it carries a guarantee
the others don't need: a load-bearing block is never a candidate. Precision is
asymmetric — a missed dead line costs a few tokens per turn, a deleted one
costs a wrong remote or a broken script — so the floor is decided in code
(lib/floor-exclusion.mjs) before the opus judge sees anything, never in prose.

Granularity is the leaf block, with two structural exceptions: a paragraph
ending in ':' merges with the list it introduces, and an ordered list is a
contract whose steps inherit floor from any sibling. Unordered lists
deliberately do not inherit — a load-bearing bullet and a disposable one
routinely share a list, and container-reasoning is the error the hand-built
ground truth exists to catch.

Verified against that ground truth (built before any classifier existed), with
the comparison machine-checked rather than read by eye: zero load-bearing
blocks proposed, 11/18 deletable groups surfaced, ~756 tok ~ 18% of a ~4300
token file — inside the pre-registered band. The first run found five floor
violations the synthesized fixture missed; each got a structural rule and a
fixture shape so it cannot regress.

Three real bugs the dogfood run exposed, all now covered:
- JS \b is ASCII-only, so /\bunngå\b/ never matches — every Norwegian keyword
  ending in æ/ø/å was silently dead.
- A bare word/word is not a path; "pros/cons" vetoed the largest deletable
  block until PATH_RE was tightened to rooted paths and globs.
- "Mid-sentence" must key on a preceding lowercase letter; the loose version
  read **bold labels:** and quoted openers as entities, costing 4 of 11 groups.

BP-SUB-001 is grounded entirely in the Anthropic steering blog already cited by
BP-MECH-001..004 and asserts nothing from the talk that motivated the feature —
no "80%", no ablation figure.

Suite 1365 -> 1382/0. Frozen v5.0.0 snapshots untouched; plain optimize output
byte-identical on identical input (--subtract adds keys only when passed).
knowledge-refresh-cli's reference date moved to 2026-08-01: its premise that
every seed entry was verified 2026-06-20 expired when BP-SUB-001 got a genuine
verification date, and backdating the entry to fit the test would have been a
lie about when its source was checked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RW2haJXbxZpKivKHseSXNh
2026-07-31 16:24:51 +02:00

150 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: config-audit:optimize
description: Optimization lens — config that works but would fit a better mechanism (procedure→skill, lifecycle→hook, path→rule, never→permission)
argument-hint: "[path]"
allowed-tools: Read, Write, Glob, Grep, Bash, Agent
model: opus
---
# Config-Audit: Optimization Lens
The "is the config **optimal?**" axis (vs. the health scanners' "is it
**correct?**"). It finds configuration that *works* but uses a mechanism a
better one would fit — and frames every one as a *Missed opportunity*, never a
mistake.
Mechanism-fit rules come from the provenance-stamped best-practices register
(`knowledge/best-practices.json`); only CONFIRMED rules are surfaced. The motor
is hybrid: a cheap deterministic pre-filter finds candidates, then the opus
`optimization-lens-agent` judges each in context (precision-gated).
## What the user gets
- **Procedures → skills** (deterministic, CA-OPT-001)
- **Lifecycle phrasing → hooks** (BP-MECH-001)
- **Unscoped path-specific instructions → path-scoped rules** (BP-MECH-002)
- **Absolute "never" prohibitions → permissions / hooks** (BP-MECH-004)
- **`--subtract`:** instructions that no longer earn their always-loaded rent (BP-SUB-001)
Each finding cites its register rule + source URL. A clean CLAUDE.md returns "no
opportunities" — that is a good result, not a failure.
## Implementation
### Step 1: Determine target
Split `$ARGUMENTS` into a path (first non-flag argument; default: current working
directory) and flags. Recognized flags: `--global` (include the user `~/.claude`
cascade in discovery) and `--subtract` (add the subtraction axis, below).
**`--subtract` — the inverse question.** Every other lens asks what to *add* or
*move*; this one asks what no longer earns its always-loaded rent. It is opt-in
because it asks something different, and because deleting is not undoable by
reading. Pair it with `--global` to reach the user-level CLAUDE.md, where the
always-loaded cost actually sits (it loads in every repo, every session).
If `--subtract` is present, say so up front:
```
Also running the subtraction axis — instructions that cost tokens every turn
without telling me anything I couldn't work out. Load-bearing local facts
(remotes, versions, paths, policy) are excluded before anything is judged.
```
Tell the user:
```
## Optimization Lens
Looking for configuration that works but would fit a better Claude Code mechanism...
```
### Step 2: Run the lens CLI
Generate a session ID (`YYYYMMDD_HHmmss`) if no active session exists.
```bash
mkdir -p ~/.claude/config-audit/sessions/{session-id} 2>/dev/null
GLOBAL_FLAG=""
if echo "$ARGUMENTS" | grep -q -- "--global"; then GLOBAL_FLAG="--global"; fi
SUBTRACT_FLAG=""
if echo "$ARGUMENTS" | grep -q -- "--subtract"; then SUBTRACT_FLAG="--subtract"; fi
node ${CLAUDE_PLUGIN_ROOT}/scanners/optimize-lens-cli.mjs <target-path> --output-file ~/.claude/config-audit/sessions/{session-id}/optimize-lens.json $GLOBAL_FLAG $SUBTRACT_FLAG 2>/dev/null; echo $?
```
Exit code 0 is normal. Only exit code 3 is a real error → "The lens couldn't run.
Check that the path exists and contains a CLAUDE.md."
### Step 3: Read the payload
Read `~/.claude/config-audit/sessions/{session-id}/optimize-lens.json` with the
Read tool. It has `deterministic` (already-confirmed OPT findings), `candidates`
(pre-filter candidates with register provenance), `register`, and `counts`.
Under `--subtract` it also has a `subtract` block (`candidates`, `register`) and
`counts.subtractCandidates`. Each subtraction candidate spans `line``endLine`
(a whole block). Include the whole `subtract` block when spawning the agent.
**Early exit:** if `counts.deterministic === 0` and `counts.candidates === 0`
(and, under `--subtract`, `counts.subtractCandidates === 0`), skip the agent and
tell the user plainly:
```
✓ No mechanism-fit opportunities found.
Your CLAUDE.md holds facts, not procedures/automation/prohibitions that would be
better as skills, hooks, rules, or permissions. Nothing to change here.
```
Then go to Step 5.
### Step 4: Spawn the precision gate
Tell the user what's happening and set expectations:
```
Found {counts.candidates} candidate line(s) + {counts.deterministic} deterministic finding(s).
Asking the optimization-lens agent to judge each in context (~20-40 seconds)...
```
Spawn the `optimization-lens-agent` (Agent tool) with:
- the full payload from Step 3 (deterministic + candidates + register),
- the session directory path so it can write `optimization-lens-report.md`.
The agent reads the actual CLAUDE.md, drops low-confidence candidates, and keeps
only genuine opportunities — each citing its register rule + source.
### Step 5: Present results
Read the agent's `optimization-lens-report.md` and present it formatted
(markdown tables / grouped sections). Follow the UX rules: never show raw JSON or
scanner progress; lead with a one-sentence summary of what was found before the
detail. Make clear these are LOW-severity *opportunities*.
If the agent kept nothing from the candidates (all dropped) but there were
deterministic findings, show those; if it kept nothing at all, show the clean
result from Step 3.
### Step 6: Next steps
End with context-sensitive next steps, explaining WHY each is useful:
- `/config-audit plan` — turn the kept opportunities into an action plan with
backups before you change anything.
- `/config-audit feature-gap` — the complementary lens: features you *don't* use
yet (this command is about mechanisms you *do* use that could fit better).
- Re-run `/config-audit optimize` anytime after editing CLAUDE.md.
## Notes
- This command is **agent-driven and not byte-stable** — its output is a
human-facing report, deliberately outside the deterministic snapshot suite.
- `--subtract` **proposes, never writes.** Nothing is deleted; act on a finding
via `/config-audit plan``/config-audit implement` (backup + rollback).
- The subtraction floor is deterministic and runs *before* the agent, so a
load-bearing block is never a candidate. It errs toward keeping: on a
well-maintained config this axis is mostly a no-op, and that is a good result.
- The deterministic half (CA-OPT-001) also rides in the normal orchestrated
audit; this command adds the prose-judgment half on top.
- No files are modified. To act on a finding, use `/config-audit plan`
`/config-audit implement` (backup + rollback) or edit by hand.