Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
bump: patch
---

### Changed

- `/code-tidying:audit-dead-code`, `/code-tidying:batch-simplify` and the `/code-tidying:tidy`
self-update lane and exclusions reference no longer restate upstream behavior (LSP reference
counting, detector exit codes, gopls and staticcheck suppression, knip and vulture config
details, how injected commands run, git's `--since` parsing, frontmatter loading, hook
locations, `userConfig` types). Each keeps its own rule and links the upstream section with an
as-of date and a recheck trigger. The self-update lane drops its note on how consumers update.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
bump: patch
---

### Changed

- `/planning:design`, `/planning:plan`, `/planning:prd`, `/planning:interview` and
`/planning:draft-goal-condition` no longer restate upstream behavior (how injected commands run,
Mermaid's C4 support, plan mode, the `/plan` command, the `Plan` subagent, the `/goal`
evaluator, limit and permissions). Each keeps its own rule and links the upstream section with
an as-of date and a recheck trigger.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
bump: patch
---

### Changed

- `/repo-fleet-hygiene:audit` no longer restates git worktree list ordering, GitHub's GraphQL
limits, Git Bash's handling of Windows junctions, or what `core.bare` does and its remedy
command (`bare-repo-with-working-tree` stays manual review). It keeps its own
rules and links the upstream sections with an as-of date and a recheck trigger.
26 changes: 16 additions & 10 deletions plugins/code-tidying/skills/audit-dead-code/SKILL.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pr-verify verifier failed head 17e75a6abd1ea3f4339bafcadd0dd177ac43b058. What it wrote, as data:

