# v5.3.0 Release — Multi-Session Plan _Status: PLANNED. No version bump yet. `plugin.json` = 5.2.0. All work below is gated on explicit operator GO per session. Plans live next to STATE per the continuity system._ ## Goal Release **v5.3.0** (minor, backward-compatible) covering the work that has accumulated on `main` since the v5.2.0 release (`1576909`, 2026-06-18), with a **fully updated README + CHANGELOG**. The features are already implemented and on `main`; the bulk of this release is documentation, changelog narrative, version sync, and a tag — plus a decision on whether any remaining CC-gap items should ship in 5.3.0 first. ## Pre-verified facts (do NOT re-derive) - Last release: **v5.2.0** = commit `1576909`, 2026-06-18. Prior: v5.1.0 (2026-05-01). - Unreleased commits on `main` since v5.2.0 (8): | Commit | Type | 5.3.0 changelog section | |--------|------|-------------------------| | `0a631e3` | refactor(skl): extract skill-listing budget to shared lib | Internal | | `dfe9049` | feat(feature-gap): `disableBundledSkills` under listing pressure | Added | | `03949c6` | feat(dis): ineffective allow wildcards; `Tool(*)` = deny-all | Added | | `b0bf8c5` | feat(cml): context-window-scaled CLAUDE.md char budget | Added | | `d678765` | feat(dis): forbidden-param permission rules | Added | | `c6c5f17` | feat(plh): plugin namespace collision (same declared name) | Added | | `0874188` | fix(plh): cross-plugin command overlap HIGH→LOW | **Changed** | | `96743ec` | fix(readme): add SKL row to scanner table `[skip-docs]` | Fixed (docs) | - **Scanner count unchanged: 13.** The 7 features extended EXISTING scanners (CML/DIS/PLH/GAP) — no new scanner file. So the `scanners-13` badge, the table (now 13 rows after `96743ec`), and `countScannerShape` need **no change** for 5.3.0. Do not bump the scanner badge. - **One behavior change to call out** (`0874188`): the cross-plugin command-name finding went **HIGH → LOW** and was reframed from "conflict" to "ambiguity" (namespacing keeps both commands reachable). Scoring impact: any config with cross-plugin command-name overlap scores slightly higher now. Not a `--json`-shape break; no test asserted the old HIGH (verified 2026-06-19). Document under **Changed**, not Breaking. - Suite at HEAD: **936/936**. self-audit: configGrade A 97, pluginGrade A 100, readmeCheck.passed. - Edit-target files (from the v5.2.0 release pattern, `docs/v5.2.0-release-plan.md`): `.claude-plugin/plugin.json`, `README.md` (badges + What's New + version-history row + TOC), `CHANGELOG.md` (`## [5.3.0]` block above `## [5.2.0]`), and `docs/cc-2.1.x-gap-matrix.md`. --- ## Session A — Release-readiness audit & scope decision (read/plan; 1 doc output) **No code changes.** Decide exact 5.3.0 scope and surface the "build more first?" question. 1. **Reconcile `docs/cc-2.1.x-gap-matrix.md` against current code.** STATE flags it as stale. For each matrix row, mark which of the 7 feature commits closed it; list every still-open gap. 2. **Classify each still-open gap** → `ship-in-5.3.0` / `defer-to-5.4` / `wontfix`, with a one-line rationale and effort tag. **Operator GO required** on the ship-list before any build. 3. **Draft the CHANGELOG narrative** — map all 8 unreleased commits to Added/Changed/Fixed/Internal bullets (table above is the starting point). Draft the "What's New in v5.3.0" prose. 4. **Confirm version = 5.3.0** (minor) and write the Changed-note for the PLH severity downgrade. 5. **Knowledge review** — check whether any `knowledge/*.md` corpus file needs an update for the 7 features (e.g. permission-rule or plugin-namespacing corpus). List files to touch, if any. **Output:** updated `cc-2.1.x-gap-matrix.md`; a `## v5.3.0 scope decision` block appended to THIS file (ship-list + operator GO + draft changelog bullets + knowledge-touch list). **Verifisering (testbar):** - Every one of the 8 unreleased commits appears in exactly one draft changelog bullet. - Every still-open matrix gap has a `ship/defer/wontfix` verdict recorded. - Operator GO on the ship-list is recorded verbatim in the scope-decision block. - `git log 1576909..HEAD` count matches the number of mapped commits (no commit dropped). --- ## Session B — (conditional) implement approved remaining features **Runs only if Session A's ship-list is non-empty.** If empty → skip entirely; 5.3.0 is a docs-and-release-only version. - One feature per chunk, **/tdd: failing test FIRST** (Iron Law), then minimal implementation. - Per feature commit: self-audit gates + docs-gate (README **and** CLAUDE ≥3 substantive lines, or `[skip-docs]` for non-feature commits). Stage docs in a separate Bash call before commit. - If a feature adds a **new scanner**, THEN (and only then) bump the `scanners-` badge, the table, and `countScannerShape` — and note it for Session C's "What's New". - Checkpoint STATE + this plan after each feature (chunk-before-compaction). **Verifisering (per feature):** new tests RED→GREEN; full suite N/N; self-audit configGrade ≥ A, pluginGrade ≥ A, readmeCheck.passed; contamination-grep + gitleaks clean on any snapshot/fixture touch. --- ## Session C — Release v5.3.0 (version sync + docs + tag + push) 1. **Bump** `.claude-plugin/plugin.json` 5.2.0 → 5.3.0. (Version lives ONLY here per STATE.) 2. **README:** - `version-` badge → 5.3.0; `tests-` badge → current exact case count. - Replace "What's New in v5.2.0" with **What's New in v5.3.0** (+ update the TOC anchor at the top). - Insert a new **version-history table row** above the `**5.2.0**` row. - Sweep for stale prose. **Scanner count stays 13** unless Session B added a scanner. 3. **CHANGELOG.md:** insert `## [5.3.0] - ` block above `## [5.2.0]` (Added / Changed / Fixed / Internal / Test count / Verification — mirror the 5.2.0 block). 4. **Knowledge/docs:** apply any updates Session A flagged. 5. **Marketplace cross-repo (CONDITIONAL — verify first):** check whether the marketplace catalog (`../.claude-plugin/marketplace.json` or the marketplace README) references config-audit's version or feature list. If yes → update there too. Separate repo → **same push-window rules, separate push**. (Not yet confirmed to exist; Session C verifies before assuming.) 6. **Gates (all must pass before commit):** - `node --test 'tests/**/*.test.mjs'` → N/N green. - `node scanners/self-audit.mjs --json --check-readme` → readmeCheck.passed, configGrade A, pluginGrade A, scanner count consistent with badge+table. - SC-5 snapshot byte-equal (or re-seeded + contamination-grep clean); gitleaks clean. 7. **Commit** `release: v5.3.0 — `, **tag** `v5.3.0`, **push** (plugin repo; marketplace repo if step 5 applies) inside the push window. **Verifisering (testbar):** - `git tag --list v5.3.0` returns `v5.3.0`. - README `version-` badge value == `.claude-plugin/plugin.json` `version`. - `self-audit --check-readme` → `readmeCheck.passed: true`, badge tests == suite case count. - `git log -1` subject starts with `release: v5.3.0`. - If marketplace updated: its config-audit entry shows 5.3.0. --- ## Key assumptions (test, don't trust) - **5.3.0 is non-breaking.** Verify: `json-backcompat` + `raw-backcompat` + snapshot tests green (they are at HEAD); the PLH severity change alters a severity VALUE, not the `--json` shape, and no test/consumer asserts the old HIGH. If Session B adds anything that changes the JSON shape or scoring math materially → re-classify as a Breaking note (like the 5.0.0 row). - **docs-gate** blocks any commit lacking ≥3 substantive lines in BOTH README and CLAUDE — use `[skip-docs]` for pure release/doc commits, or make both edits substantive. (Proven 2026-06-19.) - **self-audit `--check-readme`** only checks badge NUMBERS vs filesystem, NOT prose-table completeness — so manually re-verify the scanner table and "What's New" by eye (the SKL-row gap `96743ec` slipped exactly because the gate is number-only). ## Out of scope (do not start without separate GO) - New CC-gap features beyond Session A's approved ship-list. - Any scanner refactor not required by an approved feature. - Marketplace-wide changes beyond the config-audit catalog entry. --- ## v5.3.0 scope decision (Session A output, 2026-06-19) ### Operator GO (recorded verbatim) > **"Release-only, ship-list tom"** — Session B SKIP; knowledge-backing (disableBundledSkills, > 40k char-budget, forbidden-param) folded into Session C; open M-gaps → v5.4 backlog. **Ship-list = EMPTY.** Session B is skipped entirely. v5.3.0 is a docs + knowledge + release of the work already on `main`. No new feature build. ### Reconciliation result (matrix vs. current code) The gap-matrix was the **v5.2.0** plan. Verified against HEAD: the entire HIGH-priority false-positive cluster is **already CLOSED** — `settings-validator` (all 11 keys + `xhigh`), `hook-validator` (28 events incl. `MessageDisplay`/`post-session`), `mcp-config-validator` (POSIX/auto-injected env + `trust` removed), `claude-md-linter` (HIGH→MEDIUM reframe), DIS/CNF (param-aware). The 8 unreleased commits add incrementally on top. **No active false positive or behavior bug remains unshipped.** Full row-by-row verdicts appended to `cc-2.1.x-gap-matrix.md`. ### Still-open gaps → verdicts (all defer; none are bugs) | Gap (matrix row) | Effort | Verdict | |---|---|---| | PLH shadow-folder: plugin.json key shadows default component folder (129) | M | defer-5.4 | | permissions: acceptEdits prompts on shell-startup/build-config writes (141) | M | defer-5.4 | | permissions: Read-deny hides Glob/Grep; Windows backslash/case path (140) | M | defer-5.4 | | settings: autoMode.hard_deny nested-structure validation (144) | M | defer-5.4 | | PLH: validate `skills:` array entries are dirs within plugin (130) | M | defer-5.4 | | CLAUDE.md: nested `.claude` closest-wins conflict detection (104, 131) | M | defer-5.4 | | Knowledge L-rows: env vars, model-lineup nuance, hook-output fields, plugin/skill doc rows | S | defer (rolling knowledge maintenance) | ### Draft CHANGELOG narrative (all 9 commits `1576909..HEAD` accounted for) **Added** - **DIS forbidden-param rules** (`d678765`) — flags `Tool(param:value)` whose key is the tool's own canonicalizing field (`command`/`file_path`/`path`/`notebook_path`/`url`); CC 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)`) never flagged. Predicate `forbiddenParamRule` in `permission-rules.mjs`. - **DIS ineffective allow wildcards + `Tool(*)` deny-all** (`03949c6`) — 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____*` never flagged. - **CML context-window-scaled char budget** (`b0bf8c5`) — 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 in shared `scanners/lib/context-window.mjs`. - **PLH plugin namespace collision** (`c6c5f17`) — 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 declared `name`, not `basename(dir)`; name-less plugins excluded. - **feature-gap `disableBundledSkills` lever** (`dfe9049`) — 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** (`0874188`) — 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/consumer asserted the old HIGH. **Fixed** - **README scanner table** (`96743ec`) — 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** (`0a631e3`) — `scanners/lib/context-window.mjs` as single source of truth for the 200k/1M window constants, re-exported by `skill-listing-budget.mjs` and consumed by the new CML char-budget finding. **Excluded from changelog:** `9b828fa` `docs(plan): v5.3.0 multi-session release plan [skip-docs]` — the plan meta-commit itself, not a product change. (9 commits total = 8 mapped + 1 excluded.) ### What's New in v5.3.0 (draft prose) > **v5.3.0 — permission-rule & plugin-hygiene hardening.** Five additive scanner findings extend > the permission, CLAUDE.md, and plugin surfaces: DIS now catches forbidden-parameter rules and > ineffective allow-wildcards that Claude Code silently ignores; CML mirrors CC's own 40.0k-char > "large CLAUDE.md" startup warning, context-window scaled; PLH flags two plugins that declare the > same name (one silently shadows the other); and feature-gap recommends `disableBundledSkills` > when the skill listing is over budget. The cross-plugin command-name finding is reframed from a > HIGH conflict to a LOW ambiguity to match Claude Code's namespacing. Scanner count stays **13** > (all extend existing scanners). `--json`/`--raw` remain byte-stable. ### Version & non-breaking confirmation - **5.3.0** (minor). Additive findings + one severity downgrade (PLH HIGH→LOW). No envelope/JSON shape change; `json-backcompat` + `raw-backcompat` + SC-5 snapshot green at HEAD. The PLH change alters a severity VALUE, not the shape. **Document the downgrade under Changed, not Breaking.** ### Knowledge-touch list (apply in Session C step 4) Three short backing entries for the v5.3.0 features (rows currently absent from the corpus — verified by grep, 0 files each). Pure docs, no scanner/test impact: 1. `knowledge/prompt-cache-patterns.md` — `disableBundledSkills` as a token-efficiency lever (hides bundled-skill descriptions from the system prompt). (matrix row 167) 2. `knowledge/claude-code-capabilities.md` *or* `prompt-cache-patterns.md` — the CC 40.0k-char "Large CLAUDE.md will impact performance" startup warning + 2.1.169 context-window scaling (backs the new CML finding). 3. `knowledge/claude-code-capabilities.md` — `Tool(param:value)` permission semantics: param matching is deny/ask-only, and the canonicalizing-field rules CC ignores (backs DIS forbidden-param). (matrix rows 137, 139) Everything else in the matrix (env-var rows, model-lineup nuance, hook-output fields, plugin/skill doc rows) → **defer** to rolling knowledge maintenance; not required for 5.3.0 correctness.