The optimize lens CLI fed its precision-gate agent every CLAUDE.md that discovery
returned, including the 256 files under ~/.claude/plugins/ — vendored plugin
CLAUDE.md across every cached version (7 config-audit, 6 ms-ai-architect, 5 okr,
...) plus their bundled tests/fixtures and examples. Running `optimize --global`
on this machine produced 454 candidates across 92 "files", ~250 of them sourced
from plugin-internal files a user cannot act on (the plugin overwrites them on
update). Same class as M-BUG-2: plugin-bundled config is not the user's cascade.
Second defect: candidates were keyed by `relPath || absPath`, but relPath
collides across scopes — a repo-root `CLAUDE.md` and the user-global
`~/.claude/CLAUDE.md` both relPath to `CLAUDE.md`. The two files that actually
matter were merged into one indistinguishable bucket (21 candidates), the agent's
Read(file) would resolve the wrong one, and cache-file relPaths were not readable
relative to cwd at all.
Fix (lens-CLI-local, surgical):
- Filter isPluginBundled (absPath under `.claude/plugins/`) from discovery for
BOTH halves of the motor (candidate loop + the OPT scanner, which reads
discovery.files directly). Drops vendored files regardless of active/stale
version, so excludeCache is unnecessary here.
- Key each candidate by absPath: unique + readable.
No change to file-discovery.mjs or the OPT scanner, so their byte-stable
snapshots are untouched.
Suite 1348/0 (+4: candidate scoping, real-config survives, deterministic scoping,
absolute-path identity). Frozen v5.0.0 + SC-5 snapshots untouched (the lens CLI
has no snapshot; the command is agent-driven, not byte-stable). Dogfood ~/.claude
`optimize --global`: candidates 454->45, deterministic 2->0 (both were stale
plugin-cache copies), distinct files 92->11, repo vs user-global now distinct
(12 + 9 = 21). Residual 45 includes config-audit's own tests/fixtures CLAUDE.md
(repo-specific dogfooding artifact, not a general bug — left alone).
The recall+precision halves of the CA-OPT hybrid motor for the three
mechanism-fit cases the deterministic OPT scanner (2a) deliberately skips:
lifecycle→hook (BP-MECH-001), unscoped path-specific→rule (BP-MECH-002),
absolute "never"→permission (BP-MECH-004).
New:
- scanners/lib/lens-prefilter.mjs — cheap, recall-oriented line scan of the
CLAUDE.md body; detector names mirror the register lensCheck fields; skips
fenced code, gates the path class on an instruction verb. Pure + 13 tests.
- scanners/optimize-lens-cli.mjs — discovery + OPT scanner + pre-filter; attaches
only the CONFIRMED register entry to each candidate (unverifiable → dropped,
Verifiseringsplikt); emits {deterministic, candidates, register, counts}.
- agents/optimization-lens-agent.md — opus precision gate (7th agent, orange):
reads the real CLAUDE.md, drops low-confidence candidates, keeps only genuine
opportunities, cites register id + source.
- commands/optimize.md — /config-audit optimize orchestrates pre-filter→agent→report.
Agent-driven → deliberately NOT byte-stable (own command, outside the snapshot
suite). No new orchestrated scanner → scanner count stays 15. Counts: agents
6→7, commands 18→19, suite 1055→1068. Self-audit A/A unchanged, readmeCheck
passed (clean HOME). Plan: docs/v5.7-optimization-lens-plan.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>