Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a57962d
docs(topics): lock the docs-naming-consistency brief and draft plan
claude Sep 11, 2026
c61ed52
Merge remote-tracking branch 'origin/main' into claude/docs-naming-co…
claude Sep 11, 2026
81492dd
docs(topics): revise the docs-naming plan after stress-test review
claude Sep 11, 2026
16b720a
docs(topics): keep the em-dash check as a byte escape
claude Sep 11, 2026
bdb8eb1
docs: rename the 13 docs/ root files to lower-kebab-case
claude Sep 11, 2026
1412626
docs: repoint every docs/ citation to the lower-kebab names and bump …
claude Sep 11, 2026
f9fce8c
case
Sep 11, 2026
6de5b0f
feat(scripts): gate docs/ filenames as lower-kebab-case
claude Sep 11, 2026
ecc3388
docs(adr): record the lower-kebab-case rule for docs/ and its exemptions
claude Sep 11, 2026
b5481c3
Merge remote-tracking branch 'origin/main' into claude/docs-naming-co…
claude Sep 11, 2026
8a259be
refactor(scripts): name a made-up file in the docs-naming checker's f…
claude Sep 11, 2026
ccb2390
fix(scripts): hold check-docs-naming to the check-script contract
claude Sep 11, 2026
ad5c116
docs(topics): close Phase 5 of the docs-naming plan
claude Sep 11, 2026
ae07c1c
docs(topics): prune the docs-naming-consistency contract slice
claude Sep 11, 2026
82899c3
Merge remote-tracking branch 'origin/main' into claude/docs-naming-co…
claude Sep 11, 2026
71754f5
Merge remote-tracking branch 'origin/main' into claude/docs-naming-co…
claude Sep 11, 2026
8906fde
fix(scripts): reject empty dot segments and fold case without Bash 4 …
claude Sep 11, 2026
21c3566
fix(scripts): never let a failed fixture build run git against the ch…
claude Sep 11, 2026
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
4 changes: 2 additions & 2 deletions .claude/cloud-bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fi
# exists for: a session exercises the plugin code on the current branch, not
# published main.
#
# Timing limit (docs/CLOUD-SESSIONS.md, "Plugins in sessions on this repo"):
# Timing limit (docs/cloud-sessions.md, "Plugins in sessions on this repo"):
# the plugin/command registry is read at process start, BEFORE a SessionStart
# hook runs, and is not re-read, so a hook run's installs are invisible to the
# session performing them. They serve the next process start — which on an
Expand Down Expand Up @@ -261,7 +261,7 @@ if [[ -x "$claude_bin" ]] && command -v jq >/dev/null 2>&1; then
# A directory-source install cache is keyed by the semver in plugin.json, not
# by commit, so a later commit under the same version never replaces the
# snapshot and `plugin update` false-greens on the version compare — see
# "Same-version commit drift" in docs/MIGRATION-PLAYBOOK.md and #2061. On a
# "Same-version commit drift" in docs/migration-playbook.md and #2061. On a
# resume after the checkout advanced, a presence check alone would therefore
# keep serving the skills and hooks of whatever commit installed first, which
# defeats the reason this repo uses a directory source at all. Compare the SHA
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/catalog-taxonomy.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ paths:
# Catalog category taxonomy

The category vocabulary for `.claude-plugin/marketplace.json` is maintained in
[`docs/CATALOG-TAXONOMY.md`](../../docs/CATALOG-TAXONOMY.md). Read its Form rule, Assignment
[`docs/catalog-taxonomy.md`](../../docs/catalog-taxonomy.md). Read its Form rule, Assignment
principle, and Singleton governance sections before assigning, renaming, or merging any plugin
category; do not invent a category value from the existing entries alone.
38 changes: 38 additions & 0 deletions .claude/rules/docs-naming.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
description: "Every file under docs/ is named in lower-kebab-case, with README.md, CHANGELOG.md, INDEX.md, docs/topics/, and code files exempt; scripts/check-docs-naming.sh --check is the gate; read before adding or renaming a docs/ file"
paths:
- "docs/**"
---

# docs/ file naming

Name every file under `docs/` in lower-kebab-case: lowercase letters, digits, and single hyphens,
with a lowercase extension (`plugin-philosophy.md`, `0001-first.md`, `v1.2.schema.json`). Never an
uppercase letter, an underscore, or a space in the basename.

