Multi-agent workflow for analyzing, reporting, and optimizing Claude Code configuration across your entire machine
  • JavaScript 99.6%
  • HTML 0.4%
Find a file
Kjell Tore Guttormsen 36c55fb167 docs(plan): add the floor constraint — compensatory vs load-bearing (§6.0)
Operator corrected two things about the brief committed in 3086e8b/3252b51.

Provenance: the operator watched the recording and identifies Boris Cherny on
stage, so the attribution is confirmed by direct observation, not a channel's
claim. The verbatim figures (80 %, "more intelligent without the prompts") still
reach us through the summary's editing and stay at that confidence level. §1 now
carries both levels separately, and the register source string reflects the split
instead of flattening to "unverified".

Design: "start with what it must have" is the constraint the whole feature turns
on, so it is a hard constraint (§6.0), not a candidate-shape detail. Model
capability erodes compensatory instructions ("read the whole file first") and
does nothing to load-bearing local facts ("only Forgejo", "bash is 3.2", the test
command) — the model isn't failing at intelligence there, it cannot know. A tool
that treats them alike deletes the Forgejo constraint because Opus 5 "is smart
enough now". Rebuild is therefore three tiers: floor restored immediately, earned
returns on repeated stumbling, dead never comes back. Policy prohibitions stay in
the floor by decision rather than classification — asymmetric cost, cheap to keep.

Consequences threaded through: §5 disqualifies any shape that cannot express the
distinction, §7.2 becomes the core open question (age and class are independent
signals, so age alone can never carry the call), and §8 gains a blocking floor
test with a hand-built fasit and named must-survive items.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNrtHo9hKSLKNyMS6b4Zuy
2026-07-29 09:55:22 +02:00
.claude/rules feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
.claude-plugin release: v5.12.5 — "Dogfood denoise" (M-BUG-2/6/7/8/10 scanner false-positive batch) 2026-06-26 18:04:20 +02:00
agents fix(acr): pin Bash >> append discipline on shared implementation log (M-BUG-20) 2026-07-17 03:53:06 +02:00
commands fix(acr): pin Bash >> append discipline on shared implementation log (M-BUG-20) 2026-07-17 03:53:06 +02:00
docs docs(plan): add the floor constraint — compensatory vs load-bearing (§6.0) 2026-07-29 09:55:22 +02:00
examples fix(mcp-config-validator): remove invented trust field (verify-first) 2026-06-18 14:22:56 +02:00
hooks feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
knowledge feat(knowledge): best-practices register foundation — v5.7 Fase 1 Chunk 1 2026-06-20 22:37:47 +02:00
scanners fix(rul): globToRegex corrupts mid-pattern /**/ globs (M-BUG-19) 2026-07-17 03:53:06 +02:00
skills/config-hierarchy feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
templates feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
tests fix(acr): pin Bash >> append discipline on shared implementation log (M-BUG-20) 2026-07-17 03:53:06 +02:00
.config-audit-ignore feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
.gitignore chore(state): make STATE.md local-only — public open/ mirror must not carry state-of-play 2026-06-21 19:01:34 +02:00
CHANGELOG.md release: v5.12.5 — "Dogfood denoise" (M-BUG-2/6/7/8/10 scanner false-positive batch) 2026-06-26 18:04:20 +02:00
CLAUDE.md docs(claude-md): trim project CLAUDE.md to invariants (−662 always-tok) 2026-06-29 08:32:44 +02:00
GOVERNANCE.md docs: introduce GOVERNANCE.md and unify fork-and-own blurb 2026-05-03 14:57:00 +02:00
LICENSE feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
README.md release: v5.12.5 — "Dogfood denoise" (M-BUG-2/6/7/8/10 scanner false-positive batch) 2026-06-26 18:04:20 +02:00

Config-Audit Plugin for Claude Code

Know if your configuration is correct. Find what could improve it. Fix it automatically.

Solo-maintained, fork-and-own. This plugin is a starting point, not a vendor product. Issues are welcome as signals; pull requests are not accepted. See GOVERNANCE.md for the full model and what upstream provides.

AI-generated: all code produced by Claude Code through dialog-driven development. Full disclosure →

Version Platform Scanners Commands Agents Hooks Tests License

A Claude Code plugin that checks configuration health, suggests context-aware improvements, and auto-fixes issues — CLAUDE.md, settings.json, hooks, rules, MCP servers, @imports, and plugins. 16 deterministic scanners across 10 quality areas, context-aware feature recommendations, auto-fix with backup/rollback, a prompt-cache-aware Token Hotspots scanner with optional API-calibrated --accurate-tokens mode, plus cache-prefix stability, dead-tool, cross-plugin collision, output-style, and always-loaded agent-listing-budget detection. Zero external dependencies.


Table of Contents


What's New in v5.4.0

Plugin-hygiene & settings-validation hardening. Three additive findings extend the plugin and settings surfaces — no new scanner, so the count stays 13:

  • PLH plugin-folder shadowing (CA-PLH-015) — flags a plugin.json component-path key in the replaces set (commands/agents/outputStyles) that points at a custom path while the default folder of that name still exists, so the folder is silently ignored (dead config). Mirrors Claude Code's own warning in /doctor, claude plugin list, and the /plugin detail view. skills is excluded (it adds to the default scan, never shadows), as are hooks/mcpServers/lspServers (own merge rules); a custom path resolving into the default folder is not flagged.
  • PLH skills:-array validation (CA-PLH-016) — validates each plugin.json skills entry (string or array) resolves to an existing directory inside the plugin root; flags non-string, escapes-root, not-found, and not-a-directory entries. Mirrors claude plugin validate.
  • SET autoMode structure + dead-config — checks that autoMode is an object whose only keys are environment/allow/soft_deny/hard_deny, each a string array (the literal "$defaults" is valid); unknown sub-keys and wrong types are flagged (medium). Separately, autoMode placed in shared project settings (.claude/settings.json) is flagged as dead config (low) — Claude Code's classifier does not read it there.

All three extend existing PLH and SET scanners. --json and --raw output remain byte-stable.


What Is This?

Claude Code reads instructions from at least 7 different file types across multiple scopes: CLAUDE.md, settings.json, .claude/rules/, hooks.json, .mcp.json, .claudeignore, and settings.local.json. Each can exist at project level, user level, or both. Plugins add more. The system is powerful — but nobody tells you what you're using wrong, what you're missing, or what's silently conflicting.

This plugin provides three layers of configuration intelligence:

  • Health — 16 deterministic scanners verify correctness across every configuration file, catching broken imports, deprecated settings, conflicting rules, format errors, permission contradictions, prompt-cache token waste, cache-prefix instability, dead tool grants, cross-plugin skill collisions, output styles that silently strip Claude Code's coding instructions, an oversized always-loaded agent listing, and procedures in CLAUDE.md that would fit better as a skill
  • Opportunities — context-aware recommendations for Claude Code features that could benefit your specific project, backed by Anthropic's official guidance
  • Action — auto-fix with mandatory backups, syntax validation, rollback support, and a human-in-the-loop workflow for anything non-trivial

