release: v5.3.0 — permission-rule & plugin-hygiene hardening (DIS/CML/PLH)

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). PLH cross-plugin command-name overlap reframed HIGH → LOW (namespacing keeps both reachable). feature-gap recommends disableBundledSkills under skill-listing pressure.

Version sync: plugin.json 5.2.0→5.3.0, README version badge + What's New + version-history row + TOC anchor (tests badge already 936+, scanner count stays 13), CHANGELOG [5.3.0] entry, 3 knowledge-backing entries. 936/936 tests; self-audit configGrade A 97, pluginGrade A 100, readmeCheck.passed:true; gitleaks clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ter3E2JSi1Khgmuf2kady8
This commit is contained in:
Kjell Tore Guttormsen 2026-06-19 20:45:29 +02:00
commit fe686b6594
5 changed files with 118 additions and 13 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "config-audit", "name": "config-audit",
"description": "Multi-agent workflow for analyzing, reporting, and optimizing Claude Code configuration across your entire machine", "description": "Multi-agent workflow for analyzing, reporting, and optimizing Claude Code configuration across your entire machine",
"version": "5.2.0", "version": "5.3.0",
"author": { "author": {
"name": "Kjell Tore Guttormsen" "name": "Kjell Tore Guttormsen"
}, },

View file