Exempt, and only these:

- `README.md`, `CHANGELOG.md`, and `INDEX.md` anywhere under `docs/`, the conventional uppercase
names tooling and forges look for by exact spelling (`INDEX.md` is the topic-docs convention's
reserved index name).
- Everything under `docs/topics/`, the branch-only contract slice whose file names (`PLAN.md`,
`BRIEF.md`) belong to the topic-docs convention and are pruned before merge.
- Code files by extension (`.py`, `.sh`, `.mjs`, `.js`, `.ps1`), whose casing is the language's
convention.

No two tracked paths under `docs/` may differ only by case. A case-insensitive checkout (Windows,
macOS) writes the second over the first, so a lowercase file can never sit beside its uppercase
twin, and a rename is a hard cutover: move the file with `git mv`, repoint every citation in the
same pull request, and bump every plugin whose body cites it.

The gate is `scripts/check-docs-naming.sh --check`, which the `lint` job runs on every pull
request. This rule loads when a covered file is read, never when one is created, so run the gate
before pushing a new `docs/` file; the rule alone cannot catch it.

Why: `docs/` carried a mix of UPPER-KEBAB, lower-kebab, and mixed-case names, and every citation
had to remember which spelling one file used. One rule means a new name needs no lookup and a
rename never happens twice. The decision, its exemptions, and the hard-cutover consequence are
recorded in the ADR named below.

Decision record:
[ADR 0033](../../docs/adr/0033-name-docs-files-lower-kebab-case-with-conventional-exceptions.md).
2 changes: 1 addition & 1 deletion .claude/rules/ruff-pin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ Lint Python in this repo through `scripts/run-ruff.sh check <paths>` (the wrappe
ruff arguments through and resolves the CI-pinned ruff version); a bare `ruff` on PATH can
disagree with CI in both directions, so never use it for verification here. Do not adopt a newer ruff's new rules in an
unrelated change; bumping the pin is a deliberate Dependabot change. Full rationale:
[`docs/CI-RUNNER-ROUTING.md`, "Local / workstation ruff"](../../docs/CI-RUNNER-ROUTING.md#local--workstation-ruff).
[`docs/ci-runner-routing.md`, "Local / workstation ruff"](../../docs/ci-runner-routing.md#local--workstation-ruff).
4 changes: 2 additions & 2 deletions .github/recurring-schedule.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"last_checked": "2026-08-08",
"next_due": "2026-11-06",
"notes": "On each frontier model release (primary trigger), run /claude-config:audit-instructions and /claude-config:unhobble over this repository's session surfaces to re-test which standing instructions the new model still needs. No automation observes the release event: the trigger's consumer is the standing OPEN [Maintenance] issue (#2019) — kept open continuously so /work-items:work can select it the moment an operator or agent notices a release, ahead of next_due. The quarterly cadence is a backstop only, guaranteeing the pass happens even when a release goes unnoticed (docs/PLUGIN-PHILOSOPHY.md, Instruction economy). Tier-4 caveat (known limitation, unenforced): last-resort selection can pick the open issue when no release has occurred, and neither the work skill's tier-4 step nor recheck's close step consults any precondition — the issue body instructs the claimant (no frontier release since last_checked: unclaim, leave open, never recheck-close), but honoring that depends on the claimant reading the body and deviating from the unconditional close step. If a premature close drains the item before a real release, re-open or re-create it from this row. Session surfaces only, never the shipped plugin components.",
"notes": "On each frontier model release (primary trigger), run /claude-config:audit-instructions and /claude-config:unhobble over this repository's session surfaces to re-test which standing instructions the new model still needs. No automation observes the release event: the trigger's consumer is the standing OPEN [Maintenance] issue (#2019) — kept open continuously so /work-items:work can select it the moment an operator or agent notices a release, ahead of next_due. The quarterly cadence is a backstop only, guaranteeing the pass happens even when a release goes unnoticed (docs/plugin-philosophy.md, Instruction economy). Tier-4 caveat (known limitation, unenforced): last-resort selection can pick the open issue when no release has occurred, and neither the work skill's tier-4 step nor recheck's close step consults any precondition — the issue body instructs the claimant (no frontier release since last_checked: unclaim, leave open, never recheck-close), but honoring that depends on the claimant reading the body and deviating from the unconditional close step. If a premature close drains the item before a real release, re-open or re-create it from this row. Session surfaces only, never the shipped plugin components.",
"close_previous": true
},
{
Expand All @@ -38,7 +38,7 @@
"triggers": [],
"last_checked": "2026-08-08",
"next_due": "2026-11-06",
"notes": "Report-only self-maintenance routine (digest menu #9 pilot). Sweep docs/ and top-level repo docs for references to files/checks/skills that no longer exist, stale version claims, and moved OFFICIAL-DOCS.md pages (review:doc-drift-detector or docs-hygiene audits); verify generated CATALOG/SKILL-CHEAT-SHEET freshness on a scratch branch. File one issue per confirmed drift cluster or comment no-drift on the open [Maintenance] issue (#2024 is the first instance). Never edits docs directly from the routine.",
"notes": "Report-only self-maintenance routine (digest menu #9 pilot). Sweep docs/ and top-level repo docs for references to files/checks/skills that no longer exist, stale version claims, and moved official-docs.md pages (review:doc-drift-detector or docs-hygiene audits); verify generated CATALOG/skill-cheat-sheet freshness on a scratch branch. File one issue per confirmed drift cluster or comment no-drift on the open [Maintenance] issue (#2024 is the first instance). Never edits docs directly from the routine.",
"close_previous": true
}
]
Expand Down
14 changes: 12 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,15 @@ jobs:
continue-on-error: true
run: scripts/check-skill-leaf-names.sh --check