Tip

Start with /config-audit posture for a 30-second scorecard, then /config-audit for the full picture.


The Configuration Problem

You've been using Claude Code for weeks — maybe months. It works fine. But there's a gap between "works fine" and "configured well," and it's invisible until someone shows you.

These are not hypotheticals. They come from running the posture scanner on real setups:

  • Your global CLAUDE.md says "never use mocks" but a project rule says "prefer mocks" — Claude gets confused and you don't know why
  • You've written dozens of projects but have never set up hooks, rules, or keybindings because you didn't know they existed
  • Three plugins define hooks for the same event with conflicting behavior
  • Your settings.json has a deprecated key that silently does nothing
  • An @import in your CLAUDE.md points to a file you deleted last week
  • You're using maybe 30% of what Claude Code can do — and you don't know what the other 70% is

The plugin ships with two example projects. Run them yourself:

examples/minimal-setup/ — just a CLAUDE.md, nothing else

> node scanners/posture.mjs examples/minimal-setup/

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Config-Audit Health Score
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 Health: A (99/100)    7 areas scanned

 Area Scores
 ───────────
 CLAUDE.md ............ A (90)
 Settings ............. A (100)   Hooks ............... A (100)
 Rules ................ A (100)   MCP ................. A (100)
 Imports .............. A (100)   Conflicts ........... A (100)

 22 opportunities available — run /config-audit feature-gap for recommendations

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Grade A — nothing is broken. The health grade only reflects real issues, and this setup has none. The 22 opportunities are not failures — they're features you could use. Run /config-audit feature-gap to see which ones are relevant to your project.

examples/optimal-setup/ — full configuration across all 4 tiers

> node scanners/posture.mjs examples/optimal-setup/

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Config-Audit Health Score
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 Health: A (93/100)    7 areas scanned

 Area Scores
 ───────────
 CLAUDE.md ............ A (100)   Settings ............ A (90)
 Hooks ................ A (100)   Rules ............... B (80)
 MCP .................. A (90)    Imports ............. A (100)
 Conflicts ............ A (90)

 3 opportunities available — run /config-audit feature-gap for recommendations

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Also Grade A — with only 3 opportunities remaining. This project has CLAUDE.md split via @imports, permissions scoped to specific tools, path-scoped rules (different rules for src/ vs. tests/), hooks covering multiple events, and MCP servers. Both setups are healthy — the difference is how much of Claude Code's surface area you're choosing to use.


Quick Start

Prerequisites

  • Claude Code installed
  • Node.js 18+ (for standalone CLI tools)

Installation

Add the marketplace and browse plugins with /plugin:

claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git

Or enable directly in ~/.claude/settings.json:

{
  "enabledPlugins": {
    "config-audit@ktg-plugin-marketplace": true
  }
}

First Scan

# Full audit with auto-scope detection (inside Claude Code)
/config-audit

# 30-second posture check (standalone, no LLM needed)
node scanners/posture.mjs /path/to/project

# Auto-fix issues with backup
node scanners/fix-cli.mjs /path/to/project --apply

The CLI tools work standalone — no Claude Code session needed, just Node.js 18+.


Feature Opportunities — Context-Aware Recommendations

Most configuration tools stop at "is it valid?" Config-audit goes further: what could improve your setup, and is it relevant to your project?

The feature opportunity scanner checks 25 dimensions and groups recommendations by impact:

Impact Level Focus Examples
High Correctness & security permissions.deny for sensitive files, basic hooks for safety automation
Worth Considering Workflow efficiency Path-scoped rules, modular @imports, custom agents
Explore Nice-to-have Keybindings, status line, output styles, agent teams

Each recommendation is context-aware — it considers what your project actually contains. A solo TypeScript project gets different suggestions than a team Python monorepo. Recommendations include why (backed by Anthropic's official guidance) and how (concrete steps).

Run /config-audit feature-gap to see what's relevant to your project.


Workflow Examples

1. First Time — Just Curious

You heard about this plugin and want to know where you stand:

/config-audit                          # Auto-detects scope, runs full audit
                                       # → See your grade, top issues, and gaps
/config-audit posture                  # Even faster: 30-second scorecard only

2. Monthly Configuration Checkup

A quick health check — are things still clean?

/config-audit posture                  # Quick health check (A-F grade, 7 areas)
/config-audit                          # Full audit if grade dropped
/config-audit fix                      # Auto-fix deterministic issues
/config-audit posture                  # Verify improvement

3. Deep Optimization

You want to go from C to A. The full pipeline:

/config-audit                          # Audit — understand what you have
/config-audit feature-gap              # Opportunities — context-aware recommendations
/config-audit plan                     # Plan — prioritized actions with risk assessment
/config-audit implement                # Execute — changes with backup + verification

4. Plugin Author

You maintain Claude Code plugins and want to ensure quality:

/config-audit plugin-health            # Audit plugin structure, frontmatter, cross-plugin conflicts
                                       # → Checks naming, frontmatter completeness, tool grants, duplicates

5. Track Configuration Drift

Your team configuration changes over time. Track it:

/config-audit drift                    # First run creates baseline, subsequent runs show delta
                                       # → New findings, resolved findings, unchanged, moved
/config-audit drift --save my-baseline # Save a named baseline for comparison

Commands

Core (just run /config-audit to get started)

Command Description
/config-audit Full audit with auto-scope detection (no setup needed)
/config-audit posture Quick health scorecard: A-F grades across 10 quality areas (incl. Token Efficiency, Plugin Hygiene)
/config-audit tokens prompt-cache-aware token hotspots — ranked by estimated waste, each tagged with its load pattern (always / on-demand / external); 8 patterns + optional --accurate-tokens API calibration. Cache-aware: stale ~/.claude/plugins/cache versions (superseded installs that load on zero turns) are excluded from the ranking by default — only each plugin's active version is counted; --no-exclude-cache restores the full walk. Stale versions surface as a separate Dead config disk-cleanup finding
/config-audit manifest Ranked table of every token source (CLAUDE.md, rules, agents, skills, output styles, MCP, hooks) sorted by estimated tokens — each tagged with its load pattern (always-loaded / on-demand / external) plus an always-loaded subtotal ("≈X tokens enter context every turn before you type"). Component-level: no coarse plugin roll-up (it would double-count)
/config-audit feature-gap Context-aware feature recommendations grouped by impact
/config-audit optimize Optimization lens (mechanism-fit): config that works but fits a better mechanism — procedure→skill, lifecycle→hook, unscoped path→rule, "never"→permission. Hybrid motor (deterministic pre-filter + opus precision gate), every finding cites a best-practices-register rule
/config-audit fix Auto-fix deterministic issues with backup + verification
/config-audit rollback Restore configuration from a previous backup
/config-audit plan Generate prioritized action plan from audit findings
/config-audit implement Execute plan with automatic backup + verification
/config-audit help Show all commands with usage examples

Additional

Command Description
/config-audit drift Compare current config against a saved baseline
/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 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)
/config-audit status Show current session state and available actions
/config-audit cleanup Remove old session directories

