fix: correct plugin-system inaccuracies and harden references - #2
Merged
Conversation
Audited every file against current official Claude Code docs (verified this session) and fixed the inaccuracies found: - marketplace.json: drop off-schema `owner.url` (the documented owner object supports only `name` + `email`) and use the documented contact field with a role-based shared inbox; add the `$schema` pointer to the published SchemaStore marketplace schema for editor validation. - MIGRATION-PLAYBOOK.md: components are namespaced by the plugin's own `name`, not the marketplace name (`/<plugin-name>:foo`); correct the prior `/melodic-software:foo` claim. Tighten userConfig detail: supported types include directory/file, and non-sensitive values are stored under `pluginConfigs[<id>].options`. - CLAUDE.md: make the canonical-docs table comprehensive (plugin dependencies, slash commands, memory, the .claude directory, tools reference) and cite the SchemaStore JSON Schemas for the repo's JSON. Sources: plugins-reference, plugin-marketplaces, sub-agents, memory docs at code.claude.com; schemas at json.schemastore.org. `claude plugin validate .` passes (only the expected "no plugins defined" warning). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 28, 2026
This was referenced Jul 4, 2026
Merged
This was referenced Jul 11, 2026
feat: add review-toolkit plugin (6 reviewer agents + quality-gate and code-review-fanout skills)
#71
Merged
This was referenced Jul 12, 2026
kyle-sexton
added a commit
that referenced
this pull request
Jul 12, 2026
Address two more Codex P2 findings plus the analogous coaching case: - codebase-detection case (#2): the eval repo has no real auth-flow module, so grounding would fail or reward inventing sources. Reframe to the routing + graceful-degradation invariant — resolve to codebase mode, discover from live files, and ask the user to point when no grounding exists rather than inventing repo sources. - primary-source case (#5) and coaching case (#4): a fresh topic invocation runs the mission interview before teaching, so expecting immediate content rewarded skipping the mission gate. Make both gate-aware — respect the new-workspace mission flow while asserting the grounding / one-question-coaching invariants.
This was referenced Jul 12, 2026
kyle-sexton
added a commit
that referenced
this pull request
Jul 13, 2026
… hardening (#138) Applies the resolved `planning/setup` hardening to `knowledge/setup`'s `library_dir` seam (same single-directory `userConfig` shape, same latent issues). ## Changes **`plugins/knowledge/skills/setup/SKILL.md`** - **Precedence** — step 1 now resolves the full documented order (Managed > `--settings` > Local > Project > User), warns when higher layers are unreadable instead of declaring a lower value authoritative, and surfaces layer shadowing before the project write. - **Portability** — step 5 guards the tracked project write: never propagate a machine-specific personal-layer value into team settings; route personal-only overrides to `.claude/settings.local.json` (portability required only for the shared project write). - **Declared-convention alignment** — inspect the repo's declared working-notes/artifacts convention even when a value is set; surface divergence and offer to reconcile. **`plugins/codebase-audit/skills/setup/SKILL.md`** (partial match — writes a tracked `.md`, not settings) - Applied only the precedence/shadowing subset: step 1 reports the *effective additively-merged* config across user-global → team → local layers (and warns on unreadable layers), instead of summarizing the team file alone. Settings-write portability specifics do not apply. ## Deviations (own-flagged) 1. **Fix #3 premise softened for knowledge.** The issue's fix #3 parenthetical assumed knowledge "honors that convention over the config at write time" (true for planning). Verified via `skills/youtube/extraction/lib/work-root.js` and the youtube pipeline that **knowledge resolves `library_dir` directly at write time — no skill overrides it with a repo convention at runtime.** Documenting that behavior would be false, so I softened the imported write-time-override claim: `library_dir` is runtime-authoritative, and setup's job is to keep it *aligned* with any declared convention. Fixes #1 and #2 are unaffected. 2. **`codebase-audit` version bump not in issue scope.** Patch-bumped `0.1.0 → 0.1.1` because its SKILL behavior changed; the issue only specified the `knowledge` minor bump. ## Verification - `knowledge` `plugin.json` minor bump `0.2.0 → 0.3.0`; `codebase-audit` `0.1.0 → 0.1.1`. - `claude plugin validate` clean on both plugins. - markdownlint clean on both edited files. Refs melodic-software/medley#1463 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Changes are limited to plugin skill documentation and version metadata; no application runtime or security-sensitive code paths are modified. > > **Overview** > **Hardens setup skills** for the `knowledge` and `codebase-audit` plugins so interactive setup reflects layered config reality instead of treating a single team file as authoritative. > > For **`knowledge/setup`**, step 1 now follows the full Claude Code precedence chain (Managed → `--settings` → Local → Project → User), warns when higher layers are unreadable, and calls out when a project write would stay shadowed. A new step reconciles `library_dir` with repo-declared working-notes conventions even when a value is already set. Persistence (step 5) blocks copying machine-specific personal paths into tracked project settings, routes personal-only overrides to `.claude/settings.local.json`, and the output section documents honest pipeline behavior (`book-distill` ignores `library_dir`; YouTube does not yet honor it). **`knowledge`** bumps **0.2.0 → 0.3.0**. > > For **`codebase-audit/setup`**, step 1 is expanded to summarize the **effective merged** config across user-global → team → local layers (including dimension opt-outs via empty source lists), explain that only the team file is written, and warn when overlays block re-enabling dimensions. **`codebase-audit`** patch-bumps **0.1.0 → 0.1.1**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f13139a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
kyle-sexton
added a commit
that referenced
this pull request
Jul 15, 2026
## Summary Executes the owner-approved tier-2 restores from the salvage sweep (items #2–#12 plus semantic-drift items D1–D4): pre-migration behavior and guidance dropped at the cutover, restored and genericized to the marketplace's repo-agnostic seams. Every touched plugin gets a version bump and CHANGELOG entry. | Plugin | Version | Restored | |---|---|---| | claude-config-audit | 0.4.0 | Pre-computed context blocks (3 skills) + `allowed-tools` scoping; all script paths `${CLAUDE_PLUGIN_ROOT}`-rooted; every `!` command empirically tested with fallbacks | | event-storming | 0.3.0 | `--design-level` missing-prerequisite guard (never fabricate a process model) + eval id 7; bare "memory" refs swept to the `${CLAUDE_PLUGIN_DATA}/history.jsonl` seam | | planning | 0.9.0 | Agent-team vs fan-out composition guidance in /architect Step 4.5 (decompose by context boundary, never lifecycle role; disjoint file ownership); baseline capture routes to `/implementation:verify-improvement` SSOT when installed; devils-advocate regains the `/implementation:verify-changes` pointer | | session-flow | 0.4.0 | Retro ecosystem-improvement catalog (`reference/`, 221 lines) — hook-event table reconciled against the current hooks doc (8 events added, 2 medley errors fixed); handoff failure-pattern `context/gotchas.md` | | review-toolkit | 0.5.0 | Normalization-pipeline model assignment (Stage 0/3 Sonnet, 1–2 deterministic/Haiku, 4 deterministic) + per-stage heading annotations | | implementation | 0.5.0 | Optional `tool-pin` version-drift warning in /lint + ecosystem-commands contract 1.1.0 (additive schema key, per the contract's own versioning rule); /implement over-correction trap logs to the session retro when installed | | codebase-audit | 0.2.0 | Background/unattended Phase 1 fan-out variant (graceful-degrade framing) | | code-tidying | 0.4.0 | Stdlib-only frontmatter-fence integrity check in the self-update lane (pass/fail paths tested) | | prototype | 0.2.1 | Composition table (fully-qualified marketplace names, `when installed` gating); named `session-flow:handoff` seam in the auto-invoke gate | ## Playbook compliance - Repo-agnostic: coupling grep over all added lines is clean (no medley paths, no consumer-repo names, no reach-outs); cross-plugin references use fully-qualified names with graceful "when installed" degrade. - Fresh-docs: `disable-model-invocation`/frontmatter, `${CLAUDE_PLUGIN_ROOT}` substitution scope ("Skill and agent content — anywhere the placeholder appears"), and the hook-event table were verified against code.claude.com docs this session. - `docs/conventions/ecosystem-commands/` confirmed repo-owned (not a standards-managed materialization) before the schema edit. - All nine plugins pass `claude plugin validate`; catalog passes `claude plugin validate --strict`; new/changed markdown passes markdownlint-cli2 (0 errors); the new eval validates against `evals.schema.json`. ## Security review note (claude-config-audit 0.4.0) The pre-computed context blocks add a code-execution-at-skill-load surface: `!` commands run when the skill is invoked. Scope check per the plugin-acceptance review: all commands invoke scripts **bundled inside the plugin** via `${CLAUDE_PLUGIN_ROOT}` (no `../` reach-outs, no absolute paths), are read-only inventory/count operations, carry `|| echo`-style fallbacks so load never hard-fails, and make no network calls. The `allowed-tools` entry pre-approves exactly the one bundled read-only script, nothing broader. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_011xHkkNc7CR98L8Xz9Mu7ZA --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
kyle-sexton
added a commit
that referenced
this pull request
Jul 16, 2026
… follow-ups) (#205) ## Summary The three follow-ups deliberately deferred out of #204 (recorded in its PR body), each decision-gated with the maintainer before editing. Net **−341 lines**; no plugin manifest, schema, or skill behavior touched. ## #1 — Retire the audit snapshots Delete `docs/evals-coverage.md` and `docs/extensibility-contract-grading.md`. They were hand-stamped, point-in-time records that drift the moment a plugin changes (the reorg already forced a two-layer temporal re-stamp). **Retire over generate.** The durable policy already lives in `docs/MIGRATION-PLAYBOOK.md` — the warrant rule + consumer-verify recipe ("Evals — warrant policy and consumer-verify recipe") and the four-seams contract ("Extensibility contract v2.1"). A generator could derive only eval *presence* (a live glob) — the minority of one doc and none of the other; class, contract grades, and medley program state stay irreducibly hand-graded or externally-owned. Generating only the presence slice yields a half-generated hybrid that still drifts on its biggest surface. Retire is the clean fit. **Gaps captured first.** Two warranted-but-unowned eval gaps were recorded *only* in the retired snapshot (verified still live against the tree): `context7/setup` and `planning/wayfind`. Filed durably before deletion: - `melodic-software/medley#1537` — evals(context7/setup) - `melodic-software/medley#1538` — evals(planning/wayfind) Inbound pointers updated: README doc-index (2 bullets removed) and the playbook's evals section (now states on-demand verification instead of pointing at a deleted snapshot). No dangling references remain (repo-wide grep clean). ## #2 — Reclassify the depth-variant convention tension The playbook stated a depth/intensity variant "takes an argument, never a sibling," yet `discovery`'s `explore-deep` / `research-deep` ship as sibling skills. Inspection shows they are **structural, not depth**: - `explore-deep` — `context: fork` + `agent: general-purpose`: a distinct execution *topology* (isolated forked subagent), declared in frontmatter, not expressible as a runtime argument. - `research-deep` — a dispatcher to the heaviest isolated tier (workflow engine, forked subagent, or inline fallback), with its own body and auto-invocation description. The convention needed no exception — it needed a sharper structural/depth test. Amended to classify **execution tier as a structural axis** (sibling) and bind the `-deep` suffix to that axis, so the naming no longer reads as a violation and a future reader does not re-flag it. A true effort knob on one execution path still takes an argument. No skills renamed. ## #3 — README revisit-condition dedup Assessed, closed **no-op**. The coupling flagged in #204 is a documented, directional SSOT+index: `docs/CATALOG-TAXONOMY.md` (L71–73) declares plugin-scoped revisit conditions are *owned by each plugin's README* and the taxonomy "Trigger register" lists them "only as pointers." The READMEs are the single owners of genuine plugin-specific rationale; the register summarizes them. Nothing to dedup. Confirmed none of the three sections cross-names the taxonomy doc. ## Verification - `scripts/validate-plugins.sh`: pass (all manifests + strict catalog sync) - `scripts/run-plugin-tests.sh`: 7 passed, 0 failed - `markdownlint-cli2`: 0 errors on both touched markdown files - Repo-wide grep for the retired doc names: no remaining references ## Note (not in this PR) `docs/hook-migration-audit.md` is the same "point-in-time audit" genus as the two retired here. Left untouched; flagged for a consistency decision in a later pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0163dXPBdRYFpx4wTtS648tE Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Aug 11, 2026
kyle-sexton
added a commit
that referenced
this pull request
Aug 11, 2026
The refuting pass found real defects in the orchestrator's own work for the sixth session running, and the review gate was right twice more. WRONG BOOK ON SIX LINES. The punctuation sweep asked "is the ASCII form absent from ANY of the four books?" That is not "does the book this passage cites print it that way?", and the difference is load-bearing: the 2009 book genuinely prints ASCII apostrophes (2,373 ASCII against 6 curly in its own EPUB) while 1991, 2011 and 2014 print curly, so every line Pat reprinted in 2009 got a free pass. - song-forms.md:581,582,584,587 — a block cited to 1991 at :567, in a section whose own line 564 warns that 2009 prints the same lyric differently. The file documented the trap and the sweep walked into it. - brainstorm.md:148, object-writing.md:420 — the two lines settled by hand; both blocks are cited to 2011 and both were aligned against 2009. Anchor uniqueness within 2009 was never the question. Each repair is asserted present in its citing book and absent before the change. RECEIPT ACCURACY. The changelog reported 468/468 and 393 quotation marks. The shipped totals are 470/470 and 396 — 308 apostrophes plus 396 quotes, 704 characters. The old figures described the state before the two hand-applied lines. Corrected, along with the same error in T4's line-number citations. TWO CLAIMS IN voices.md WERE FALSE. - The public-toggle warning was described as disputed in its own thread. It is not: a reader asked a clarifying question and the poster re-affirmed it. Being told to discount a safety warning on the strength of a dispute that does not exist is worse than not raising it. The source is the poster, not "one commenter", and the warning applies to every voice creation. - The section asserted in bold that the bootstrap "agrees with" the file's existing "sing actual melodies, not spoken word" rule. It does not. That rule's reason is that the model must learn your sung timbre; here the only audio a human performs is speech, and voice #2 learns from Suno's synthesis of a speech-trained clone. Record the tension, never resolve it away — the first version broke this project's own standing rule. Now stated as unresolved, with the better-supported route named, plus two further unrecorded interactions: the anti-impersonation phrase compares against "your uploaded singing" while stage 4 uploads generated audio, and the reported ~95-100% Audio Influence sits above the 85%+ over-fit tier this same file describes. REVIEW GATE. troubleshoot.md:19's effect column still read "Trailing tags ignored" as a certainty after its cause column was hedged. Softened to match. NEWLY INCOHERENT STEP. troubleshoot.md's "Exclusions are being ignored" fix list opened with a step that then told the reader it was not a verified rule — a fix list whose first step fixes nothing. Moved out of the numbered list to prose. Also: v55-features.md now says "no source was found placing them" rather than asserting a completed search; the [Fade In] qualifier moved out of the table cell to prose, matching the [Synth Solo] precedent it cites; book-references.md no longer claims the README carries all four full catalogue titles (1991's dc:title carries a subtitle the README drops); and README.md now points back at book-references.md, since the regrowth guard only protected one direction. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
kyle-sexton
added a commit
that referenced
this pull request
Aug 11, 2026
…y finding, and stop calling the addition mechanical (#2206) ## Summary `claude-config`'s `audit` skill had a two-link defect chain in Category B. Batch-4 reconciliation **AD-13** requires both links ship as one change, and they do. **Link 1 — no channel for hook coverage to retract a baseline finding (#2201).** Category B iterates the baseline permission patterns and states flatly that each "must appear" in `permissions.deny`, rated `error`. Its only two off-ramps are keyed on the *consuming repo* writing prose: a documented exemption in its own rules files (`required-permissions.md:138-142`), or its own documented hook conventions (`:157-160`). Neither is keyed on a hook that is actually installed and enabled, and `grep -rn "hook"` across the whole skill returns no `hooks.json` read, no plugin-hook enumeration, and no coverage concept at all. So a repo that blocks `git push --force` with a `PreToolUse` hook exiting 2 — which [permissions.md](https://code.claude.com/docs/en/permissions.md) says "stops the tool call before permission rules are evaluated, so the block applies even when an allow rule would otherwise let the call proceed" (raw fetch, 2026-08-11) — was told its security floor was missing. "Narrowing the baseline" now carries a third narrowing: a family already blocked by an **installed, enabled** `PreToolUse` hook is `info`, not `error`, whether the hook came from the repo or from a plugin. It obliges the report to name the residual — plugin disable/uninstall, per-guard opt-out, and `allowManagedHooksOnly` / `strictPluginOnlyCustomization` — because hook coverage is contingent in ways a deny rule is not, and an `info` that hides that is worse than the `error` it replaced. And because the skill genuinely cannot enumerate a plugin's `hooks/hooks.json`, a run that took no inventory now states the finding **conditionally** ("if a `PreToolUse` hook on `Bash` already blocks this family, this finding is void") rather than asserting it. Fail open, not fail silent. **Verification sharpened the wiring half.** The two existing off-ramps were not in Category B's instruction path at all — the category delegates by *pattern* ("iterate the patterns in required-permissions.md") and `audit-checklist.md:21-24` says "assert presence per sub-category". Neither names the off-ramp sections. A third off-ramp added to `required-permissions.md` alone would inherit that same weak wiring, so Category B and the checklist's B.1–B.3 severity table now both point at "Narrowing the baseline", and the table says its ratings are the *unnarrowed* ones. (`audit-checklist.md` is not in the ledger's fix sketch; it is added deliberately under AD-13's own logic — leaving a flat `error` rating there would have left a third file asserting the opposite.) **Link 2 — the false positive was routed into `--fix` as mechanical (#2202).** `procedures.md:49` graded "Add missing baseline deny rules" `Auto-fixable: Yes (from checklist)` / `Requires judgment: No`, and `SKILL.md:212-214` restated that in prose. It is now judgment-required with the judgment written out — is the family already covered, and would the addition suppress a gate the project built deliberately. *Moving* a deny rule from local to project stays mechanical (that is #8961 placement, not a policy change), and `SKILL.md` splits the two the same way. **Corrected rationale, stated so it is not shipped wrong.** The filed claim was "no human judgment gate", which is accurate as written and must not be read as "no human gate" — a *confirmation* gate exists at `SKILL.md:187-193` and is already pinned by eval #2. Adding a confirmation prompt is therefore **not** the fix. The residual harm is narrower: the matrix told the user this class of edit needed no thought, next to an offered reply `'all'` that applies the lot in one keystroke. Two more scope statements kept honest — the applied change was *more* deny rules, which is fail-closed rather than a security regression; and the ask-suppression harm requires a hook that **returns an `ask` decision**, since a hook blocking by `exit 2` short-circuits before permission rules and suppresses nothing. **What review added, and it materially improved the change.** Seven threads, all substantive, all addressed: - **The narrowing was too generous, three ways.** It is now fenced by three preconditions. The hook must be *live*: `disableAllHooks`, `allowManagedHooksOnly`, and `strictPluginOnlyCustomization` were named only as a future residual, and a hook one of them has already switched off blocks nothing, so under any of them the finding stands unnarrowed. The hook must be on the tool surface the pattern defends: `sensitive-file-deny` is a `Read`-pattern family, so a `Bash`-only hook leaves `Read`/`Grep`/`Glob` open and retires nothing there. And it must block *that* family — force-push coverage says nothing about `git clean -fd`, nor a long flag about its short spelling. - **The liveness precondition cited a check that did not exist.** It told the auditor to take the lever reading from Category D; Category D checks paths, readability, timeouts, matchers, exec-form resolution, duplicates, and events, and never asked whether the hooks it inventoried could run. All three lever names appeared nowhere in the skill. That is the same false-assurance shape this PR set out to remove, so **Category D now reads and reports all three** (`info` — a repo may set them deliberately, and the reading is state, not a defect), and where the reading was not taken the narrowing is **unavailable** rather than assumed clear. - **And the reading is sequenced.** Category B owns the narrowing and runs before Category D. A–I is presentation order, not a dependency ban, so Category B says to pull the reading forward or defer the downgrade and revise the severity after Category D runs. On a scope-filtered run like `/audit permissions`, which never reaches Category D, the narrowing is unavailable unless the operator supplies the state. - **Three pointer sites had gone stale** against my own tightening, still saying "installed, enabled". Fixed, then swept. - **The changelog shape misrepresented the bump.** Everything sat under `### Fixed` while the bump is minor. Two graded outputs genuinely move, so the behavior changes are now under `### Changed` with the reason up front, the wiring repairs under `### Fixed`, and the new material under `### Added`. Three evals, not one, and they grade the discriminations rather than the happy path: | # | Case | Grades | |---|---|---| | 8 | `baseline-deny-narrowed-by-installed-hook` | per-family narrowing — force-push and hard-reset drop to `info` under a live Bash hook, while `git clean` patterns it does not match and `sensitive-file-deny` Read patterns it cannot reach hold at `error` | | 9 | `no-hook-inventory-states-the-finding-conditionally` | the fail-open half — no inventory means a conditional finding, not an assertion | | 10 | `suppressed-hook-does-not-narrow-the-baseline` | the negative case the liveness fence exists for — a declared hook under `disableAllHooks: true` narrows nothing | No trust surface widened: no new hook, no new grant, no new external read or write. The permission guidance moves in the direction of fewer manufactured deny-rule additions, and the new Category D row is a read-and-report of settings the audit already has in hand. ## Test plan There is no executable test for this change — it is skill content plus `evals.json`, and this skill's `scripts/` cover plugin-drift and settings structure, not Category B prose. The honest gates are the static ones, all run against the working tree: ``` $ jq empty plugins/claude-config/skills/audit/evals/evals.json && echo "evals.json: valid JSON" evals.json: valid JSON $ jq empty plugins/claude-config/.claude-plugin/plugin.json && echo "plugin.json: valid JSON" plugin.json: valid JSON $ bash plugins/skill-quality/scripts/check-evals-quality.sh plugins/claude-config/skills/audit/evals/evals.json check-evals-quality: PASS (0 warning(s) across 1 file(s)) # (this one earned its keep — it caught eval 9 sharing eval 1's prompt verbatim, # which would have made the two gradeable only by out-of-band context) $ CHECK_SKILL_SKILLS_ROOT="$PWD/plugins/claude-config/skills" bash plugins/skill-quality/scripts/check-skill.sh audit INFO: description length 444/1536 chars INFO: all 3 base-ref trigger phrase(s) preserved INFO: SKILL.md 256/500 lines INFO: markdownlint clean INFO: script test passed: scripts/check-plugin-drift.test.sh INFO: script test passed: scripts/check-structure.test.sh INFO: script test passed: scripts/fix-plugin-drift.test.sh WARN: SKILL.md is 256 lines (soft target 200 — consider pushing detail to progressive-disclosure spokes) WARN: no Gotchas surface (inline '## Gotchas' or context/gotchas.md) — confirm the skill has no observed failure history INFO: no metadata.category in frontmatter (optional — category not machine-readable) INFO: shell: declared — dynamic-context injection portability is the author's explicit choice INFO: summary 90/100 codepoints CHECK-SKILL audit: PASS — 0 errors, 2 warning(s) $ npx --no-install markdownlint-cli2 --config .markdownlint-cli2.jsonc plugins/claude-config/CHANGELOG.md markdownlint-cli2 v0.23.2 (markdownlint v0.41.1) Summary: 0 issues in 0 files ``` Both `check-skill` warnings pre-date this change (the SKILL.md soft target and the absent Gotchas surface); this diff adds 4 lines to `SKILL.md`. Every gate above was re-run after each review round; the output shown is from the final tree. ## Related Closes #2201 Closes #2202 Inbox item: `20260810-225905-claude-config-audit-category-b-hook-blindness.md` (batch-4 ledger `I2`, rows `A1` + `A3`; row `V1` is folded into `A3`'s judgment wording per the ledger and is deliberately **not** filed separately). Ledger rows in `I2` left filed-not-fixed by design: `A2` (baseline recommends the pattern class upstream calls fragile — MED, adjacent section of the same file), `A4` (nothing reads a plugin's `hooks/hooks.json` — MED, and the reason the new off-ramp has to fail open rather than enumerate), `B5`'s Category G half (belongs to item `…-category-g-unmeasurable`), `MN1` (LOW). Issue filing for those rows is held pending the operator's call on batch-4 filing volume (RECONCILE OR-4). --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 11, 2026
feat(claude-config): make audit Category G executable and give the skill a real hook inventory
#2301
Merged
Merged
kyle-sexton
added a commit
that referenced
this pull request
Aug 15, 2026
Fills PLAN.md's empty `## Plan` with an eight-phase sequence and records the Tier B design early-exit that gates it. The spine is ordered by two constraints that are easy to miss. Fanout is findings producer #1, so the first detector of any kind makes producer #2 and the single-file consumer becomes a silent-shadowing bug -- coexistence is strictly phase 1, not merely early. And the owner doc precedes the *second* adopter, so the Pattern-C proof slice runs before the detector contract is written rather than after it. Draft only: the fresh-context stress-test has not been applied yet. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kyle-sexton
added a commit
that referenced
this pull request
Aug 15, 2026
…sues, contract-slice prune (#2686) No linked issue ## Summary Answers "what can we do with the maintenance-routine pattern" for this marketplace, and lands the answer as durable artifacts rather than a document. Eight research lanes and three verification passes ran to completion; this PR graduates what they settled and prunes the working slice. The research inverted the original framing three times, and the plan encodes the inverted shape: 1. **The apply machinery already exists and is reachable by file format alone.** What is missing, class after class, is a **detector** to feed it. Validated empirically, not inferred: a hand-written conforming file from a non-fanout producer passed the fix action's locator, frontmatter gate, exact-branch check, and table parse. 2. **Merge rate cannot justify any of this.** Peer-reviewed observational work, a large-N regression, and a randomized trial all find artifact quality weakly-to-not coupled to acceptance. The verification contract is justified on defect escape and reviewer burden, never acceptance. Nothing here cites the source's 388/180 figures as evidence of efficacy — a single self-report with no independent corroboration and no published methodology. 3. **Class-level beats instance-level.** Three lanes converged from different literatures: durable wins come from policy and mechanism, not from better per-instance agent judgement. ## Fix **ADR 0010 — merge findings across producers, and mark consumption explicitly.** The correctness gate the whole effort turns on. `review:fanout`'s fix action consumes exactly one findings file and merges nothing (`context/fix-pass-mode.md:3,7`), which is safe only while fanout is the sole producer. The first detector of any kind makes producer #2, at which point the later timestamp silently wins and the earlier producer's findings are never applied — no error, no warning, run reports success. Three decisions, each with a rejected alternative that had a real case: - The consumer merges the conforming set instead of picking the newest, and unions the coverage fields rather than reporting one producer's. - Cross-producer dedup is **presence-only**. The existing ±3-line key sits behind a Sonnet semantic stage the fix action does not have, and adopting the bucket without the semantics would invert the pipeline's own minimise-false-merge rule and silently discard a remediation. - The applied-plan record becomes a **consumption ledger** written on every apply path. It is currently written only under `--yes` in a non-interactive session, so any bound anchored on it is a no-op on the path most runs take. **Eight phase issues**, each carrying its own ADR-0004 incumbent evidence inlined as `path:line` — deliberately not a pointer into the gitignored `.work/` tree, which no delegated worker, fresh session, or second machine can read: | Issue | Phase | |---|---| | #2678 | `feat(review)`: merge findings across producers (implements ADR 0010) | | #2679 | `docs(conventions)`: detector-findings owner doc (stub) | | #2680 | `feat(mutation-testing)`: persist survivors as a conforming findings file | | #2681 | `docs(conventions)`: harden detector-findings with the rule-id to severity crosswalk | | #2682 | `feat(autonomy)`: catalog rows for every routine class considered | | #2683 | `feat(autonomy)`: reviewer-burden promotion term, recorded as deferred | | #2684 | `feat(testing)`: can't-fail test audit plus fail-closed `--check` mode | | #2685 | `spike`: per-repo routine capability detection, promoted to its own topic | **The contract slice is pruned** in this PR's final commit, per `docs/conventions/topic-docs/README.md:43`. Recover the full PLAN.md and the design resolution from the commit before the prune: ```bash git show 5341117:docs/topics/boris-routines-adoption/PLAN.md git show 5341117:docs/topics/boris-routines-adoption/design/design-resolution.md ``` ## Verification - `bash scripts/check-contract-slice-prune.sh --check-diff origin/main` — exits 1 before the prune commit (it named both slice paths), exits 0 after. That transition is the point of the final commit. - `npx markdownlint-cli2` — 0 issues across ADR 0010, PLAN.md, and design-resolution.md. - Per-phase sanity-check invariant, measured rather than asserted: `awk '/^### Phase [0-9]/{p=$0;c[p]=0} /Sanity Check/{if(p!="")c[p]++} END{for (k in c) if (c[k]==0) print k}'` printed nothing — all ten numbered phases carried at least one mechanically verifiable check. - Two independent fresh-context review passes ran against the plan with the authoring rationale withheld: an adversarial pass (2 CRITICAL, 8 HIGH) and a mechanics pass (1 CRITICAL, 7 IMPORTANT). Every finding acted on was re-verified against the file before the plan was changed. Details in the collapsed section below. <details> <summary><b>What the review passes caught</b></summary> Both CRITICALs from the adversarial pass landed on the coexistence design and both held: - **The staleness bound could not exist on the path the plan runs.** `fix-pass-mode.md:76` — "Interactive and headless-stop paths write no record". The solo shape is the interactive path, so the merge set would have grown without limit, re-injecting findings that `:95`'s required post-fix re-review had already resolved. The draft would have regressed a documented loop while claiming to close a correctness gate. - **The dedup key was not mechanically available.** `findings-normalization.md:77` places dedup at "Stage 3 Sonnet (semantic merge)"; `:66` orders "Minimize FALSE-MERGE over FALSE-SPLIT — a false merge silently drops a real issue". The fix action runs no LLM stage. The mechanics pass then executed rather than argued its CRITICAL: `check-contract-slice-prune.sh --check-diff origin/main` exits 1 on this branch, which is what produced the prune commit and the branch-shape decision. It also repaired five sanity checks that could not pass as written — a bare `check-changelog-parity.sh` exits 2 on usage; a `grep -c … returns 0` check inverts its own exit code, so the success case failed and a wrongly staged file passed; a forbidden-metric grep passed vacuously on zero matches; two checks named a state with no command. Other corrections worth recording: `docs/PLUGIN-PHILOSOPHY.md:471` is a **deadline** ("before a second plugin adopts it"), not a licence to author an owner doc late — and the pilot phase is itself the second adopter, hence the stub-then-harden split. `routines.md:192,195` already carry `dead-code-sweep` and `coverage-mutation-watch`, so the catalog phase gained an existing-row sweep as its first work item. The new skill takes the `audit` leaf and joins the registered owner set rather than picking `scan` to sidestep the argument the registry asks for. And the routine-delivery gap is bound to `liveness-assertion`'s two-limb Core contract instead of being deferred by scope, which was not one of the permitted answers. </details> <details> <summary><b>The locked Brief (the contract this plan was built to)</b></summary> ## Brief ### TLDR Generalize the maintenance-routine pattern reported by @bcherny (2026-08-13) into tool-, org-, and product-agnostic capability for this marketplace: **detectors** that emit conforming findings, plus **catalog rows** governing them, plus the **substrate** both need. Not a port of his eleven routines, and not a new plugin. The research inverted the original framing three times, and the Brief encodes the inverted shape: 1. **The apply machinery already exists and is reachable by file format alone** (validated, below). What is missing, class after class, is a **detector** to feed it. 2. **Merge rate cannot justify any of this.** Three independent lines — peer-reviewed observational, large-N regression, randomized trial — find artifact quality weakly-to-not coupled to acceptance. The verification contract is justified on **defect escape** and **reviewer burden**, never on acceptance. 3. **Class-level beats instance-level.** Three lanes converged from different literatures: durable wins come from policy and mechanism, not from better per-instance agent judgement. ### Goal Ship, in dependency order: - **Tier 0 substrate** — the four items below, which every candidate class depends on. - **Tier 1 detectors** — three classes with the strongest evidence and a real local surface. - **Catalog rows** for every class considered, including the ones deliberately not built, so the reasoning is recorded rather than re-litigated. ### Constraints **Binding repository rules** (verified, `path:line` in the research record): - **ADR 0005** — a new class extends the existing catalog: a `reference/` edit plus a `CHANGELOG.md` entry plus a version bump. **Not a new catalog, not a new skill, not a new plugin.** This closed the original "where does it land" question; it is not reopened here. - **ADR 0004 incumbent-first gate is binding** — no remediation ships until it proves no existing skill covers it, with `path:line` evidence. Satisfied for all eight classes by `research/V1-coverage-negatives.md`; each issue carries its own evidence. - **ADR 0008** — a row is admitted only when its observable is anchored to text that is present. An obligation a surface *should* satisfy, anchored to nothing, does not become a row however well sourced. - Version bump **and** matching CHANGELOG entry in the same PR (CI-enforced, zero exemptions); `metadata.workflow-stage` required; regenerate `docs/CATALOG.md` and `docs/SKILL-CHEAT-SHEET.md`; SKILL.md under 500 lines; **evals required for any new skill**; only `docs/topics/` is docs-only-allowlisted, so anything under `plugins/**` runs the full CI suite. **Product constraints** (verified at primary, `code.claude.com/docs/en/routines.md`, 2026-08-14): - Routines are available on **Pro, Max, Team, and Enterprise** — the mechanism is reachable on this account. Claude Tag (the Slack surface the source used) is Team/Enterprise-only and is out of reach; only that delivery surface is unavailable, not the capability. - **Minimum schedule interval is one hour.** Runs count against a per-account daily allowance; **one-off runs do not**, which is the pilot lever. - **No permission containment during a run** — "no permission-mode picker and no approval prompts". Containment is repo selection, environment, connector list, and the `claude/`-branch push rule. - **Repo `.claude/` loads; user-scope `~/.claude` does not.** `pluginConfigs` is ignored at project scope by design, so any plugin taking `userConfig` has no cloud-run way to receive values. - **Green status ≠ success** — "It does not mean the task in your prompt succeeded." Efficacy reads logs, never statuses. - **Workflows do not travel into scheduled runs**; custom slash commands do. **Evidentiary constraint:** the source is a single self-report with zero independent corroboration and no published methodology. Nothing in this plan may cite 388/180 as evidence of efficacy. ### Acceptance criteria Per-unit close-out loop — one class at a time: incumbent evidence recorded → row derived through the catalog's own mapping rules → detector or deferral shipped → CI green → CHANGELOG + version bump in the same PR. A class is **closed** when its row exists with a derived guardrail class and either a shipped detector or a `join:` trigger naming what would unblock it. 1. **Findings-file coexistence is settled before a second producer ships.** The fix action consumes exactly one file and merges nothing; two producers in one branch directory means the later timestamp silently wins. Green run, hidden findings. This is a correctness gate, not a nicety. 2. **Every detector emits machine-computed severity**, not prose routed through an LLM crosswalk. No crosswalk row exists for a deterministic surface today; that is contract work, not a detail. 3. **Every class-level gate satisfies items 1-2 of the trust-path definition** (below). Items 3-5 are org-scale and explicitly deferred at solo volume. 4. **No acceptance-rate metric anywhere** — not as a promotion input, not as an efficacy signal. 5. Each shipped detector carries evals, per the CI gate. ### Captured assumptions - The format-only path stays supported. **Validated 2026-08-14, not assumed**: a hand-written conforming file from a non-fanout producer passed the fix action's locator, frontmatter gate, exact-branch check, and table parse, including the cell-escaping rule. Probe deleted afterward — while it existed it *was* the newest file in that directory and would have shadowed a real review. - Detectors are scripts unless a named agent is earned. The repo's own philosophy prefers one script "wherever the judgment is mechanical", and fanout can dispatch **agents only** — which is why `mutation-testing:audit`, the best deterministic detector in the fleet, reaches no relay today. - Catalog rows derive their guardrail class through the existing mapping rules, never by hand. ### The class-level trust path (the operative definition) An **instance-level** path asks a judge to evaluate each change on its merits. A **class-level** path decides once, for a category, what condition makes any member acceptable — so the per-instance question collapses from a judgement to a check. The mechanism: per-instance persuasion is subject to habituation; a standing class rule is not. | # | Requirement | Portable? | |---|---|---| | 1 | Class definition narrow enough that membership is decidable without judgement | **yes** | | 2 | Machine-checkable gate that fails closed | **yes** | | 3 | A denominator — enough instances to compute a rate | org-scale | | 4 | An outcome signal that is **not** the merge decision | org-scale | | 5 | A lookback window and a demotion rule | org-scale | "Dead-code removal where the code is provably unreachable" is a class. "Code quality improvements" is not. If deciding membership needs the judgement you were eliminating, it is an instance-level path wearing a class-level label. Solo shape: **the gate without the statistics** — narrow class, machine-checkable gate, run it *before* the PR opens, human on the merge. The earned auto-merge tier is deferred with a trigger. ### Scope — tiers **Tier 0 — substrate. Blocks everything.** | Item | Why | |---|---| | Findings-file coexistence | Silent-shadowing correctness bug the moment a second producer exists | | Detector contract | Machine-computed severity, rule/threshold vocabulary, suppression; owner doc must precede the **second** adopter | | Per-repo capability detection | The agnostic core: which classes bind, resolved from repo state (build files, language, test framework, flag system, architecture config, MCP servers, CLI tools) | | Repo-scope plugin declaration | User-scope does not load in cloud; **gated on the cloud probe** (below) | **Tier 1 — build.** Formal-logic modeling (decision tables + property-based testing; strongest evidence, and its mechanical artifacts *are* the verification payload) · useless-test **repair** queue (genuinely uncovered; the fleet names the capability it lacks) · layering enforcement, **inform-human posture** (most mechanical once rules exist; propose-and-baseline, never impose-and-fail). **Tier 2 — rows now, build later.** Dead code, both postures, with a **30-90 day** window floor and staged quarantine — never the source's one-day window · clone **detection** + trend gating (the unify *decision* has no automation precedent in twenty years) · stale-flag removal (strong prior art; consumer-facing, no local surface). **Tier 3 — rows recording why not.** Logic simplification above expression level (no published effectiveness evidence; excluded by name in `tidyings.md`) · abstraction flattening (no validated detector exists, and the fault data runs backwards — Speculative Generality and Middle Man sometimes *reduce* faults) · ant-only shipper (the decision is a human product call) · GUI crash fuzzing (no local surface; 36.6% crash-replay reproducibility). ### Out of scope - A new plugin, a new catalog, or a parallel governance surface (ADR 0005). - A self-tuning routine class. Across 22 verified papers, none tunes from deployed production outcomes with a human gate; the famous citations are within-episode and do not persist. The existing promotion apparatus is the better-grounded shape and already avoids the merge-rate confound by keying on completions, gate passes, and reverts. - Auto-merge without human review at solo volume — requirements 3-5 above are unmeetable here. - Porting the source's prompts. They are a **meta-prompt** (instructions to *create* routines), one layer above any stored prompt. ### Deferred questions - **Q12 (arbiter: USER-RESERVED)** — repo-scope plugin declaration in cloud. **Filed as [#2660](#2660 (`needs-human`). Two official pages contradict each other on whether repo-declared marketplace plugins install; workspace trust for a cloud clone is undocumented, and if untrusted the declaration is ignored **silently**; private-marketplace auth in cloud is undocumented. One probe settles all three, and it cannot run unattended — browser selection, account mutation, and metered usage all require the human. Tier 0's fourth item is blocked on it; the documented alternative (components committed directly to `.claude/`) is the fallback and needs no marketplace fetch, trust step, or credentials. - **Q4 follow-on (arbiter: `/planning:plan`)** — add a reviewer-burden term to the existing promotion predicate, and keep any future tuner's signal set disjoint from promotion evidence. Composition hazard if not: a tuner could raise the metric that promotes the cell that reduces scrutiny of the tuner's own output. - **Q2 (resolved, recorded)** — `join: proven recurring manual pattern` stays our-own-proven. The source's run is named-product evidence and belongs in the routine-catalog research record, not the non-normative precedent-pointers section, whose own scope line routes it elsewhere. - **Live daily run-cap numbers (arbiter: USER-RESERVED)** — the docs direct readers to `claude.ai/code/routines`; published figures trace to a stale April blog post. Needs an authenticated session. </details> ## The plan's shape Ten phases, sequential. Blast radius HIGH. Full bodies, work items, and sanity checks live in the eight issues above; the spine is: ```text P1 coexistence ──> P2 convention stub ──> P3 Pattern-C pilot ──> P4 harden ──> P7 detector (must merge to main) ^ P5 catalog rows ──> P6 predicate term ────────────────────────────────────────────┘ P8 capability detection ── promoted to its own topic P9 repo-scope declaration ── blocked on #2660 P10 graduate + prune ── this PR ``` Three ordering constraints, none obvious: - **P1 before any detector** — fanout is producer #1, so the first detector of any kind makes producer #2. - **P2 before P3** — a new cross-plugin convention lands in an owner doc *before a second plugin adopts it*, and P3 is that second adopter. - **P2 merged to `main` before P3** — a plugin cannot cite a repo-relative `docs/conventions/` path, because it installs standalone. The established form is a raw URL to `main`, which only resolves once the convention is merged. ## Approved reductions against the Brief Both were surfaced as scope cuts rather than absorbed, and accepted: - **Tier 1: three detectors to one.** Ships can't-fail tests (#2684); formal-logic modeling and layering enforcement become catalog rows with named triggers. - **Detection, not repair.** The Brief names a repair *queue*; a judgment-shaped finding is surfaced rather than auto-applied, so the queue-and-apply half needs its own decision. - **One deviation:** the Brief's per-unit close-out loop is batched stage-at-a-time, because the substrate phases are shared by every class and a per-class loop would re-pay them N times. ## Follow-up outside this PR `AGENTS.md` is 28 lines at HEAD and no longer carries the exec-bit or Windows-filemode guidance — commit e22190e's managed sync deleted the 34 lines 7c2a9b3 had added four commits earlier. It is a managed materialization, so a local patch is removed by the next sync; the fix belongs upstream in `melodic-software/standards`. The exec-bit CI gate still runs and is ungated by the docs-only allowlist, so the constraint is live while its documentation is not. ## Related - Refs #2678, #2679, #2680, #2681, #2682, #2683, #2684, #2685 — the eight phase issues this PR files - Refs #2660 — repo-scope plugin declaration in a cloud run (`needs-human` spike); Tier 0's fourth item is blocked on it, and the documented fallback proceeds regardless - Refs #2649, #2650 — mutator-gating defects found during the research sweep - ADR 0010 — `docs/adr/0010-merge-findings-across-producers-and-mark-consumption-explicitly.md` --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 15, 2026
Merged
kyle-sexton
added a commit
that referenced
this pull request
Aug 15, 2026
… reviewer-burden term (#2694) Closes #2682 Closes #2683 Phases 5 and 6 of the boris-routines-adoption plan, in **one PR by design** — one autonomy version bump, one CHANGELOG entry. Splitting them either duplicates the bump or strands one without its changelog line, and `check-changelog-parity.sh` fails on both. Independent of the detector chain (#2690 / #2692); nothing here blocks on those merging. ## Why rows for classes we are not building A catalog that lists only what shipped cannot be reasoned from. A reader asking *"why is there no clone unifier?"* finds silence, and silence reads as an oversight rather than a decision. **Nine rows added, one existing row amended**, and every derivation run **through the mapping rules** (`routines.md` "Mapping rules (catalog to matrix)"), never by hand — that is this phase's whole discipline. ## Existing-row sweep (first work item) Run against `routines.md` itself, not the research record. Per candidate class, "no row" or the existing row's identity: | Candidate | Sweep result | |---|---| | dead code | **Row exists** — `dead-code-sweep`, `DET detect \| DC (review-gated PR) \| repo \| n/a — no agent session \| not-a-routine`. → **amended**, not duplicated. | | clone work | **No row.** The nearest row, `coverage-mutation-watch`, is a **different observable** — coverage and mutation score, not clone density — so it is no match and was not amended. → new row. | | the other eight | **No row.** → new rows. | `clone-trend-gate` ships a **byte-identical cell signature** to `coverage-mutation-watch` (`DET | R (digest/gate) | repo | n/a — no agent session | not-a-routine`). The rows are genuinely distinct — clone density and its trend versus coverage and mutation score — and because nothing in the six cells says so, a class parameter now states it. Two rows that read as a copy-paste duplicate need the difference written down somewhere. **The issue's line citations had drifted.** It cites `dead-code-sweep` at `:192` and `coverage-mutation-watch` at `:195`; they are at `:191` and `:193` on `main`. The row *identities* and their full cell text match exactly, so the sweep result stands — but the offsets are not uniform (1 and 2), so the numbers were re-resolved rather than adjusted. ## ADR-0004 incumbent gate — the search record #2682: *"ADR-0004's incumbent gate applies to rows here, not only to detectors."* ADR-0004 D-1 requires the search carry `path:line` evidence. It is recorded here rather than in `routines.md` because that contract is deployment-agnostic — an adopting org does not ship this marketplace, and a binding parameter grounded in what *this* repository happens to contain is the same defect as grounding one in this fleet's hardware. What the search *changed* in the contract is in the contract; the evidence trail is here. | # | Class | Verdict | Evidence | |---|---|---|---| | 1 | `formal-logic-modeling` | **No incumbent** | Searched `TLA+`, `Alloy`, model-checking, invariant-verification, design-by-contract vocabulary across `plugins/`. No hits that were not false positives. | | 2 | `cant-fail-test-repair` | **Partial** | `plugins/mutation-testing/skills/audit/SKILL.md:126` — surviving-mutant disposition surfaces tests that cannot fail a given mutant. Remediation (`:201-209`) authors **new** killing tests via `/testing:write`; it does not repair the existing tautological assertion, which is this class's whole content. | | 3 | `layering-enforcement` | **Incumbent** | `plugins/review/agents/architecture-guardian.md:3` — "Reviews code for dependency-direction violations, layer boundary breaches…"; `:33` checks "inner layers must not reference outer layers; follow the project's stated layer rules." Close match, same inform-human posture. **Already reflected in the row**: its join trigger requires "a recurring manual pattern the incumbent reviewer does not already cover", and its parameter requires clearing the incumbent gate against the existing architecture-review surface. | | 4 | `clone-trend-gate` | **No incumbent** | Searched clone-detection tool names, `clone densit`, `copy-paste detector`, `code clone`. `plugins/review/agents/code-reviewer.md:46` flags "Duplicated Code" ad hoc during diff review — not a density trend or a gate. | | 5 | `stale-flag-removal` | **Partial (weak)** | `plugins/code-tidying/skills/tidy/templates/host-wiring-lane.template.md:16` lists "stale feature-flag branches" as one example under the Dead Code tidying. A bare example phrase inside a glob-scoped lane; no flag-age tracking, no staleness detector, no single-variation-everywhere trigger. | | 6 | `logic-simplification-sweep` | **No incumbent, at either altitude** | Above expression level: `tidyings.md` has no cross-function control-flow restructuring; Beck's Guard Clauses (`plugins/code-tidying/skills/tidy/reference/tidyings.md:15`) restructures within one method only. At expression level: searched `boolean expression`, De Morgan, `redundant condition`, `simplif.*expression` across `plugins/code-tidying/` — **zero matches**. `plugins/code-tidying/skills/batch-simplify/SKILL.md:140` delegates to an external agent not present in this repo, with instructions naming no altitude. | | 7 | `abstraction-flattening` | **Partial — the closest call in the set** | `plugins/architecture/skills/improve/research/deepening/scan-briefing.md:49-51` (two-adapter rule → "speculative indirection") and `research/deepening/vocabulary.md:28` (the deletion test: "If complexity vanishes, it was a pass-through") detect the same smells this class targets. But the lens's remedy is *deepening*, it applies no fix itself, and it routes through a human interview and planning handoff (`SKILL.md:63`) — there is no autonomous change path. | | 8 | `ant-only-shipper` | **No incumbent** | Searched champion/challenger, canary, shadow deploy, A/B, promote-to-production, competing-implementation vocabulary. `plugins/prototype/skills/explore-directions/SKILL.md` is adjacent — throwaway UI variations picked by a human in-browser — not an evidence-based promotion recommender. | | 9 | `gui-crash-fuzzing` | **No incumbent** | Searched `fuzz`, monkey-test, random-click, GUI-crash, UI-stress vocabulary. All hits false positives. | | 10 | `dead-code-sweep` (amended) | **Partial** | `plugins/code-tidying/skills/tidy/reference/tidyings.md:21-25` — Beck #2 Dead Code covers detection and verified deletion inside a scoped lane. It has **no quarantine-then-judge staging**, which is the entire normative content of the amendment. | ### What the search changed - **`abstraction-flattening`'s "no validated detector" was under-qualified.** Heuristic detectors for exactly these smells ship — including in this marketplace. The parameter now says what is actually true and what the join trigger actually names: *a scanner is not the join trigger; a published validated detector is*, and none surveyed is validated against a fault-outcome ground truth. - **`logic-simplification-sweep`'s "already covered by structure-only tidying surfaces" was false**, and the search is what established that — there is no incumbent at either altitude. The claim is removed rather than restated. - **No verdict removed a row.** Two partials (`cant-fail-test-repair`, `dead-code-sweep`) are "detection exists, the remediation shape does not", which is a capability gap rather than a duplicate. `layering-enforcement`'s real incumbent was already gated in the row before this search. ## Rows added **Tier 1 — join triggers** | Class | Judgment | Output | Access | Derived | Status | |---|---|---|---|---|---| | `formal-logic-modeling` | AGT | R | repo | `C1` | join: a stated invariant or specification artifact exists to model against | | `cant-fail-test-repair` | hybrid: DET detect; AGT repair judgment is the routine | DC (PR) | repo | `C3` | join: proven recurring manual pattern | | `layering-enforcement` | AGT/HUM | R | repo | `C1`; disposition human-gated | join: layering rules stated as text, and a recurring manual pattern the incumbent reviewer does not already cover | **Tier 2** | Class | Note | |---|---| | `dead-code-sweep` | **Amended.** Was `DET detect` only; the quarantine-exit judgment makes it hybrid, and that portion derives `C3` — liveness is *not* mechanically checkable, since reflection, dynamic dispatch, and out-of-tree callers each defeat the build that would otherwise prove it. Window floor **30–90 days with staged quarantine, never one day**, and not tunable downward by an org binding. | | `clone-trend-gate` | `DET \| R (digest/gate) \| repo \| n/a \| not-a-routine`. Detection and trend gating **only**. | | `stale-flag-removal` | hybrid; removal portion derives **`C4`** — a flag definition is a configuration surface, and the structural-blast-radius rule composes above `C2`/`C3`. Disposition human-gated. | **Tier 3 — recording why not** | Class | Why not | |---|---| | `logic-simplification-sweep` | `C3`; `join (external)`: published effectiveness evidence exists. | | `abstraction-flattening` | `C4` (structural surface); `join (external)`: a validated detector is published. The fault data also runs *backwards* — Speculative Generality and Middle Man are in some studies associated with **fewer** faults. | | `ant-only-shipper` | `AGT/HUM`, `C1`, human-gated. The promotion decision is a product call. | | `gui-crash-fuzzing` | `not-a-routine` (DET). Reported crash-replay reproducibility is low enough that filing every crash would degrade the governed queue rather than feed it, so its `WI` output is replay-gated. The row also carries the isolation consequence the catalog had skipped: unattended GUI actuation requires `L3`. | ## Exclusions are exclusions, not deferrals Recorded as such, because a deferral invites a future PR to "finish" the class: - **`clone-trend-gate`** — the unify *decision* is excluded, not a deferred posture. No surveyed clone-detection tool automates deciding which clones to unify, across a detection literature the survey found spanning two decades. On that record there is nothing to defer *to*, so adding a unify posture re-opens the class rather than extending it. - **`gui-crash-fuzzing`** — judging a filed crash beyond replay is excluded the same way. A filed crash is ordinary queue intake, owned by the issue-lifecycle classes. Without this the row's `DET → not-a-routine` exit would be skipping a judgment portion, which is precisely the misreading `routines.md` §"What a routine is" is worded to prevent. - **`stale-flag-removal` / `ant-only-shipper`** — the disposition never automates. Which branch survives, and whether to promote, are product calls. That is why both rows are `AGT/HUM`. - **`layering-enforcement`** — inform-human posture only; a direct-change posture derives `C4` and no surveyed precedent supports one. ## The contract is now three tiers, explicitly The new `Class parameters` section carries normative detail six table cells cannot hold — stated as **binding**, so a leaf contradicting one is non-conforming. That created a contradiction with three statements in the same file saying definition depth exists only for the `v1` classes, while `clone-trend-gate` and `gui-crash-fuzzing` — neither of which will ever gain a leaf — carry parameters. **Resolved by widening, not collapsing.** The hub now declares three tiers: catalog plus mapping rules; class parameters, binding any class leaf or not; leaf-level depth for the ten `v1` classes. Collapsing the parameters back into row cells was the alternative and was rejected — the section exists precisely because the cells cannot carry the detail, and several parameters bind `v1` and hybrid rows generally rather than one deferred class. ## Four general derivation rules now live in the mapping rules `## Mapping rules` exists, in its own words, *"so an adopting org can classify a **novel** routine class end-to-end… without a contract change."* Three general rules were filed under `### Class parameters` instead — two of them titled with a class token while generalizing in their last sentence (*"The same reading applies to every `AGT/HUM` row"*; the structural axis *"keys on blast radius"*). An org reading the mapping rules would not have found them. All three moved: the hybrid portion-split rule onto the hybrid bullet under *Judgment and output*; the `AGT/HUM` clarification onto its existing bullet; the target-not-file rule onto *Structural blast radius*. A **fourth** was stranded the same way inside a `dead-code-sweep` note and is now stated generally: a risk-raising axis evaluates **per item** as well as class-wide, so a class whose axis fires on only some items derives the lower class and records the escalation rather than deriving the higher one wholesale. **One honest limitation now stated in the rules themselves.** The structural axis keys on the change's *target*, and **no catalog column records a target** — which is why `logic-simplification-sweep` and `abstraction-flattening` carry byte-identical axis cells (`AGT | DC (PR) | repo`) and derive `C3` and `C4`. Rather than leave a reader to conclude the three axis columns are sufficient when they are not, the rule now says the target comes from the class's own definition and that a row turning on it says so in its `Derived row` cell. ## A second `join` semantic, separated Every pre-existing `join:` trigger is a condition the adopting **org** can satisfy: connect a telemetry surface, write the layering rules down, accumulate a manual pattern. `published effectiveness evidence exists` and `a validated detector is published` are world state no adopter can act on. One token carrying both semantics made those two rows read as backlog items. A `join (external): …` legend row now separates them. Rewording the two triggers into adopter-actionable form was the alternative and would have been dishonest — the point is that the org *cannot* fire them. An `excluded:` status was also rejected: these classes are genuinely deferred pending evidence, unlike the unify decision, which is excluded outright. Every other `join:` row in the table was re-checked against the new definition; none belongs under the new one. ## #2683 — the predicate side - **What may never enter a predicate.** An acceptance or merge rate is never a promotion input and is not an efficacy signal, in either role, at any cell, at any threshold. - **Two shipped terms sit close to that line, and both are now distinguished.** `0 human-reverted merges` is a *correctness* signal — a human asserting the change was wrong after it landed — not an acceptance rate. And `≥ 20 autonomous C2 merges over ≥ 14 days` is a **volume floor**, not a rate: a ratio rises when its denominator shrinks, so attempting less — or attempting only what is certain to land — raises it with no change in the work. A count has no denominator to shrink. Selectivity leaves it flat. - **The term inventory is now complete.** It previously enumerated four term types and the table has **seven** — merge counts, advisory-review counts, and missed-blocking-finding counts were all missing. All three are correctness- or volume-side, so nothing in the argument moved. - **Reviewer-burden term: deferred with an explicit trigger, not omitted.** It needs a denominator, and a denominator needs three org-scale things this contract does not have — a population to divide by, a non-merge outcome signal, and a lookback window with a demotion rule. Without them the term moves with *volume* rather than trustworthiness, which rewards a cell for producing less. Trigger: the volume **and** a non-merge outcome signal; volume alone is not the trigger. - **Standing constraint on any future tuner** — its signal set stays **disjoint** from promotion evidence. Overlap is a self-dealing loop: a tuner optimizing a signal that also promotes a cell can raise that signal to reduce the scrutiny applied to the tuner's own output. Binds the tuner's inputs, not its intent, and binds whether or not the reviewer-burden term is ever activated. ## Two claims in #2682 that did not verify — and one of the replacements did not either **#2682 says logic simplification above expression level is "excluded by name in `tidyings.md`".** It is not: `plugins/code-tidying/skills/tidy/reference/tidyings.md` contains **zero** occurrences of `simplif`, case-insensitive. **The first replacement for that claim was also false.** An earlier revision of this description said expression-level simplification is "already covered by structure-only tidying surfaces" and that simplification above that level "changes behavior in the general case". Both fail: - The incumbent search found **no incumbent at either altitude** — no cross-function control-flow restructuring in `tidyings.md`, and zero expression-simplification matches anywhere in `plugins/code-tidying/`. - "Changes behavior in the general case" is contradicted by `plugins/code-tidying/skills/batch-simplify/SKILL.md:174` — *"Simplification is behavior-preserving"* — which treats behavior alteration as a **regression** its verification exists to catch. It also contradicted the row's own cell, which claims only that equivalence above expression level is not mechanically checkable: weaker, and correct. A checkable-and-false claim had been replaced by an uncheckable one. The parameter now uses the row cell's own wording and drops the coverage comparison entirely; the `path:line` evidence lives in the incumbent table above, where it cannot rot a deployment-agnostic contract. ## Deployment-specific fact removed from normative text A binding parameter read: *"The fleet ships no GUI to fuzz, so the class has no observable here at all"* — inside a section declaring *"A parameter here binds the class; it is not commentary"*, in a contract whose own closing line is *"The contract assumes no machine, org size, or budget"* and whose hosting stance makes substrate a deployment-owned binding. An adopting org that ships GUIs would read a binding parameter grounded in **this** fleet's inventory. Struck. The deployment-independent half stays, and the class's `not-a-routine` derivation never depended on the inventory in the first place — it follows from Judgment `DET`, which holds for any deployment. **On #2682's present-observable admission check** (*"Drop any candidate anchored to nothing"*): the observable here is crashes surfaced by actuating a GUI — a real, nameable artifact class, not nothing. A deployment without a GUI simply never schedules the class, which is true of every access-gated row in the catalog and is not an admission question. The row is admitted; what was wrong was grounding its *parameter* in one deployment's inventory, not the row's presence. ## Empirical claims, hedged to the register the evidence supports The supporting research record is gitignored, so no in-tree reader can check any empirical claim in this contract. Several were stated at a confidence the reader has no way to audit: | Was | Is | |---|---| | "Published practice at scale runs an order of magnitude longer than a day" — ~10 days, which does not reach the 30-day floor it was offered to support | The floor derives from what the window must **out-last**: 30 days is the shortest window spanning a monthly invocation cadence at all, 90 spans a quarterly one, and a one-day window spans nothing | | "twenty years of clone-detection tooling produced no production automation" — a universal negative stated as fact | "no **surveyed** clone-detection tool automates the choice…, across a detection literature the survey found spanning two decades" | | "The flag-lifecycle tools that lead this space" | "The flag-lifecycle tooling **surveyed**" | | "No published effectiveness evidence supports automating it" — universal negative | "No effectiveness evidence… **surfaced in the surveyed literature**" | | "a direct-change posture … has no evidence behind it" | "**no surveyed precedent** supports one" | | "reproducibility around 36.6%" — two significant figures, no citation | "low enough that filing every crash would degrade the queue" — and the population shift is fixed too: the figure measured replay of *crashes*, and was being applied to *filed work items* | | "weakest precedent of the catalog" — a superlative over all forty-nine rows | "among the weakest precedent the survey found" | | "Three independent lines of evidence — peer-reviewed observational work, large-N regression, and a randomized trial", citing exactly one | The rule now rests on the one finding **verified at primary source** (Lenarduzzi et al., quoted verbatim); the other two design families are named as survey context, explicitly not checked | The target register is the one already-well-calibrated claim in the section — *"in some studies associated with fewer faults"* — which is left as it stands. ## Fresh-context verification, and the two contradictions it caught The edits above were checked by a **separate fresh-context agent** with the authoring session's reasoning withheld, briefed to judge whether each finding actually no longer holds, whether any fix introduced a new in-tree contradiction, whether the remaining empirical claims are calibrated, and whether every row still derives correctly. It re-derived six rows from the mapping rules and axis cells alone before reading the `Derived row` column: **six of six matched.** It found two real contradictions, both now closed: - **`gui-crash-fuzzing`'s Output cell (`R + WI`) contradicted its own binding parameter**, which said filing would degrade the governed queue. The previous revision masked this — *"the fleet ships no GUI to fuzz"* made the whole row moot, so the Output cell never had to agree with the parameter. Removing that escape exposed it. The `WI` output is now admission-constrained: an item is filed only where re-running the recorded input sequence reproduces the crash, and the rest stay in the `R` half. That gate is a re-run rather than a judgment, so it adds no `AGT` portion and the `DET` exit stays complete. - **`work-classes.md` deferred the reviewer-burden term on "the org-scale trust-path requirements this contract already defers"** — a phrase with **zero** other occurrences anywhere in the repository. A back-reference leaked from the gitignored research record into normative text, asserting a prior decision no in-tree reader can locate. The three requirements were already enumerated inline, so the phantom reference is dropped rather than manufactured. It also caught the stranded per-item rule, the missing-target-column limitation, the four over-claimed hedges above, and one SSOT gap outside the three files in play: **`guardrails/isolation-ladder.md` scoped `L3` to untrusted-provenance (`C5`) work alone**, while the catalog's access rule has always also required it for unattended GUI actuation — a demand that reaches classes deriving no work class, so it cannot travel through the matrix's min-isolation column. That leaf is the contract's source of truth for when a level applies, and was incomplete against its own charter. Fixed at the root rather than papered over in `routines.md`. ## Other corrections in this pass - **The posture-qualified-identity mandate was unsatisfiable for seven of the nine hybrid rows.** The new parameter made it mandatory for every hybrid row, while *Routine identity* says posture tokens are owned by the class's definition leaf — and seven hybrid rows are `join:`-deferred with no leaf. Scoped: tokens are minted with the leaf, so the obligation binds at leaf time; until then a deferred class records its split in its Judgment cell and binds nothing. - **The `L3` on `gui-crash-fuzzing` does not come from the matrix.** The guardrail matrix's min-isolation column is indexed by work class (`C1`–`C5`); a row deriving no class cannot reach it. The floor comes from the GUI-actuation mapping rule directly, and the row and its parameter now say so rather than implying a matrix lookup that would not resolve. - **`## Precedent pointers`' scope line claimed coverage it did not have.** It declared itself pointers "for the deferred and deterministic rows"; all nine new rows are deferred or deterministic and none got one. Narrowed to the rows where a shipped pattern was surveyed, with an explicit note that absence is not a claim that no pattern exists — rather than inventing nine pointers this pass has no evidence for. - **`dead-code-sweep`'s precedent pointer was stale against the amended row.** It described deletion pipelines with no quarantine stage while the row's whole normative content is staged quarantine — so it read as precedent for the unstaged form. It now says the staged quarantine is the row's own normative content, not a property read off those pipelines. - **`### Reviewer-burden term` sits under a preamble that did not cover it.** The preamble said "the threshold values below are suggested defaults the org binds"; a deliberately-not-live term with no threshold is not a suggested default. Promoting it to a sibling `##` was the alternative and was **rejected** — #2683 names §"Suggested default predicates" as its placement. The preamble was narrowed to the table instead, and now states that the two subsections after it are not defaults and carry no bindable threshold. - **CHANGELOG bullets re-filed per Keep a Changelog**, which the file's own header cites. The `dead-code-sweep` amendment and the derivation-rule bullet change existing content and moved to `### Changed`. The row count is now exact: **nine added, one amended** — class rows go 40 → 49, and "ten rows added" double-counted the amendment. (Commit `21fce8eb`'s body carries the same off-by-one; history is not rewritten, the durable surface is fixed.) ## Sanity checks — actual output, re-run at `c0795c93` - **No two rows share a class token** — `awk -F'|' '/^\| [a-z]/ {print $2}' … | sort | uniq -d` returns **empty**. Verified non-vacuous: the same pipeline yields **51** distinct tokens, against **41** on `origin/main`. The delta is **+10, not +9**: nine new class rows plus the new `join (external): …` status-legend row, which the pipeline also matches because legend rows begin `| join…`. Class rows alone go 40 → 49. - `grep -n "388\|180 merged" plugins/autonomy/reference/routines.md` → **empty**. - `grep -ci "never a promotion input\|no acceptance-rate\|not an efficacy signal" …work-classes.md` → **1**. - `grep -Eci "predicate .*(merge|acceptance) rate|(merge|acceptance) rate .*(threshold|>=)" …work-classes.md` → **0**. - `scripts/check-changelog-parity.sh --check-bump origin/main` → **exit 0** (autonomy 0.16.12 → 0.17.0). - `scripts/check-changed-skills.sh origin/main` → "No changed skills under `plugins/*/skills/`". - `markdownlint-cli2` on all four changed files → **0 issues**. ## Declared human gate — evidence recorded, disposition open #2682: *"a reviewer who did not author the rows re-derives three of them from the mapping rules and the row's own axis cells alone. No command self-clears this."* **A fresh-context agent performed the re-derivation. No human re-derived these rows, and this PR does not claim the gate is cleared.** An earlier revision of this description said CLEARED; that was the authoring session grading its own homework, and a fresh-context same-vendor agent is the middle rung of the independence hierarchy, not the reviewer #2682 names. The full record — the withheld-answer protocol, the agent's unprompted provenance statement, the three derivations, and this same caveat — is posted as a durable comment on **both** #2682 and this PR, so it does not live only in a commit body and a PR description written by the session that produced the rows. | Class | Independently derived | Authored | Match | |---|---|---|---| | `dead-code-sweep` | `C3` | `C3` | yes | | `stale-flag-removal` | `C4` | `C4` | yes | | `abstraction-flattening` | `C4` | `C4` | yes | Three of three. **The run predates three subsequent commits**, so it was performed against a superseded revision — but the later verification pass re-derived all three classes against the current text and reached the same three answers, so the result survives the edits rather than merely predating them. More useful than the match: the derivation showed the mapping rules *imply* three things they never *stated*, each of which the agent had to reason out to avoid a wrong answer. All three are now stated in `## Mapping rules` itself, alongside the fourth the verification pass found stranded. **What a human still owes this gate:** deciding whether an agent re-derivation satisfies it. The record exists so that call can be made against the actual protocol rather than against a summary. ## Related Independent of #2690 / #2692. Blocks the can't-fail test detector's row amendment (#2684). --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
kyle-sexton
added a commit
that referenced
this pull request
Aug 16, 2026
…, machine-health, source-control babysit) Second-pass application of simplification items the first pass had deferred, for the _scripts, knowledge#1, machine-health#1/#2 and source-control#1 buckets. Each bucket was verified by a fresh-context verifier agent (pass; knowledge#1 after one revise cycle). Adds small shared helpers: scripts/lib/{sync-cluster.sh,report-first-difference.mjs}, plugins/knowledge/skills/map-corpus/lib/gate_common.py, plugins/machine-health/skills/audit/tests/helpers/Invoke-CheckScript.ps1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 17, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full per-file audit of the repo against current official Claude Code docs (re-verified this session per the repo''s fresh-docs mandate). The vast majority of existing content was confirmed accurate; this PR fixes the real inaccuracies found and strengthens references. No code, only manifest/docs.
Real defects fixed
marketplace.json— off-schemaowner.url. The documentedownerobject supports onlyname(required) +email(optional) —urlis not a valid owner field. Replaced with the documented contact field using theinfo@melodicsoftware.comshared inbox (matches the docs''DevTools Team/devtools@example.comteam-alias example; no personal PII). Source: plugin-marketplaces "Owner fields".MIGRATION-PLAYBOOK.md— wrong namespacing. Components are namespaced by the plugin''s ownname, not the marketplace name. Corrected/melodic-software:foo→/<plugin-name>:foo. Source: plugins-reference (plugin-dev:agent-creatorexample).Polish / accuracy
marketplace.json— added$schema→ published SchemaStore marketplace schema (editor validation; Claude Code ignores it at load time).MIGRATION-PLAYBOOK.md—userConfigtypes also includedirectory/file; non-sensitive values stored underpluginConfigs[<id>].options.CLAUDE.md— canonical-docs table made comprehensive (plugin dependencies, slash commands, memory,.claudedirectory, tools reference) + cited the two SchemaStore JSON Schemas.Verified-correct (no change needed)
All plugin env vars/paths (
CLAUDE_PLUGIN_ROOT/DATA/PROJECT_DIR, cache/data paths),userConfig→keychain storage,hooks/hooks.json, agent shadowing precedence,extraKnownMarketplaces+CLAUDE_CODE_PLUGIN_SEED_DIRheadless guidance,claude plugin validate/--plugin-dir, all README commands, and.gitignore(CLAUDE.local.mdand.claude/rules/are both current, documented features).Validation
claude plugin validate .→ passes (exit 0; only the expected "no plugins defined" warning). JSON parses.🤖 Generated with Claude Code