Summary: Issue #12692: the diff covers all 28 rows across the 11 files in code-tidying, planning and
  repo-fleet-hygiene. Each touched plugin has a changelog fragment, and CI's covering jobs passed
  (https://github.com/melodic-software/claude-code-plugins/actions/runs/41584099998/job/125745659930).
  One required item is still missing. The issue names a trigger-less stamp at
  plugins/planning/skills/design/SKILL.md:393 and asks for its recheck trigger. The diff only
  reflows that text: the stamp line now ends at `as of 2026-10-11;` and `recheck when` starts the
  next line. Before the change, that line held `recheck` and was still flagged, so the check reads
  one line at a time. The stamp is therefore still trigger-less, and the done-when item that
  `check-stamps.sh --trigger-less` passes on the touched files is not met. Nothing shows CI ran that
  script, and the PR body says it was not run.
- No steering text aimed at the reviewer was found in the PR body, comments or diff.
- plugins/code-tidying/skills/audit-dead-code/SKILL.md:142-145: r048 asked for links to gopls as
  well as vulture and knip. gopls was dropped because its docs page has no exit-code section, as the
  fix round explains. The run-health rule still covers it. A human may want to confirm this
  departure from the row.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced by #12773, which fixes this. The stamp at plugins/planning/skills/design/SKILL.md:392-394 now opens its own line as as of 2026-10-11; recheck when that section changes the per-call question limit. check-stamps.sh --trigger-less on all 11 touched files: 0 findings, 49 candidates parsed. (It also passed before the join, because the trigger check reads the whole file: check-stamps.sh:451-464.) The gopls point is unchanged: the exit-code rule at audit-dead-code/SKILL.md:142-145 still covers gopls, and its command-line page documents no exit codes to link.

Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ Bounded by design. Evidence catalogue: [context/adjudication.md](context/adjudic
[context/adjudication.md, Bounding the pass](context/adjudication.md#bounding-the-pass); relay
as of 2026-10-11, recheck when that record's pointer moves out of that section).
6. **Optional LSP assist**, never required and never a lane: when Claude Code's `LSP` tool is
available, `findReferences` on one candidate is one more evidence source. `includeDeclaration`
is hard-coded true, so the dead threshold is `resultCount == 1`; imports count as references,
so a re-export still reads alive. Done when every emitted candidate has a `dead`, `uncertain`
or `alive` verdict with evidence, or the cap stopped the batch and the report says so.
available, `findReferences` on one candidate is one more evidence source. Read what it returns
in [LSP tool behavior](https://code.claude.com/docs/en/tools-reference#lsp-tool-behavior)
before reading a count as dead (as of 2026-11-03; recheck when that section changes what
`findReferences` returns). Done when every emitted candidate has a `dead`, `uncertain` or
`alive` verdict with evidence, or the cap stopped the batch and the report says so.

## Hard rules

Expand All @@ -138,8 +139,10 @@ Bounded by design. Evidence catalogue: [context/adjudication.md](context/adjudic
`Summary total:` mean two things.
- **T3 is the drift bucket.** An unrecognized detector line is recorded, never dropped and never
counted as a finding. A fourth verdict landing there is the alarm, not the answer.
- **Exit codes are never run health.** knip exits 1 for findings and for hard errors; vulture
exits 3 for findings and 1 for a lone unparsable input; gopls always exits 0.
- **Exit codes are never run health.** Run health comes from the detector's output, never its
exit code. The documented codes: [vulture](https://github.com/jendrikseipp/vulture#exit-codes),
[knip](https://knip.dev/reference/cli#--no-exit-code). As of 2026-11-03; recheck when one of
those sections changes its exit codes.
- **Presence is proven by invocation**, never by a locator hit (measured: `command -v
rust-analyzer` succeeds while invocation fails).
- **knip evaluates repo-controlled config through jiti.** Disclose it on every run that loads one.
Expand Down Expand Up @@ -205,10 +208,13 @@ formats"), and the next run reaches new code. Each step is done when the operato
verdicts and suppression text, has declined them, or the batch is explicitly deferred; the loop ends when a follow-up scan is
scheduled or the operator stops after one batch.

Only knip and vulture converge. **Go and the grep lane have no native suppression** (measured:
`gopls check -severity=hint` reports through every candidate directive; `//lint:ignore` is
staticcheck's), so those verdicts live in the report and in a comment at the declaration, and the
same candidates return. Say so rather than emitting a directive that does nothing.
Only knip and vulture converge. **Go and the grep lane get no suppression directive**: those
verdicts live in the report and in a comment at the declaration, and the same candidates return.
Say so rather than emitting a directive. The probe behind the Go half is in
[context/adjudication.md](context/adjudication.md#suppression-formats) "Suppression formats"; `//lint:ignore` belongs
to staticcheck, per
[Ignoring problems with linter directives](https://staticcheck.dev/docs/configuration/#ignoring-problems-with-linter-directives)
(as of 2026-11-03; recheck when that section names gopls among the tools that read it).

`dead` and `uncertain` verdicts are session-scoped: an un-suppressed `uncertain` returns next run.
A committed vulture whitelist raises `F821` under a consumer's ruff config; say so when you emit
Expand Down

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pr-verify verifier failed head 17e75a6abd1ea3f4339bafcadd0dd177ac43b058. What it wrote about this file, as data:

- plugins/code-tidying/skills/audit-dead-code/context/adjudication.md:31-33 and
  plugins/planning/skills/draft-goal-condition/SKILL.md:130-131: `as of` and its date are split
  across two lines. Check that check-stamps.sh still finds these as stamps, or keep `as of
  2026-11-03; recheck when` together on one line, as the other new stamps do.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in replacement #12773. as of and its date were on different lines at adjudication.md:32-33 and draft-goal-condition/SKILL.md:130-131, so the stamp checker never parsed either date. Both now read as of 2026-11-03; recheck when ... on one line. On the touched files, the check-stamps.sh --trigger-less candidate count went from 47 to 49, so both are now seen, with 0 findings.

Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Cheap checks first, in this order: a repo-wide literal search for the bare name
strings), then the config surfaces, then the framework-registration patterns for the candidate's
language. Stop at the first piece of real evidence.

The optional `LSP` assist is one more source, never a substitute: `findReferences` with
`includeDeclaration` hard-coded true means the dead threshold is `resultCount == 1`, and an import
counts as a reference, so a re-export still reads alive.
The optional `LSP` assist is one more source, never a substitute. What `findReferences` returns:
[LSP tool behavior](https://code.claude.com/docs/en/tools-reference#lsp-tool-behavior), as of
2026-11-03; recheck when that section changes what `findReferences` returns.

## Verdict rules

Expand Down Expand Up @@ -66,7 +66,7 @@ parser recognized, and it is a bug report about the detector, not a finding abou

The skill writes nothing. It emits ready-to-paste text and the human decides.

**knip**, in `knip.json` (or the `knip` key in `package.json`):
**knip**, an `ignore` entry for the project's knip config, emitted as JSON:

```json
{
Expand All @@ -75,16 +75,19 @@ The skill writes nothing. It emits ready-to-paste text and the human decides.
}
```

Note that a `knip.config.ts` is a **code module** knip evaluates through jiti; the JSON form does
not cross that boundary and is the safer paste when either will do.
Where knip reads its config and what `ignore` takes:
[ignore](https://knip.dev/reference/configuration#ignore), as of 2026-11-03; recheck when that
section changes what an `ignore` entry takes.

**vulture**, a whitelist file passed alongside the sources:
**vulture**, a whitelist entry carrying the adjudication as its comment:

```python
# whitelist.py: names vulture must treat as used.
format_legacy_row # adjudicated alive: dispatched by name from handlers.py
```

How vulture reads a whitelist: [Whitelists](https://github.com/jendrikseipp/vulture#whitelists),
as of 2026-11-03; recheck when that section changes how a whitelist is passed.

**A committed vulture whitelist raises `F821` (undefined name) under a consumer's ruff config.**
Say so whenever you emit one; the consumer either excludes the file in `ruff.toml` or keeps the
whitelist out of the linted tree.
Expand Down
10 changes: 4 additions & 6 deletions plugins/code-tidying/skills/batch-simplify/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@ invocation:
- Current branch, `git branch --show-current`

Treat a failure (not a repository, git unavailable) as an unknown value and carry on. Keep these as
separate body Bash calls rather than pre-compute lines: the harness runs a skill's whole pre-compute
block as one shell invocation, and a worktree-isolated session refuses a compound command that
contains git. The dated record for that composition claim is the
[gather-block convention](https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/gather-block/README.md#the-pre-compute-block-runs-as-one-shell-invocation),
"The pre-compute block runs as one shell invocation".
separate body Bash calls rather than pre-compute lines. How the harness runs a skill's injected
commands: [How injected commands run](https://code.claude.com/docs/en/skills#how-injected-commands-run),
as of 2026-11-03; recheck when that section changes how injected commands run.

## Variables

Expand All @@ -87,7 +85,7 @@ For any batch run (Phases 1-8), copy `templates/checklist.md` into your project'

Supported formats: `24h`, `48h`, `72h`, `7d`, `2d`, `1w`. Default: `48h`.

**Normalize before use:** git's `--since` approxidate parser requires `24 hours`, not `24h`. Convert before passing to `git log`:
**Normalize before use:** convert to long units before passing the window to `git log --since` (the option's entry is under [Commit Limiting](https://git-scm.com/docs/git-log#_commit_limiting), as of 2026-11-03; recheck when that entry documents the short `h`, `d` and `w` forms):

- `<N>h` → `<N> hours` (e.g., `48h` → `48 hours`)
- `<N>d` → `<N> days` (e.g., `7d` → `7 days`)
Expand Down
4 changes: 2 additions & 2 deletions plugins/code-tidying/skills/tidy/lanes/self-update.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Lane: self-update

The recursive lane: tidy operating on its own plugin files. **Maintainer-facing:** valid ONLY in a working-tree checkout of this plugin (the marketplace clone, or a directory loaded via `--plugin-dir`), never against an installed marketplace copy. Consumers receive updates through `/plugin marketplace update`. **This lane is permanently manual-merge.** The risk profile is unique: a bad change here can disable the safety mechanisms that protect every other lane.
The recursive lane: tidy operating on its own plugin files. **Maintainer-facing:** valid ONLY in a working-tree checkout of this plugin (the marketplace clone, or a directory loaded via `--plugin-dir`), never against an installed marketplace copy. **This lane is permanently manual-merge.** The risk profile is unique: a bad change here can disable the safety mechanisms that protect every other lane.

## Scope

Expand Down Expand Up @@ -48,7 +48,7 @@ npx markdownlint-cli2 <changed .md files>
bash skills/tidy/scripts/open-pr-count.test.sh # if the script changed (it shouldn't in this lane)
```

Markdown lint does not cover the frontmatter parse contract. A broken `---` fence in a SKILL.md would block the next session's skill discovery. Run from the plugin root:
Markdown lint does not cover the frontmatter parse contract, so run this fence check from the plugin root. How Claude Code reads a SKILL.md's frontmatter block: [Frontmatter reference](https://code.claude.com/docs/en/skills#frontmatter-reference), as of 2026-11-03; recheck when that section changes how a malformed frontmatter block loads.

```bash
# Stdlib-only (no PyYAML): confirms each SKILL.md's `---` fences are present and the frontmatter between them is non-empty.
Expand Down
4 changes: 2 additions & 2 deletions plugins/code-tidying/skills/tidy/reference/exclusions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The GLOBAL HARD list gates every lane. A tidying that would touch any entry is a

### Agent & enforcement configuration (universal)

Claude Code surface: `.claude/**` in full. The whole directory is agent surface: settings, agents, hooks, rules, routines, tidy-lanes (the consumer's own lane definitions, since the lane contract cannot tidy itself), and any settings-wired hook or bootstrap script that lives there. Any script wired as a hook command **anywhere** is excluded wherever it lives, because a hook command may point outside `.claude/`. Hook wiring is not only the project settings scope (`.claude/settings.json`, `.claude/settings.local.json`): a plugin's `hooks/hooks.json` and a skill's or agent's frontmatter `hooks` block wire hook commands too, and a script reached through either is excluded on the same footing. `.mcp.json`. Other agents' config bundles (e.g. `.codex/**`, `.cursor/**`), since a tidy must not mutate another agent's behavior. GitHub surface: `.github/workflows/**`, `.github/actions/**`, `.github/CODEOWNERS`, `.github/dependabot.yml`. Local git-hook chain: the hook manager's config and script directories (e.g. `lefthook.yml`, `.lefthook/**`, `.husky/**`, `.pre-commit-config.yaml`). Cross-ecosystem lint / style config: `.editorconfig`, `.shellcheckrc`, and their per-tool equivalents.
Claude Code surface: `.claude/**` in full. The whole directory is agent surface: settings, agents, hooks, rules, routines, tidy-lanes (the consumer's own lane definitions, since the lane contract cannot tidy itself), and any settings-wired hook or bootstrap script that lives there. Any script wired as a hook command **anywhere** is excluded wherever it lives, because a hook command may point outside `.claude/`. Every place a hook can be wired counts, not only the project settings files: see [Hook locations](https://code.claude.com/docs/en/hooks#hook-locations), as of 2026-11-03; recheck when that section adds or removes a location. `.mcp.json`. Other agents' config bundles (e.g. `.codex/**`, `.cursor/**`), since a tidy must not mutate another agent's behavior. GitHub surface: `.github/workflows/**`, `.github/actions/**`, `.github/CODEOWNERS`, `.github/dependabot.yml`. Local git-hook chain: the hook manager's config and script directories (e.g. `lefthook.yml`, `.lefthook/**`, `.husky/**`, `.pre-commit-config.yaml`). Cross-ecosystem lint / style config: `.editorconfig`, `.shellcheckrc`, and their per-tool equivalents.

### Consumer-declared protections

Expand Down Expand Up @@ -122,7 +122,7 @@ To operate on a directory genuinely named `override`, spell it `./override`.

### The `hard_exclusions` userConfig option

`enforce` (default) keeps the section 1 path list blocking. `advisory` reports each HARD path match and never blocks, so the operator's standing posture is "tell me, then proceed". It is a scalar, not a list: `userConfig` types are `string`, `number`, `boolean`, `directory`, and `file`, so a per-path list cannot live there and belongs in the repository file below. Any value outside the two is read as `enforce`.
`enforce` (default) keeps the section 1 path list blocking. `advisory` reports each HARD path match and never blocks, so the operator's standing posture is "tell me, then proceed". It is a scalar, not a list: a per-path list belongs in the repository file below. Option types: [User configuration](https://code.claude.com/docs/en/plugins/manifest-reference#user-configuration), as of 2026-11-03; recheck when that section changes the option types. Any value outside the two is read as `enforce`.

### The consumer-declared overrides file

Expand Down
13 changes: 6 additions & 7 deletions plugins/planning/skills/design/SKILL.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pr-verify verifier failed head 17e75a6abd1ea3f4339bafcadd0dd177ac43b058. What it wrote about this file, as data:

- plugins/planning/skills/design/SKILL.md:392-393: the stamp `as of 2026-10-11;` still has no
  recheck trigger on its own line, because the reflow moved `recheck when ...` to the next line. Put
  `as of 2026-10-11; recheck when that section changes the per-call question limit` on one line
  (re-wrap the text around it as needed), then run
  `plugins/attribution/skills/audit/scripts/check-stamps.sh --trigger-less` on every touched file
  and report the result.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in replacement #12773. plugins/planning/skills/design/SKILL.md:393 now reads as of 2026-10-11; recheck when that section changes the per-call question limit on one line. check-stamps.sh --trigger-less on every touched file: 0 findings, 49 candidates parsed, 0 declined.

Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ Collect these with **individual** Bash calls, one command per call, never combin
- Current branch, `git branch --show-current`

Treat a failure (not a repository, git unavailable) as an unknown value and carry on. Keep these as
body Bash calls, not pre-compute lines: a worktree-isolated session refuses a compound command that
contains git, and the pre-compute block runs as one. Record: the
[gather-block convention](https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/gather-block/README.md#the-pre-compute-block-runs-as-one-shell-invocation),
"The pre-compute block runs as one shell invocation".
body Bash calls, not pre-compute lines. How the harness runs a skill's injected commands:
[How injected commands run](https://code.claude.com/docs/en/skills#how-injected-commands-run), as
of 2026-11-03; recheck when that section changes how injected commands run.

## Variables

Expand Down Expand Up @@ -338,7 +337,7 @@ file. After the gate passes, the handoff output names those files and signatures
| `module` | domain-model.md, module-boundary.md, contracts.md, design-threads.md | none | none (no typed artifact, so no scope label) |
| `data` | entity-relationships.md, schema-decisions.md, design-threads.md | `entity-relationships.md` | mermaid `erDiagram` by default; DBML when `diagram_dialect.data` resolves to `dbml` |
| `integration` | contract-spec.md, sequence-flows.md, design-threads.md | `sequence-flows.md`, `contract-spec.md` | mermaid `sequenceDiagram` for the flows; an OpenAPI 3.1 sketch for the contract spec |
| `system` | component-map.md, communication-patterns.md, design-threads.md | `component-map.md`, and only when `diagram_dialect.system` names a dialect | a C4 container view in LikeC4 or C4-PlantUML. Never Mermaid's experimental C4 support |
| `system` | component-map.md, communication-patterns.md, design-threads.md | `component-map.md`, and only when `diagram_dialect.system` names a dialect | a C4 container view in LikeC4 or C4-PlantUML, never Mermaid's [C4 diagrams](https://mermaid.js.org/syntax/c4.html#c4-diagrams) (as of 2026-11-03; recheck when that page changes which C4 features it supports) |

`design-threads.md` is common across all scopes.

Expand Down Expand Up @@ -390,8 +389,8 @@ it, emit the plainest correct form of the dialect. The typed artifact is produce
for the round after it resolves. Render a round via `AskUserQuestion` only when the plugin's
`use_ask_user_question` user config (`${user_config.use_ask_user_question}`; unexpanded or empty means off) is on and the round
is independent questions that fit one `AskUserQuestion` call (the per-call question limit:
<https://code.claude.com/docs/en/agent-sdk/user-input#limitations>, as of 2026-10-11; recheck
when that section changes the per-call question limit). Inline prose otherwise
<https://code.claude.com/docs/en/agent-sdk/user-input#limitations>, as of 2026-10-11;
recheck when that section changes the per-call question limit). Inline prose otherwise
- **Grounding steps.** Ground a consequential recommendation in the affected code plus its
consumers and in external research that reads official docs first, routed to
`/discovery:explore` and `/discovery:research` if enabled. A recommendation that changes is
Expand Down
Loading
Loading