@ -5,6 +5,77 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [5.3.0] - 2026-06-19
### Summary
Permission-rule & plugin-hygiene hardening. Five additive scanner findings extend the existing
DIS, CML, PLH, and feature-gap scanners — no new scanner file, so the scanner count stays **13**.
DIS gains forbidden-parameter and ineffective-allow-wildcard detection; CML mirrors Claude Code's
own 40.0k-char "large CLAUDE.md" startup warning, context-window scaled; PLH flags two plugins
that declare the same name; and feature-gap recommends `disableBundledSkills` under skill-listing
pressure. The cross-plugin command-name finding is reframed from a HIGH conflict to a LOW
ambiguity. Scanner internals only — no command, agent, or output-format changes; `--json` and
`--raw` remain byte-stable.
### Added
- **DIS forbidden-param rules** — flags `Tool(param:value)` whose key is the tool's own
canonicalizing field (`command`/`file_path`/`path`/`notebook_path`/`url`); Claude Code ignores
these and emits a startup warning. Severity by intent: **deny/ask = false security (medium)**,
**allow = dead config (low)**. Valid forms (`Bash(npm:*)`, `WebFetch(domain:host)`,
`Agent(model:opus)`) are never flagged. Predicate `forbiddenParamRule` in `permission-rules.mjs`.
- **DIS ineffective allow-wildcards + `Tool(*)` deny-all** — flags unanchored tool-name globs in
`permissions.allow` (`*`, `B*`, `mcp__*`) that CC silently skips (low); treats `Tool(*)` as
deny-all (`Bash(*)``Bash`) so a bare allow killed by it is reported as dead config. Valid
`mcp__<server>__*` is never flagged.
- **CML context-window-scaled char budget** — new `CA-CML` finding mirroring CC's startup warning
*"Large CLAUDE.md will impact performance (X chars > 40.0k)"*. Anchors on the conservative 200k
window; discloses the relaxed ~200,000-char figure at 1M context. Severity **medium** (token
cost). Char-keyed, complementary to the 200/500-line checks. Window constants live in the shared
`scanners/lib/context-window.mjs`.
- **PLH plugin namespace collision** — flags 2+ discovered plugins declaring the same `name` in
`plugin.json`. Namespaces collapse; CC picks an undocumented winner; the loser's
commands/skills/agents go silently unreachable. Severity **medium** (dead config),
`category: 'plugin-hygiene'`, COL-shaped `details.namespaces`. Keys on the declared `name`, not
`basename(dir)`; name-less plugins are excluded.
- **feature-gap `disableBundledSkills` lever** — conditional recommendation to set
`disableBundledSkills` when the active skill listing is over budget; remediation companion to
SKL `CA-SKL-002`.
### Changed
- **PLH cross-plugin command-name overlap: HIGH → LOW** — reframed from "conflict" to "ambiguity".
Commands are namespaced (`/name:command`) so both stay reachable; only a same-`name` plugin
collision loses components (covered by the new namespace-collision finding). Now group-first
(one finding per command name listing every namespace), COL-shaped `details.namespaces`. The old
HIGH `Cross-plugin command name conflict` finding and its humanizer entry are removed. Scoring
impact: configs with cross-plugin command overlap score slightly higher. Not a `--json`-shape
break — no test or consumer asserted the old HIGH.
### Fixed
- **README scanner table** — added the missing SKL row (12 → 13 rows); the prose table lagged the
badge/self-audit count (the `--check-readme` gate is number-only and didn't catch it).
### Internal
- **Extract skill-listing budget to shared lib**`scanners/lib/context-window.mjs` as the single
source of truth for the 200k/1M context-window constants, re-exported by
`skill-listing-budget.mjs` and consumed by the new CML char-budget finding.
### Knowledge
- Three backing entries added: `disableBundledSkills` as a token-efficiency lever
(`prompt-cache-patterns.md`); the 40.0k-char "large CLAUDE.md" startup warning + CC 2.1.169
context-window scaling (`claude-code-capabilities.md`); and `Tool(param:value)` permission
semantics — deny/ask-only matching plus the canonicalizing-field rules CC ignores
(`claude-code-capabilities.md`).
### Test count
- 936 tests across 56 test files (unchanged — this release covers already-tested work on `main`).
### Verification
- 936/936 tests pass (`node --test 'tests/**/*.test.mjs'`).
- `node scanners/self-audit.mjs --json --check-readme``configGrade: A`, `pluginGrade: A`,
`readmeCheck.passed: true`.
- README version badge updated: `version-5.2.0``version-5.3.0`. Scanner count stays 13; tests
badge already `936+`.
## [5.2.0] - 2026-06-18 ## [5.2.0] - 2026-06-18
### Summary ### Summary

View file

@ -6,7 +6,7 @@
*AI-generated: all code produced by Claude Code through dialog-driven development. [Full disclosure →](../../README.md#ai-generated-code-disclosure)* *AI-generated: all code produced by Claude Code through dialog-driven development. [Full disclosure →](../../README.md#ai-generated-code-disclosure)*
![Version](https://img.shields.io/badge/version-5.2.0-blue) ![Version](https://img.shields.io/badge/version-5.3.0-blue)
![Platform](https://img.shields.io/badge/platform-Claude_Code_Plugin-purple) ![Platform](https://img.shields.io/badge/platform-Claude_Code_Plugin-purple)
![Scanners](https://img.shields.io/badge/scanners-13-cyan) ![Scanners](https://img.shields.io/badge/scanners-13-cyan)
![Commands](https://img.shields.io/badge/commands-18-green) ![Commands](https://img.shields.io/badge/commands-18-green)
@ -21,7 +21,7 @@ A Claude Code plugin that checks configuration health, suggests context-aware im
## Table of Contents ## Table of Contents
- [What's New in v5.2.0](#whats-new-in-v520) - [What's New in v5.3.0](#whats-new-in-v530)
- [What Is This?](#what-is-this) - [What Is This?](#what-is-this)
- [The Configuration Problem](#the-configuration-problem) - [The Configuration Problem](#the-configuration-problem)
- [Quick Start](#quick-start) - [Quick Start](#quick-start)
@ -45,16 +45,31 @@ A Claude Code plugin that checks configuration health, suggests context-aware im
--- ---
## What's New in v5.2.0 ## What's New in v5.3.0
**Claude Code 2.1.114→181 compatibility + skill-listing budget.** A new orchestrated **Permission-rule & plugin-hygiene hardening.** Five additive scanner findings extend the
scanner, **SKL**, checks the model's skill-listing token budget: `CA-SKL-001` flags any permission, CLAUDE.md, and plugin surfaces — no new scanner, so the count stays **13**:
active skill description over the 1,536-char listing cap (silently truncated by CC 2.1.105),
and `CA-SKL-002` flags when the summed descriptions exceed the listing budget (~2% of context). - **DIS forbidden-param rules** — flags `Tool(param:value)` whose key is the tool's own
Five validators were refreshed for the settings and hook surface that shipped across canonicalizing field (`command`/`file_path`/`path`/`notebook_path`/`url`), which Claude Code
CC 2.1.114181 (new settings keys, `xhigh` effort, `MessageDisplay` + post-session hook silently ignores with a startup warning. Severity by intent: deny/ask = false security
events), and an adversarial gap-review eliminated a batch of false positives in the MCP and (medium), allow = dead config (low). Valid forms (`Bash(npm:*)`, `WebFetch(domain:host)`,
permissions scanners. → **13 orchestrated deterministic scanners** (+ standalone plugin-health). `Agent(model:opus)`) are never flagged.
- **DIS ineffective allow-wildcards** — unanchored tool-name globs in `permissions.allow`
(`*`, `B*`, `mcp__*`) that CC silently skips, plus `Tool(*)` treated as deny-all
(`Bash(*)``Bash`) so a bare allow killed by it is reported as dead config.
- **CML context-window-scaled char budget** — mirrors CC's own *"Large CLAUDE.md will impact
performance (X chars > 40.0k)"* startup warning; anchors on the conservative 200k window and
discloses the relaxed ~200,000-char figure at 1M context. Char-keyed, complementary to the
existing line checks.
- **PLH plugin namespace collision** — flags two or more plugins declaring the same `name` in
`plugin.json`; their namespaces collapse and Claude Code silently drops the loser's components.
- **feature-gap `disableBundledSkills` lever** — recommends disabling bundled skills when the
active skill listing is over budget (remediation companion to `CA-SKL-002`).
The cross-plugin command-name finding is reframed from a HIGH conflict to a **LOW ambiguity** to
match Claude Code's namespacing (`/name:command` keeps both commands reachable). `--json` and
`--raw` output remain byte-stable.
--- ---
@ -603,6 +618,7 @@ This plugin is cautious by design — configuration files are important, and a b
| Version | Date | Highlights | | Version | Date | Highlights |
|---------|------|-----------| |---------|------|-----------|
| **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.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.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 | | **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 |

View file

@ -31,6 +31,13 @@
| `/code-review` bundled review skill | v2.1.147 | Renamed from the former cleanup skill; reports correctness bugs at a chosen effort (`/code-review high`), `--comment` posts inline PR comments. | | `/code-review` bundled review skill | v2.1.147 | Renamed from the former cleanup skill; reports correctness bugs at a chosen effort (`/code-review high`), `--comment` posts inline PR comments. |
| `/config key=value` | v2.1.181 | Apply any setting from the prompt (e.g. `/config thinking=false`) — interactive, `-p`, and Remote Control. Lets `/config-audit` settings recommendations be applied without hand-editing settings.json. | | `/config key=value` | v2.1.181 | Apply any setting from the prompt (e.g. `/config thinking=false`) — interactive, `-p`, and Remote Control. Lets `/config-audit` settings recommendations be applied without hand-editing settings.json. |
## v5.3.0 scanner-backing facts (verified 2026-06-19)
| Fact | Source | Backs |
|------|--------|-------|
| **"Large CLAUDE.md will impact performance (X chars > 40.0k)"** — Claude Code emits this startup warning when a CLAUDE.md exceeds ~40,000 chars. CC 2.1.169 scales the threshold with the model's context window: ~40.0k at a 200k-context model, relaxing to ~200,000 chars at 1M context. The figure is a **char** count, not a line count — complementary to the 200/500-line adherence guidance (a file can be long by lines yet under budget, or short by lines yet over it). | CC changelog 2.1.169 + live startup-warning text | CML `CA-CML` char-budget finding — anchors on the conservative 200k window (fires earliest, since the user's window is unobservable) and discloses the relaxed 1M figure. Window constants in `scanners/lib/context-window.mjs`. Severity medium (token cost, not an adherence cliff). |
| **`Tool(param:value)` permission matching is deny/ask-only.** The `param:value` form is honored only in `permissions.deny` and `permissions.ask`; in `permissions.allow` it matches nothing (dead config). Separately, a rule whose key is the tool's own *canonicalizing field*`command` (Bash/PowerShell), `file_path` (Read/Edit/Write), `path` (Grep/Glob), `notebook_path` (NotebookEdit), `url` (WebFetch) — is **ignored** by CC, which emits a startup warning. Valid parameter forms (`Bash(npm:*)`, `WebFetch(domain:host)`, `Agent(model:opus)`) are honored. | code.claude.com/docs/en/permissions | DIS forbidden-param finding (`forbiddenParamRule` in `permission-rules.mjs`): deny/ask = false security (medium, the block never applies), allow = dead config (low). |
## Official Configuration Guidance (Anthropic) ## Official Configuration Guidance (Anthropic)
These principles are backed by official docs and verified community reports. Use them to ground recommendations. These principles are backed by official docs and verified community reports. Use them to ground recommendations.

View file

@ -56,3 +56,14 @@ uncertainty band.
| medium | Materially inflates token cost per turn (cache miss, schema bloat) | | medium | Materially inflates token cost per turn (cache miss, schema bloat) |
| low | Detectable inefficiency that compounds across long sessions | | low | Detectable inefficiency that compounds across long sessions |
| info | Informational signal — no action required, may indicate room for optimisation | | info | Informational signal — no action required, may indicate room for optimisation |
## Skill-listing budget lever: disableBundledSkills
When the active skill listing exceeds its token budget (SKL `CA-SKL-002`), the
`disableBundledSkills` setting is a direct token-efficiency lever: it removes the descriptions
of plugin-bundled skills from the skill listing injected into the system prompt, shrinking the
per-turn baseline. Unlike trimming individual descriptions (`CA-SKL-001`), it is a single switch
that drops the entire bundled-skill surface at once — appropriate when the bundled skills are not
in active use. feature-gap surfaces it as a conditional recommendation, the remediation companion
to `CA-SKL-002`. Sibling levers: `skillOverrides` (selectively re-enable specific skills) and
per-skill description trimming.