Scope

By default, /config-audit auto-detects scope from your git context. Override with: /config-audit current, /config-audit repo, /config-audit home, /config-audit full. Use --delta for incremental scanning (only new/changed findings).


Deterministic Scanners

15 Node.js scanners that perform structural analysis an LLM cannot reliably do: schema validation, circular reference detection, import resolution, conflict detection across scopes, prompt-cache-aware token-cost analysis, cache-prefix stability, dead-tool detection, cross-plugin skill collisions, output-style validation, and a best-practice optimization lens (mechanism-fit). Plus a standalone plugin-health scanner. Zero external dependencies.

Why deterministic? LLMs are powerful at understanding intent and context. But they cannot reliably validate JSON schemas, detect circular @import chains, or catch that your global settings.json contradicts your project-level one. These scanners fill that gap — fast, repeatable, and zero false positives on structural issues.

Scanner Prefix What It Catches
claude-md-linter.mjs CML Oversized files (line count plus a context-window-scaled char budget mirroring Claude Code's ~40.0k-char startup warning), missing sections, broken @imports, duplicates, stale TODOs
settings-validator.mjs SET Schema violations, unknown/deprecated keys, type mismatches, permission issues
hook-validator.mjs HKV Invalid format, missing scripts, wrong event names, timeout risks, verbose-stdout scripts, and a low-precision advisory (info) when a hook injects un-grepped command output into hookSpecificOutput.additionalContext — that payload enters context on every fire (plain stdout does not)
rules-validator.mjs RUL Bad glob patterns, orphaned rules, deprecated fields, unscoped rules
mcp-config-validator.mjs MCP Invalid server types, exposed env vars, unknown fields
import-resolver.mjs IMP Broken @imports, circular references, deep chains, tilde path issues
conflict-detector.mjs CNF Settings contradictions across scopes, permission conflicts, hook duplicates
feature-gap-scanner.mjs GAP 25 feature checks shown as opportunities, not grades — plus a conditional disableBundledSkills recommendation when the active skill listing is over budget, and a conditional filter-before-Claude-reads lever when a hook injects unfiltered output into additionalContext (companion to the HKV advisory; cites the documented filter-test-output.sh pattern)
token-hotspots.mjs TOK Cache-breaking volatile content, redundant tool permissions, deep import chains, oversized cascades, bloated skill descriptions, MCP tool-schema budget, and stale ~/.claude/plugins/cache versions (disk-cleanup, zero live-context impact) — cache-aware ranking excludes superseded plugin versions by default (--no-exclude-cache to include)
cache-prefix-scanner.mjs CPS Volatile content in lines 31150 of the CLAUDE.md cascade — beyond Pattern A's top-30 window but still re-loaded every turn — plus volatile content inside @import-ed files (inlined into the cached prefix, one hop, otherwise invisible to per-file scans)
disabled-in-schema-scanner.mjs DIS Dead/ineffective permission entries: (1) tools in BOTH permissions.deny and permissions.allow — deny wins (incl. the Tool(*) deny-all glob, equivalent to a bare deny); (2) unanchored allow wildcards (*, B*, mcp__*) that Claude Code silently skips — valid only as mcp__<server>__*; (3) Tool(param:value) rules whose key is the tool's own canonicalizing field (command/file_path/path/notebook_path/url) — CC ignores these and emits a startup warning
collision-scanner.mjs COL Cross-plugin skill name collisions; user-vs-plugin overlaps
skill-listing-scanner.mjs SKL Skill-listing token budget: a single skill description over the ~1,536-char listing cap Claude Code truncates (CA-SKL-001), the summed active-skill descriptions exceeding the ~2%-of-context listing budget (CA-SKL-002), and an oversized SKILL.md body over ~5,000 tokens (CA-SKL-003, low — on-demand cost: the body loads only when the skill runs, not every turn; recommends supporting-file split + context: fork). The CA-SKL-002 (and CML char-budget) findings accept --context-window <n> to calibrate to your real window instead of the conservative 200k anchor (--context-window auto keeps the anchor but downgrades to advisory)
output-style-scanner.mjs OST Output-style validation: a custom (user/project) style missing keep-coding-instructions: true that silently strips built-in software-engineering instructions (CA-OST-001), a plugin style with force-for-plugin: true overriding the user's selected outputStyle (CA-OST-002), and a settings outputStyle resolving to no built-in or custom style — dead config (CA-OST-003)
optimization-lens-scanner.mjs OPT Optimization lens (mechanism-fit): a multi-step procedure in CLAUDE.md that would fit better as a skill (CA-OPT-001) — reads the machine-readable best-practices register, framed as an opportunity, not a failure. The deterministic half of the lens; prose-judgment cases (lifecycle→hook, unscoped path→rule, "never"→permission) are judged by the opus optimization-lens-agent via /config-audit optimize
agent-listing-scanner.mjs AGT Always-loaded agent-listing budget: a per-agent description over the soft bloat cap (CA-AGT-001, advisory) and the summed active-agent name+description listing — re-sent every turn — exceeding the listing budget (CA-AGT-002). Both LOW and explicitly inferred / upper-bound: the agent-listing mechanism is undocumented, so the evidence discloses the estimate and heuristic budget rather than overstating certainty

Cross-scanner remediation — diagnosis meets the fix. SKL diagnoses an over-budget skill listing (CA-SKL-002); GAP prescribes the remedy. When the active skill listing exceeds its ~2%-of-context budget and disableBundledSkills is not already set (in the env var or the settings cascade), the feature-gap scanner recommends that lever — hiding Claude Code's bundled skills (/code-review, /batch, /debug, /loop, /claude-api, …) from the model to reclaim listing budget without touching your own skills (CC 2.1.169+). It fires only under measured pressure, so it stays an opportunity rather than noise. Both scanners share one budget definition (scanners/lib/skill-listing-budget.mjs).

CLAUDE.md size — two complementary signals. CML checks line count (200/500, for readability) and a character budget that mirrors Claude Code's own startup warning — "Large CLAUDE.md will impact performance (X chars > 40.0k)." CC 2.1.169 scales that threshold with the model's context window, so the char finding anchors on a conservative 200k window and discloses the relaxed ~200,000-char figure at 1M context. A file can be long by lines yet under the char budget (short lines), or short by lines yet over it — so both signals earn their place. The 200k/1M window constants live in the shared scanners/lib/context-window.mjs (single source of truth with the skill-listing budget).

Permission rules CC silently ignores — severity follows intent. Tool(param:value) matching is real (CC 2.1.178), but the tool's own canonicalizing fields are off-limits: command (Bash/PowerShell), file_path (Read/Edit/Write), path (Grep/Glob), notebook_path (NotebookEdit), url (WebFetch). CC ignores a rule keyed on its tool's field and emits a startup warning, because Bash(command:rm *) is bypassable by a compound command. DIS splits severity by where the rule lives: in deny/ask it is false security (medium — the block you intended never applies), in allow it is dead config (low — param:value matching is deny/ask-only, so the entry grants nothing). The predicate lives in scanners/lib/permission-rules.mjs; valid forms like Bash(npm:*), WebFetch(domain:host), and Agent(model:opus) are never flagged.

Plugin namespace collisions — the one shadow that actually loses components. Claude Code namespaces every plugin component by the plugin's declared name (/name:command, name:skill, agent name), so a plugin component can never shadow a user- or project-level one — they live in separate namespaces. The real hazard is two plugins that declare the same name in plugin.json: their namespaces collapse into one, and because the resolution between two installed same-name plugins is undocumented, one plugin's commands, skills, and agents are silently shadowed and become unreachable. The standalone plugin-health scanner (PLH) flags this at medium severity, keying on the declared name field rather than the folder name (the folder name is irrelevant to the namespace). A command name shared by two differently-named plugins is a milder case — namespacing keeps both reachable as /a:cmd and /b:cmd, so it is only ambiguity in error messages, search results, and the command listing. PLH reports that at low severity (group-first, one finding per command name), mirroring the COL scanner, which owns the analogous skill-name overlaps across different namespaces.

Plugin-folder shadowing — when a manifest path silently buries a default folder. A plugin's plugin.json can point a component type at a custom path — commands, agents, and outputStyles all replace their default folder when set. So if a plugin declares "commands": "./custom/" while a commands/ folder still exists, Claude Code stops scanning commands/ entirely and everything in it silently disappears (dead config). PLH flags this at medium severity (CA-PLH-015), mirroring Claude Code's own warning in /doctor and claude plugin list (v2.1.140+). It does not flag skills — that key adds to the default skills/ scan rather than replacing it, so both load — nor does it flag a custom path that points back into the default folder (e.g. "commands": ["./commands/x.md"]), because the folder is then addressed explicitly.

skills:-array validation — every listed path must be a real skill folder. A plugin's plugin.json may list custom skill directories in a skills array (each entry a path to a folder containing SKILL.md). PLH validates each entry (CA-PLH-016, medium) and flags four ways an entry can be broken: it isn't a string, it points at a path that doesn't exist, it points at a file instead of a directory, or it escapes the plugin root (../… — installed plugins can't reference files outside their own directory, so the skill never loads). A valid existing directory is never flagged. This mirrors claude plugin validate. Note skills adds to the default skills/ scan, so a custom path here is never a shadow — it just has to resolve to a real folder.

