config-audit/docs/v5.3.0-release-plan.md
Kjell Tore Guttormsen 891f9506bf docs(plan): v5.3.0 Session A — scope decision (ship-list empty) + gap-matrix reconciliation [skip-docs]
Session A audit (read/plan only). Reconciled docs/cc-2.1.x-gap-matrix.md (the
v5.2.0 plan) against HEAD: the entire HIGH-priority false-positive cluster is
already CLOSED in v5.2.0 (settings keys + xhigh, 28 hook events, MCP POSIX/trust,
claude-md HIGH->MEDIUM reframe, DIS/CNF param-aware). The 8 unreleased commits add
incrementally; no active bug or false positive remains unshipped.

Operator GO 2026-06-19: "Release-only, ship-list tom" -> Session B SKIPPED. All
still-open gaps are M-effort enhancements -> defer to v5.4. v5.3.0 = docs +
knowledge + release of the 8 commits already on main.

Output: scope-decision block appended to docs/v5.3.0-release-plan.md (empty
ship-list + verbatim GO + full draft CHANGELOG bullets mapping all 8 commits +
What's New draft + 3 knowledge-backing entries for Session C); reconciliation
block prepended to docs/cc-2.1.x-gap-matrix.md. Version confirmed 5.3.0 (minor,
non-breaking). 9 commits 1576909..HEAD = 8 mapped + 1 excluded (the plan commit).
2026-06-19 20:30:04 +02:00

15 KiB

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 gapship-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] - <release-date> 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 — <one-line summary>, 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-readmereadmeCheck.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 CLOSEDsettings-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__<server>__* 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.mddisableBundledSkills 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.mdTool(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.