# Self-test first, so a broken checker cannot mask a regression.
- name: Run docs-naming tests
if: needs.changes.outputs.run_shell == 'true'
run: bash scripts/check-docs-naming.test.sh
- name: Check docs/ filenames are lower-kebab
id: docs_naming
continue-on-error: true
run: scripts/check-docs-naming.sh --check

# A plugin's prose counts its own skills by hand ("bundling fourteen
# skills", "the other thirteen skills are zero-config") and nothing
# recomputes those numbers when a skill lands, so adding one silently
Expand Down Expand Up @@ -758,7 +767,7 @@ jobs:
continue-on-error: true
run: scripts/check-plugin-manifest-presence.sh

# docs/CLOUD-SESSIONS.md promises `enabledPlugins` "turns on the whole
# docs/cloud-sessions.md promises `enabledPlugins` "turns on the whole
# catalog, so this repo dogfoods everything it publishes"; nothing
# enforced it, and ai-slop (#2892), context-budget (#2932) and
# improvement (#2985) each reached main catalogued but never enabled. The
Expand Down Expand Up @@ -1135,7 +1144,7 @@ jobs:
# a month after the 750k consumers had already overflowed, and a tripwire
# that fires after the failure it exists to predict is worse than none.
# (Neither basis speaks for a 200k-window consumer, who is over the
# 40,000-char budget today; docs/CLOUD-SESSIONS.md records that.)
# 40,000-char budget today; docs/cloud-sessions.md records that.)
# Report-only for the same reason its sibling is. The fix for the
# aggregate is the per-skill description trim, which #3526 owns.
- name: Report the skill-listing budget at this repo's configured fraction
Expand Down Expand Up @@ -1268,6 +1277,7 @@ jobs:
loop-lane-floor-drift=${{ steps.loop_lane_floor_drift.outcome }}
detector-findings-crosswalk=${{ steps.detector_findings_crosswalk.outcome }}
skill-leaf-names=${{ steps.skill_leaf_names.outcome }}
docs-naming=${{ steps.docs_naming.outcome }}
skill-count-claims=${{ steps.skill_count_claims.outcome }}
userconfig-argv=${{ steps.userconfig_argv.outcome }}
hook-exec-form=${{ steps.hook_exec_form.outcome }}
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ context, read the file directly.
| Surface | Covers | Topic |
|---|---|---|
| `.claude/rules/catalog-taxonomy.md` | `.claude-plugin/marketplace.json` | Where the marketplace category taxonomy lives; read before adding or changing a plugin's category |
| `.claude/rules/docs-naming.md` | `docs/**` | Every file under docs/ is lower-kebab-case with a short exemption list, gated by `scripts/check-docs-naming.sh --check`; read before adding or renaming a docs/ file |
| `.claude/rules/hook-budget.md` | `plugins/*/hooks/**` | Marketplace-wide latency budget for always-on hooks; read before adding or widening a hook |
| `.claude/rules/ruff-pin.md` | `**/*.py` | Python linting runs through the pinned ruff wrapper, never a bare ruff on PATH |
| `.claude/rules/skill-bodies-state-current-rules.md` | `plugins/*/skills/**, plugins/*/agents/**` | Skill and agent bodies state the current rule and its reason, never the incident, PR, or model that motivated it, and name their successor in a `## Next` section; read before editing any skill body |
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Browse and manage with `/plugin`. To refresh after updates: `/plugin marketplace
When you consume this repo from a local `directory` source, the install cache keys on semver
`version`, not commit, so several commits under one version leave early installs on a stale
snapshot and `plugin update` can report "already at the latest version" while SHA lags. See
[`docs/MIGRATION-PLAYBOOK.md`](docs/MIGRATION-PLAYBOOK.md) ("Same-version commit drift") and
[`docs/migration-playbook.md`](docs/migration-playbook.md) ("Same-version commit drift") and
[#2061](https://github.com/melodic-software/claude-code-plugins/issues/2061).

### Enable plugin suggestions for an organization
Expand Down Expand Up @@ -51,12 +51,12 @@ user opts in with `/plugin enable`; an existing install is never flipped by cata

## Finding your way

- Not sure which skill to invoke? Start at the [skill cheat sheet](docs/SKILL-CHEAT-SHEET.md). A
- Not sure which skill to invoke? Start at the [skill cheat sheet](docs/skill-cheat-sheet.md). A
scan-and-go map from what you are doing to the skill that does it.
- [Plugin catalog](docs/CATALOG.md). Every plugin by category, generated from the manifests and
- [Plugin catalog](docs/catalog.md). Every plugin by category, generated from the manifests and
kept in sync by CI. New plugins clear the per-plugin migration gate in
[`docs/MIGRATION-PLAYBOOK.md`](docs/MIGRATION-PLAYBOOK.md).
- [Catalog taxonomy](docs/CATALOG-TAXONOMY.md). The category vocabulary the catalog is grouped by.
[`docs/migration-playbook.md`](docs/migration-playbook.md).
- [Catalog taxonomy](docs/catalog-taxonomy.md). The category vocabulary the catalog is grouped by.

## What's here

Expand All @@ -73,13 +73,13 @@ user opts in with `/plugin enable`; an existing install is never flipped by cata
source-control convention). It governs work done here and ships to no one.
- `.github/`, workflows plus the policy files they read (runner policy, security paths, recurring
schedule, PR template).
- `docs/MIGRATION-PLAYBOOK.md`, design charter, extensibility model, the per-plugin migration
- `docs/migration-playbook.md`, design charter, extensibility model, the per-plugin migration
gate, and the local development loop.
- `docs/`, further design records and audits (CI runner routing, extensibility-contract smoke
tests, migration audits).
- `CLAUDE.md`, operating rules for AI agents working in this repo (fresh-docs mandate + plugin
design rules).
- `docs/OFFICIAL-DOCS.md`, canonical index of the official Claude Code doc pages the mandate
- `docs/official-docs.md`, canonical index of the official Claude Code doc pages the mandate
sends you to.

## Validate a change
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ sufficient one. Specifically:
duplicating `check-changelog-parity --check-bump` would fire correctly; it would simply
add no signal the required gate does not already produce, while adding a second place the
rule can drift. That is the **one mechanism per concern** principle
(`PLUGIN-PHILOSOPHY.md`'s validation section, owned upstream in `standards`) — redundancy,
(`plugin-philosophy.md`'s validation section, owned upstream in `standards`) — redundancy,
not a silent skip. The deletion criterion for a future guard author is "supplies no
additional signal," which is a coverage test, not a correctness one.

Expand All @@ -144,6 +144,6 @@ sufficient one. Specifically:
- #1270 (scoping, amended twice), #1284 (the two-guard PR, closed), #1319 (the shipped
guard), #1314 (the withdrawn guard's measurement and rescope)
- `docs/conventions/hook-precision/README.md` — over-fire discipline
- `docs/PLUGIN-PHILOSOPHY.md` — one mechanism per concern (validation section)
- `docs/plugin-philosophy.md` — one mechanism per concern (validation section)
- `melodic-software/standards`, `conventions/engineering/enforceability-tiers.md` —
classify the tier first, justify automation second
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ re-decide.
| # | Decision | Consequence |
|---|---|---|
| D-7 | **Fold the listing-budget material into issue #1271**, and adopt its `when_to_use` lever | #1271 already measured the defect and found the field this effort's agents missed. No second ticket |
| D-8 | **Sequence behind PR #1096** for anything touching `check-skill.sh` or `docs/PLUGIN-PHILOSOPHY.md` | Check 21 is taken. New criteria pick a free number against the post-merge file |
| D-8 | **Sequence behind PR #1096** for anything touching `check-skill.sh` or `docs/plugin-philosophy.md` | Check 21 is taken. New criteria pick a free number against the post-merge file |
| D-9 | **Sequence the user-scope work behind dotfiles PRs #318 and #312**, and read #312's Opus 5 re-derivation as an input before measuring | Measuring `dot_claude/CLAUDE.md` while two PRs edit it produces a diff that reverts newer rules |
| D-10 | **Drop the stale dotfiles branch** `docs/claude-md-github-conventions` (+13 lines to `CLAUDE.md`, last commit 2026-07-15, no PR) | One fewer writer on the contested file |
| D-11 | **Reconcile with issue #1225 before building anything sweep-shaped** | Two repo-wide sweeps become two routers |
Expand All @@ -81,7 +81,7 @@ These are the questions the section agents explicitly declined to answer, plus t
| D-15 | **Arbitration stays the repo's default posture.** Deletion is adopted only where a constraint has no current safety rationale | Overrides the article's blanket delete-constraints posture. A lane proposing a deletion must state the constraint's rationale and why it no longer holds |
| D-16 | **The fresh-docs mandate narrows in scope, not in substance** — it binds changes touching a plugin manifest, marketplace schema, hook contract, or documented harness behavior | Prose and mechanical edits are out. The mandate stays non-negotiable within its scope |
| D-17 | **Auto-memory: move `autoMemoryEnabled` from `claudeSettings.force` to `claudeSettings.seed`, seeded `false`** | Two decisions, both taken. The tier move ends the silent-revert trap; `seed` writes only when absent, so this machine keeps its current value and every fresh machine starts off. Overrides the S7 agent's `true` recommendation on tracked-drift grounds — the capability unlock is available per machine by toggle |
| D-18 | **Cut `CLAUDE.md:13-30`** (the doc-URL table) to a pointer at `docs/OFFICIAL-DOCS.md` | Verified strict subset; 29.6% of the file; line 30 already points at the superset. Accepted risk: the mandate's force must come from the rule, not from the URLs being pre-loaded |
| D-18 | **Cut `CLAUDE.md:13-30`** (the doc-URL table) to a pointer at `docs/official-docs.md` | Verified strict subset; 29.6% of the file; line 30 already points at the superset. Accepted risk: the mandate's force must come from the rule, not from the URLs being pre-loaded |
| D-19 | **Vendored `skill-authoring` guidance governs authoring mechanics; this effort's carve-out governs what stays constrained** | Different axes. Where they genuinely collide, upstream wins and the divergence is recorded — a vendored file is never hand-edited |

### Standing constraints these decisions inherit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ re-run the sweep rather than treating the row set as complete.
| **#1268** false `context: fork` rationale | No / No — **title-filter false positive** | Matched only on the literal `audit` inside another topic's slice path (`docs/topics/plugin-audit-port/`, PR #1241). It corrects one rationale inside that topic's design record, explicitly says "Do not change the decision", and has since closed. Recorded so a reader can see it was assessed rather than silently dropped |

Per D-8, anything touching `plugins/skill-quality/scripts/check-skill.sh` or
`docs/PLUGIN-PHILOSOPHY.md` sequences behind PR #1096, which claims **check 21**. The next free check
`docs/plugin-philosophy.md` sequences behind PR #1096, which claims **check 21**. The next free check
number is **22**. Neither L2 nor L3 needs a `check-skill.sh` slot — L2 lands in `claude-config`, L3 is
a catalog edit — so #1096 is a constraint to respect, not a blocker either lane waits on.

Expand Down
Loading
Loading