autoMode validation — structure and the shared-settings blind spot. The SET scanner checks the auto-mode classifier config two ways. Structure: autoMode must be an object whose only keys are environment, allow, soft_deny, and hard_deny, each a list of plain-text rule strings (the literal "$defaults" is allowed). An unknown sub-key (e.g. a typo'd hard_denies), a non-object value, or a sub-key that isn't a string array is flagged medium — a typo'd key silently drops those rules. Scope: Claude Code does not read autoMode from shared project settings (.claude/settings.json) — "a checked-in repo cannot inject its own allow rules" — so an autoMode block committed there is dead config (low); it only takes effect in user (~/.claude/settings.json), local (.claude/settings.local.json), or managed settings.

CLI Tools

All tools work standalone — no Claude Code session needed:

Tool Usage
Posture node scanners/posture.mjs <path> [--json] [--global] [--full-machine] [--output-file path]
Fix node scanners/fix-cli.mjs <path> [--apply] [--json] [--global]
Drift node scanners/drift-cli.mjs <path> [--save] [--baseline name] [--json]
Tokens node scanners/token-hotspots-cli.mjs <path> [--json] [--global] [--no-exclude-cache] [--output-file path] [--accurate-tokens] [--with-telemetry-recipe]
Manifest node scanners/manifest.mjs <path> [--json] — ranked component-level source table with per-source load pattern + always-loaded subtotal
What's active node scanners/whats-active.mjs <path> [--json] [--verbose] [--suggest-disables]
Self-audit node scanners/self-audit.mjs [--json] [--fix] [--check-readme]
Full scan node scanners/scan-orchestrator.mjs <path> [--global] [--full-machine] [--no-suppress]

Agent Architecture

Six specialized agents collaborate through the audit workflow, each matched to an appropriate model for cost and quality:

Agent Model Role Tools
scanner-agent Sonnet Fast filesystem scanning, file discovery Read, Glob, Grep, Write
analyzer-agent Sonnet Deep analysis, hierarchy mapping, conflict detection Read, Glob, Grep, Write
planner-agent Opus Action plan generation with risk assessment Read, Glob, Write
implementer-agent Sonnet Change execution with mandatory backups Read, Write, Edit, Bash, Glob
verifier-agent Sonnet Post-implementation verification Read, Glob, Grep
feature-gap-agent Opus Context-aware feature recommendations Read, Glob, Grep, Write
optimization-lens-agent Opus Mechanism-fit precision gate — judges prose-judgment lens candidates (lifecycle→hook, path→rule, never→permission), cites the best-practices register Read, Glob, Grep, Write

Orchestration Flow

                                    +-----------+
                                    | Interview |  (optional)
                                    +-----+-----+
                                          |
+-----------+     +---------+     +-------v---+     +-----------+
| Discover  | --> | Analyze | --> |   Plan    | --> | Implement |
| (sonnet)  |     | (sonnet)|     | (opus)    |     | (sonnet)  |
+-----------+     +---------+     +-----------+     +-----+-----+
                                                          |
                                                    +-----v-----+
                                                    |  Verify   |
                                                    |  (sonnet) |
                                                    +-----------+

Hooks & Safety

Four hooks provide automatic safety and session continuity — they activate the moment the plugin is installed:

Event Script What It Does
PreToolUse auto-backup-config.mjs Backs up any config file before Edit/Write touches it
PostToolUse post-edit-verify.mjs Re-scans after edits — blocks if new critical/high findings introduced
SessionStart session-start.mjs Checks for incomplete audit sessions so you can resume
Stop stop-session-reminder.mjs Shows current phase so your next session picks up where you left off

All hooks are Node.js (.mjs) for cross-platform compatibility (macOS, Linux, Windows).

Important

The PreToolUse and PostToolUse hooks only activate when config-audit is modifying configuration files. They don't interfere with your normal development workflow.


Skills

Skill Trigger Description
config-hierarchy "CLAUDE.md hierarchy", "config file locations", "settings.json structure" Comprehensive reference for Claude Code's configuration hierarchy — CLAUDE.md, settings.json, managed config, @imports, path-scoped rules

Skills activate automatically when your question matches their trigger patterns.


Suppressions

Finding ID Format

Every finding has a unique ID: CA-{SCANNER}-{NNN} — where {SCANNER} is the scanner prefix (see table above) and {NNN} is a sequential number. Examples: CA-CML-001, CA-SET-003, CA-HKV-002, CA-RUL-005.

Suppression

Some findings are expected — maybe you intentionally have a large CLAUDE.md, or a feature gap doesn't apply to your workflow. Create a .config-audit-ignore file to suppress them:

# Suppress by exact finding ID
CA-SET-003

# Suppress by scanner prefix (glob pattern)
CA-GAP-*

# Suppress all plugin health findings
CA-PLH-*

Suppressed findings are tracked in the scan envelope's suppressed_findings array for audit trail — nothing is silently hidden. Use --no-suppress to see everything.


Examples & Self-Audit

Example Projects

The examples/ directory contains two projects shown in the before/after demo above:

Example Description Grade Opportunities
minimal-setup/ Single CLAUDE.md, nothing else A 22
optimal-setup/ Full configuration across all 4 tiers A 3
# Run them yourself
node scanners/posture.mjs examples/minimal-setup/
node scanners/posture.mjs examples/optimal-setup/

Self-Audit: Scanning the Scanner

The plugin runs all 16 scanners + the standalone plugin-health scanner on itself via self-audit.mjs. Test fixtures and example files are automatically excluded from scoring — a configuration plugin that ships deliberately broken examples shouldn't fail its own audit. Use --check-readme to verify badge counts are in sync with the filesystem.

node scanners/self-audit.mjs

Scanner Library (scanners/lib/)

Shared modules used by all scanners — useful if you're reading the source or extending the plugin:

Module Purpose
severity.mjs Severity constants, risk scoring, verdict logic, WEIGHTS export (v5 F3)
output.mjs Finding objects (CA-XXX-NNN format), scanner results, envelope, details field
file-discovery.mjs Config file discovery: single-path, multi-path, full-machine
yaml-parser.mjs Frontmatter parsing, JSON parsing, @import/section extraction
string-utils.mjs Line counting, truncation, similarity, key extraction
scoring.mjs Area scoring (v5 severity-weighted), health scorecard, scoringVersion: 'v5'
backup.mjs Backup creation, manifest parsing, checksum verification
diff-engine.mjs Drift diffing: diffEnvelopes(), formatDiffReport()
baseline.mjs Baseline save/load/list/delete for drift detection
report-generator.mjs Unified markdown reports: posture, drift, plugin health
suppression.mjs .config-audit-ignore parsing, finding suppression, audit trail
active-config-reader.mjs Read-only inventory of plugins/skills/MCP/hooks/CLAUDE.md cascade with token estimates
tokenizer-api.mjs Anthropic count_tokens wrapper for --accurate-tokens (v5 N5); 5s timeout, 429 backoff, key masking

Action Engines

Module Purpose
fix-engine.mjs planFixes(), applyFixes(), verifyFixes() — 9 fix types
rollback-engine.mjs listBackups(), restoreBackup(), deleteBackup()
fix-cli.mjs CLI entry point for auto-fix
drift-cli.mjs CLI entry point for drift detection
manifest.mjs CLI: ranked component-level source table w/ load-pattern accounting (v5 N2; v5.6 B)
whats-active.mjs CLI: read-only active-config inventory (v3.1.0+)
token-hotspots-cli.mjs CLI: token hotspots ranking with optional --accurate-tokens

Knowledge Base (knowledge/)

Reference documents that inform the feature-gap agent and context-aware recommendations:

File Content
claude-code-capabilities.md Feature register: 18 config surfaces, Anthropic guidance, relevance table
configuration-best-practices.md Per-layer best practices (cache-stability guidance)
anti-patterns.md Common mistakes mapped to scanner IDs
hook-events-reference.md All 28 hook events with details
feature-evolution.md Feature timeline for staleness detection
gap-closure-templates.md Config-specific templates for closing gaps
prompt-cache-patterns.md Token-cost dynamics (prompt-cache patterns) — patterns powering the TOK scanner
cache-telemetry-recipe.md jq recipe for verifying prompt-cache hit rate from session transcripts

Machine-readable register (best-practices.json). Alongside the human-readable documents above, knowledge/best-practices.json is a provenance-stamped, schema-validated register of best-practice claims and mechanism-fit rules — each entry carries source.url, a verified date, and a confidence. It is the source of truth for the optimization lens (OPT scanner + /config-audit optimize); the Markdown files remain the human-readable mirror. Loaded and validated by scanners/lib/best-practices-register.mjs (zero-dependency, native JSON). See docs/v5.7-optimization-lens-plan.md.


Testing

node --test 'tests/**/*.test.mjs'

1168 tests across 67 test files (22 lib + 35 scanner + 1 hook + 1 agent + 3 commands + 1 knowledge + 4 top-level). Test fixtures in tests/fixtures/. Requires Node.js 18+ (node:test).


Gotchas

  • Session accumulation — session directories at ~/.claude/config-audit/sessions/ grow over time. Use /config-audit cleanup to manage
  • Node.js version — scanners require Node.js 18+ (uses node:test, node:fs/promises)
  • Plugin CLAUDE.md in node_modules — these should be excluded via scope to avoid false positives

Data Storage & Safety Guarantees

Where Data Lives

All data stays local at ~/.claude/config-audit/sessions/:

~/.claude/config-audit/sessions/{session-id}/
  scope.yaml              # Scan boundaries
  discovery.json          # File manifest
  findings/               # Individual issues (YAML)
  analysis-report.md      # Full report
  action-plan.md          # Prioritized actions
  backups/                # Pre-modification copies
  implementation-log.md   # Change log
  state.yaml              # Phase tracking

Safety Guarantees

This plugin is cautious by design — configuration files are important, and a bad edit can break your entire Claude Code setup:

Guarantee How
Backups mandatory Every file is copied before modification — no exceptions
Read-only audit /config-audit and /config-audit posture analyze without changing anything
Rollback support /config-audit rollback restores from any backup
Syntax validation Every change is validated before finalization
Verification pass A separate agent confirms changes actually work
Human-in-the-loop You approve the plan before anything is implemented
Post-edit guard Hook blocks the session if a new critical/high finding is introduced

What This Plugin Does Not Cover

  • Runtime behavior — this plugin audits configuration files, not what Claude actually does at runtime. For runtime defense, see claude-code-llm-security
  • Secret scanning — config-audit checks for structural issues, not leaked credentials. Use llm-security for secret detection
  • Custom scanner rules — scanners check against known Claude Code configuration schemas. Custom rule definitions are not supported
  • Remote/team configuration — managed settings, SSO-provisioned config, and organization-level policies are detected as gaps but not managed

Version History

Version Date Highlights
5.12.5 2026-06-26 "Dogfood denoise" — a samle-release of the Fase-3 scanner false-positive batch (M-BUG-2/6/7/8/10, all dogfooding finds on the maintainer's real machine). Five scanners stop counting non-user / non-live config as the user's: CNF (M-BUG-2) excludes files under .claude/plugins/ from conflict analysis (isPluginBundled) — installed plugins' bundled settings/hooks/fixtures are not a user-resolvable cascade (dogfood 339→0, Conflicts was an F on pure plugin noise). file-discovery (M-BUG-8) adds backups to SKIP_DIRS — a backups/ tree holds frozen copies, never live config (dogfood files-under-/backups/ 36→0, 717 live retained). token estimator (M-BUG-6) strips block-level <!-- --> HTML comments from CLAUDE.md sizing — CC strips them before injection, so they were never always-loaded tokens (dogfood ~3386→3301, ~85 tok). CPS (M-BUG-7) skips fenced/inline code and whitelists CC-stable path vars (${CLAUDE_PLUGIN_ROOT}/${CLAUDE_PROJECT_DIR}) before cache-buster matching (dogfood 5→2). SET (M-BUG-10) typo-gates the unknown-settings-key finding — the CC schema is passthrough (verified against the 2.1.193 binary), so an unknown key is forward-compatible, not an error; it now flags only a near-miss of a known key (levenshtein ≤2), severity medium→low, +6 binary-verified KNOWN_KEYS (dogfood 6→0). No count change (scanners 16, agents 7, commands 21, hooks 4); all five are byte-stable — frozen v5.0.0 + SC-5 + default-output snapshots untouched, no re-seed (each fixture's findings are genuinely unchanged). 1344 tests (+37).
5.12.4 2026-06-26 "Rooted rules" — fixes M-BUG-9 (dogfooding find) in scanners/rules-validator.mjs: the RUL "Rule path pattern matches no files" check now resolves a rule's paths:/globs: pattern against the rule's own project root (the dir containing its .claude/), not the outer scan root. Previously countGlobMatches globbed against the scan target and collectProjectFiles' depth>4 cutoff never reached deep matching files, so a live rule in a nested repo (e.g. a marketplace checkout under ~/.claude) was wrongly flagged "never activates" (high) — a false F-grade for anyone with rules in a nested repo. The fix derives each rule's project root, collects+globs per root (cached), and skips the check for user-global rules (root === $HOME), which scope against the active project at runtime. Same scope-conflation family as M-BUG-1/2. No count change (scanners 16, agents 7, commands 21); the fix is a no-op when projectRoot === targetPath (the common single-repo scan), so frozen v5.0.0 + default-output snapshots stay byte-stable. 1307 tests (+2 TDD: nested-repo false-positive + HOME guard).
5.12.3 2026-06-26 "Phantom agents" — fixes M-BUG-3/4/5 (dogfooding finds) in scanners/lib/active-config-reader.mjs: enumerateAgents now counts only the agents Claude Code actually registers. Per the official subagents doc, an agent needs valid name+description frontmatter, and CC scans recursively and silently skips frontmatter-less files. The reader previously (M-BUG-5) counted every .md regardless of frontmatter, (M-BUG-3) never recursed into agent subdirs, and (M-BUG-4) double-counted when the project dir equals the user dir (scanning $HOME — root cause, also affecting rules/output-styles). Real-machine verify: user-agent count 13→0 (all 12 user agents + REMEMBER.md are frontmatter-less → CC registers none), HOME project-dup 13→0; corrected always-loaded baseline ≈ 53 (was 66). Agent enumeration is machine-dependent and absent from the frozen snapshots, so the v5.0.0 + SC-5 + default-output snapshots stay byte-stable; no count change (scanners 16, agents 7, commands 21). 1305 tests.
5.12.2 2026-06-24 "Honest census" — fixes M-BUG-1 (dogfooding find): enumeratePlugins walked ~/.claude/plugins/marketplaces/<mkt>/plugins/ and ignored both enable-state and the polyrepo cache layout, so it over-counted phantom agents from disabled plugins while missing the entire enabled polyrepo set (whose plugins live under cache/). It now gates on installed_plugins.json + enabledPlugins and enumerates each plugin from its active installPath, with the marketplaces walk as fallback. Fixes manifest/whats-active/AGT/token-hotspots for any user with disabled plugins or a polyrepo marketplace. No count change (scanners 16, agents 7, commands 21); --json/--raw byte-stable, frozen v5.0.0 + SC-5 + default-output snapshots untouched. Real-machine verify: agent listing 114→104, ghosts gone. 1301 tests.
5.12.1 2026-06-24 "Footgun guard" — Pattern H (stale plugin-cache versions, token-hotspots) recommended deleting stale version dirs with no warning that a currently-running session may still hold one of those versions for its whole lifetime. "Stale" is judged against installed_plugins.json (what NEW sessions load), so the recommendation could reproduce the exact failure that breaks a live session: deleting the dir pulls the files out from under the running session, which then must /exit + restart. The plugin-cache-hygiene recommendation now carries the live-session caveat. Recommendation string only — no new finding ID or scanner (count stays 16, agents 7, commands 21), no token figures changed, so --json/--raw stay byte-stable and the frozen v5.0.0 + SC-5 + default-output snapshots are untouched. 1297 tests.
5.12.0 2026-06-23 "Auto-calibration" — completes the deferred B8 half (B8b): --context-window auto now probes the configured model instead of always falling back to advisory. New pure modelToContextWindow() maps known 1M-tier model IDs (Fable 5, Opus 4.8/4.7/4.6, Sonnet 4.6 — verified June 2026 — plus the explicit [1m] tier tag, dated/provider-prefixed IDs, and the opus/sonnet/fable aliases) to the 1M window; new IO helper lib/active-model.mjs resolveActiveModel() reads the model the way Claude Code resolves it (shell ANTHROPIC_MODEL override, then the settings cascade local > project > user). When auto resolves a recognized model the budget calibrates to its window (auto-probed, not advisory); when no model is pinned or it is unrecognized it keeps the conservative anchor and stays advisory (auto-unresolved) — the honest fallback. No new finding ID or scanner (count stays 16, agents 7, commands 21); the default and explicit --context-window paths are unchanged, so --json/--raw stay byte-stable and the frozen v5.0.0 + SC-5 snapshots are untouched. 1296 tests.
5.11.0 2026-06-23 "Precision polish" — the two LOW-priority calibration gaps, both additive (scanner count stays 16, agents 7, commands 21; --json/--raw byte-stable, frozen v5.0.0 + SC-5 untouched). B7 — oversized skill body (CA-SKL-003, low): the SKL scanner now measures the SKILL.md body (it already read the file in full) and flags bodies over ~5,000 tokens, recommending a supporting-file split + context: fork. Honestly framed as an on-demand cost — the body loads only when the skill is invoked, not every turn like the always-loaded listing — hence low severity. B8 — context-window calibration (--context-window): CA-SKL-002 (skill-listing budget) and the CML char-budget now calibrate to a real context window via --context-window <n> (e.g. 1000000 stops the 200k anchor crying wolf on a 1M host) instead of always anchoring at 200k; --context-window auto keeps the conservative anchor but downgrades budget findings to info/advisory rather than firing a breach (model→window auto-probing deferred to a later B8b). No flag → byte-identical to the pre-B8 200k default. CPS is intentionally excluded (no window-anchored budget to calibrate). 1279 tests
5.10.0 2026-06-23 "Deferral & injection hygiene" — three additive hardening levers that extend existing scanners toward a tighter always-loaded prefix (scanner count stays 16, agents 7, commands 21; --json/--raw byte-stable, frozen v5.0.0 + SC-5 untouched). B4 — MCP tool-schema deferral (CA-TOK-006; tokens patterns 7→8): Claude Code defers MCP tool schemas (names-only, ~120 tok; full schemas load on demand) by default, so CA-TOK-006 detects config-file signals that force the FULL schemas into the always-loaded prefix every turn — env.ENABLE_TOOL_SEARCH="false" (high), a "ToolSearch" deny (high), a configured Haiku model (medium), or per-server alwaysLoad:true (CC v2.1.121+, high); severity scales with the aggregate forced-upfront tokens. New pure engine lib/mcp-deferral.mjs shared by TOK + GAP, plus a feature-gap CLI-over-MCP companion lever (prefer gh/aws/gcloud). Triggers on config files ONLY — Vertex / custom ANTHROPIC_BASE_URL / a runtime /model switch are launch state and are disclosed, never triggered; the prefix-cache-invalidation claim was NOT-CONFIRMED in docs and is not asserted. B5 — hook additionalContext advisory + filter-before lever: HKV emits an info advisory when a hook injects unfiltered output into additionalContext, with a feature-gap filter-before-Claude-reads companion citing the documented filter-test-output.sh pattern. B6 — CPS @import volatile scan: the cache-prefix scanner now follows @imports (one hop) and flags volatile content in the imported file that breaks the cached prefix — a new medium finding, keyed on the resolved file. 1257 tests
5.9.0 2026-06-23 "Machine-wide token lens" — the three highest-impact hardening gaps toward whole-machine token tuning. B1 — agent-listing budget (new orchestrated scanner AGT, count 15→16): the always-loaded agent listing (name+description re-sent every turn) is now measured — CA-AGT-001 per-agent description bloat (advisory), CA-AGT-002 aggregate listing over budget; both LOW and explicitly inferred / upper-bound (the mechanism is undocumented — the evidence discloses it rather than overstating). B2 — machine-wide always-loaded token roll-up: the campaign ledger now carries a token bill — campaign refresh-tokens does a live cross-repo sweep that counts the shared global always-loaded layer once + per-repo deltas, with a ranked "most expensive repos" table (the whats-active double-count, avoided by construction). B3 — cache-aware filtering (folds in B0): ~/.claude/plugins/cache holds both active and stale plugin versions (installPaths point INTO it), so token-hotspots + CNF are now version-aware--exclude-cache (default ON) keeps each plugin's active version and drops only stale ones (installed_plugins.json-driven), so stale versions stop polluting the hotspot ranking and inflating duplicate-hook conflicts; stale versions surface as a separate Dead config disk-cleanup finding (zero live-context impact). --json/--raw byte-stable; frozen v5.0.0 + SC-5 snapshots untouched. 1215 tests
5.8.0 2026-06-23 "Campaign motor" — a durable, machine-wide audit campaign that sits ABOVE individual sessions (one repo = one session; a fleet of repos = a campaign). Ledger: ~/.claude/config-audit/campaign-ledger.json (outside the plugin dir → survives uninstall/upgrade) tracks a repo list + per-repo lifecycle (pending→audited→planned→implemented) + a machine-wide roll-up by status & severity; pure transforms with injected now. /config-audit campaign (commands 20→21): read-only report (campaign-cli) + human-approved writes (campaign-write-cli: init / add / set-status) — reports first, mutates only on explicit approval, never hand-edits the ledger. Cross-repo backlog: one severity-weighted prioritized pick-list (buildBacklog, critical:1000/high:100/medium:10/low:1). Plan export + execution-by-reuse: campaign-export-cli --write drops a planned repo's plan verbatim into its own docs/; execution reuses the existing /config-audit implement + rollback (no new execution machinery). All campaign code is -cli/lib → scanner count stays 15, agents 7, byte-stable. Plus pre-release cleanup: knowledge-refresh wired into the router + help; CLAUDE.md trimmed 540→134 lines (impl notes → docs/scanner-internals.md, config grade B→A). 1168 tests
5.7.0 2026-06-21 "Optimization lens" — first detector of the «optimally shaped?» axis (vs «correct?»), plus a living knowledge layer. Register: knowledge/best-practices.json, a provenance-stamped, schema-validated best-practices register (first runtime-consumed knowledge/ file). OPT scanner (count 14→15): CA-OPT-001 (LOW) a ≥6-step CLAUDE.md procedure that would fit better as a skill, citing register entry BP-MECH-003. /config-audit optimize + optimization-lens-agent (opus, agents 6→7): prose-judgment lens for lifecycle→hook (BP-MECH-001), unscoped path→rule (BP-MECH-002), "never"→permission (BP-MECH-004); pre-filter recall + opus precision gate. /config-audit knowledge-refresh (commands 19→20): deterministic stale-check (injected reference date, 90-day cadence) + web re-verify/poll, human-approved writes only. Last two are agent/web-driven (not byte-stable). 1091 tests
5.6.0 2026-06-20 "Steering-model II" — the load-pattern / compaction-survival model lands end-to-end. Foundation: active-config-reader now enumerates rules, agents, and output styles (alongside CLAUDE.md/plugins/skills/hooks/MCP), each tagged loadPattern (always / on-demand / external) + survivesCompaction from the published loading model; the frontmatter parser also reads YAML block sequences (paths: lists). B (load-pattern accounting): manifest reports component-level sources (the double-counting plugin roll-up is gone), tags every source with the load-pattern triple, and leads with an always-loaded subtotal ("tokens that enter context every turn"); token-hotspots annotates each ranked hotspot with its load pattern. C (output styles): new orchestrated OST scanner (count 13→14) — CA-OST-001 a custom style stripping built-in coding instructions (missing keep-coding-instructions: true, V10), CA-OST-002 a plugin style with force-for-plugin: true overriding the user's outputStyle (V11), CA-OST-003 a settings outputStyle resolving to no known style (dead config). Doc-verified; frozen v5.0.0 snapshots preserved via strip-helpers, SC-5 regenerated. 1023 tests
5.5.0 2026-06-20 "Steering-model I" — two additive compaction-durability / dead-config findings (count stays 13, --json/--raw byte-stable). Per the official "what survives compaction" model: RUL flags a large (>50-line) path-scoped rule not re-injected after compaction (LOW); CML flags a nested (subdir) CLAUDE.md not re-injected after compaction (LOW). PLH flags a plugin agent setting hooks/mcpServers/permissionMode — Claude Code ignores these for plugin subagents, so it's dead config (permissionMode = MEDIUM false-security, hooks/mcpServers = LOW). Known limitation: the frontmatter parser reads inline paths: but not YAML block sequences (deferred to v5.6 Foundation). 961 tests
5.4.1 2026-06-20 Scanner-correctness patch (count stays 13, --json/--raw byte-stable). HKV: added Setup/UserPromptExpansion/PostToolBatch to the valid-event set (a valid hook using one was wrongly flagged "will never fire"), and removed post-session (the 2.1.169 post-session is a self-hosted-runner workspace-lifecycle hook, not a settings.json event — absent from hooks.md; verified 2026-06-20). RUL: globs-rule wording corrected — only paths: is documented, so the finding drops the unverified "deprecated/legacy" claim and steers to the documented field. PLH: optional model/tools/name/allowed-tools frontmatter no longer required; CLAUDE.md component-section required only for components the plugin actually ships. 954 tests
5.4.0 2026-06-19 Plugin-hygiene & settings-validation hardening. Three additive findings extend existing PLH and SET scanners (count stays 13): PLH plugin-folder shadowing (CA-PLH-015 — a plugin.json component-path key in the replaces set commands/agents/outputStyles pointing at a custom path while the default folder still exists) mirroring CC's /doctor & claude plugin list warning; PLH skills:-array validation (CA-PLH-016 — each entry must resolve to a directory in the plugin root; flags non-string/escapes-root/not-found/not-a-directory) mirroring claude plugin validate; SET autoMode structure (only environment/allow/soft_deny/hard_deny string arrays) + dead-config (autoMode in shared .claude/settings.json is not read by CC). --json/--raw byte-stable. 949 tests
5.3.0 2026-06-19 Permission-rule & plugin-hygiene hardening. Five additive scanner findings extend existing scanners (count stays 13): DIS forbidden-param rules (Tool(param:value) on a canonicalizing field — deny/ask = false security, allow = dead config) and ineffective allow-wildcards + Tool(*) deny-all; CML context-window-scaled 40.0k-char CLAUDE.md budget mirroring CC's startup warning; PLH plugin namespace collision (two plugins declaring the same name); feature-gap disableBundledSkills lever under skill-listing pressure. PLH cross-plugin command-name overlap reframed HIGH → LOW (namespacing keeps both reachable). --json/--raw byte-stable. 936 tests
5.2.0 2026-06-18 CC 2.1.114→181 compatibility + skill-listing budget. New orchestrated scanner SKL (CA-SKL-001 1,536-char listing cap, CA-SKL-002 listing-budget sum) → 13 orchestrated scanners. Five validators refreshed for CC 2.1.114181 settings/hook surface (xhigh effort, MessageDisplay + post-session events, 28 hook events). False positives eliminated in MCP (auto-injected/POSIX env vars, invented trust field) and permissions (param-aware DIS/CNF). Hermetic HOME isolation across all CLI-spawning tests. 875 tests
5.1.0 2026-05-01 Plain-language UX humanizer. Default output of all 18 commands now leads with prose; findings grouped by user-impact category (Configuration mistake, Conflict, Wasted tokens, Missed opportunity, Dead config) and led by urgency phrase (Fix this now → FYI). New --raw flag preserves v5.0.0 verbatim output for tooling that scrapes stderr; --json is unchanged and byte-stable. New scanner-lib modules: humanizer.mjs, humanizer-data.mjs with TRANSLATIONS for 13 scanner prefixes. Self-audit terminal output also humanized. 792 tests (+157 humanizer-tester)
5.0.0 2026-05-01 Reality-based token-optimization. 3 new scanners (CPS cache-prefix, DIS dead tools, COL plugin collisions) → 12 deterministic scanners. New /config-audit manifest and --accurate-tokens API calibration. Severity-weighted scoring (scoringVersion: 'v5'). MCP token estimates 15 → 500+. Plugin Hygiene as 10th quality area. Knowledge: cache-stability replaces 200-line rule, cache-telemetry recipe. Breaking: F2 token magnitude jump, F3 severity weighting, F5 Pattern D removed, N1 CA-TOK-* glob now matches CA-TOK-005. 635 tests
4.0.0 2026-04-19 Opus 4.7 era: new TOK scanner (cache-breaking volatile content, redundant tool permissions, deep import chains, sonnet-era setups), /config-audit tokens command, Token Efficiency 8th quality area, scanner-agent + verifier-agent migrated haiku → sonnet. 543 tests
3.1.0 2026-04-14 New /config-audit whats-active — read-only inventory of active plugins, skills, MCP, hooks, CLAUDE.md for a repo, with token estimates. 522 tests
3.0.1 2026-04-04 Cross-platform fix: Windows path separators. 486 tests
3.0.0 2026-04-04 Health redesign: quality-only grades, context-aware opportunities (replaces utilization/maturity/segment), Anthropic guidance. 482 tests
2.2.0 2026-04-04 Fixture filtering (test findings excluded from grades), session path fix, UX polish. 461 tests
2.1.0 2026-04-03 UX redesign: auto-scope, zero questions, simplified commands (15 from 17). 441+ tests
2.0.0 2026-04-03 Complete rewrite: 8 scanners, 25 gap dimensions, auto-fix, drift, suppressions, self-audit. 408+ tests
1.6.0 2026-04-03 Report generator, suppression engine, self-audit CLI, PostToolUse hook
1.5.0 2026-04-03 Diff engine, baseline manager, drift CLI, plugin health scanner
1.4.0 2026-04-03 Fix engine, rollback engine, fix CLI, PreToolUse hook
1.3.0 2026-04-03 Scoring module, posture CLI, feature-gap agent
1.2.0 2026-04-03 4 advanced scanners (MCP, import, conflict, feature-gap)
1.1.0 2026-04-03 4 core scanners, scan orchestrator, test infrastructure
1.0.0 2026-02-11 Cross-platform support
0.7.0 2026-02-07 Initial version (version reset from inflated 1.2.0)

See CHANGELOG.md for full details.


License

MIT License — Copyright (c) 2025-2026 Kjell Tore Guttormsen