Repository navigation
Description
Problem
Many skills keep their customization in a one-off file under .claude/. This repository alone has seven: ai-slop.json, attribution.json, bugs.md, code-metrics.yaml, docs-naming.json, source-control.md and audit-pass.md. About 38 skill bodies name such a file. Each consumer has to discover them one skill at a time, and agents without the skill installed cannot read the intent.
The maintainer's target: "Customizations should be userConfig when they are per-project or per-repo settings, otherwise concise markdown lines in one well-known docs/conventions file that CLAUDE.md or AGENTS.md points to ('if you use these skills, look here')." It keeps them out of every context, easy to find, and readable by agents that don't have the skills.
What already decides part of this
docs/adr/0018-express-team-shared-conventions-as-consumer-convention-docs.md (decision 1, L30-35): team-shared prose configuration with no per-operator axis becomes a convention doc bound by one pointer line in the root instruction file, while "Per-operator-keyed surfaces, structured data, policy-floor surfaces, and all state stay dedicated files under the config-cascade layers." Two ADRs are numbered 0018, so cite the full filename. The nearby conventions are docs/conventions/config-cascade, consumer-config-layering and plugin-reconfiguration.
Interim rule (decided in the poteto-talk interview, Q53)
New settings added before this migration go in one of three homes:
- per-consumer scalar keys in the owning plugin's
userConfig - team prose conventions in the one conventions doc
- structured or per-operator data in the cascade file (ADR 0018)
Scope
- Inventory every per-skill
.claude/<topic>.*file and every skill body that names one. - Classify each setting: userConfig scalar, convention prose, or cascade data (structured, per-operator, policy floor or state), against ADR 0018.
- Migrate each file to its home, with a compatibility read of the old file for one release, and update the skill bodies and setup skills.
- Update the three conventions docs and ADR 0018 if the classification changes anything.
Acceptance criteria
- No skill reads a one-off
.claude/<topic>.*file except cascade-data files ADR 0018 keeps. - The root instruction file holds one pointer line to the conventions doc.
- Each migrated setting is listed with its new home in the PR.
Metadata
Metadata
Assignees
Labels
Type
Fields
Work status
Activity
kyle-sexton commentedon Oct 4, 2026
This was generated by AI during triage.
Triage
Routing: human-gated,
status: needs-decision, priority medium, work class structural. This is a cross-plugin configuration migration with a compatibility window, which is C4 by class: it needs plan approval before execution and human review and merge.Decision needed: approve the per-file classification (userConfig scalar, convention prose, or cascade data) before any migration starts. ADR 0018 and the interim rule settle the categories, but not which file or setting lands where; that table is the plan to approve.
Inventory notes for whoever plans it:
.claude/holds the seven files the issue names pluscloud-bootstrap.shandcutover-pathdet-ack.txt; the plan should say whether either is a skill configuration file..claude/<topic>.(json|md|yaml)across plugin SKILL.md files matches 60 files, though that pattern also catchessettings.jsonand similar, so it overcounts.Basis: verified,
git ls-tree --name-only origin/main .claude/,git grep -lE '\.claude/[a-z-]+\.(json|md|ya?ml)' origin/main -- 'plugins/*/skills/*/SKILL.md' | wc -l(60),git ls-tree origin/main docs/adr/ | grep 0018ate3bef1210.Agent Brief
Type: Task
Summary: Move each per-skill one-off
.claude/<topic>.*setting to its ADR 0018 home: owning pluginuserConfig, one conventions doc, or the config cascade.Current behavior:
Many skills read customization from their own file under the consumer's
.claude/. Consumers discover them one skill at a time, and agents without the skill installed cannot read the intent.Desired behavior:
Per-consumer scalar keys live in the owning plugin's
userConfig; team prose conventions live in one conventions doc that the root instruction file points to with one line; structured, per-operator, policy-floor or state data stays in the cascade per ADR 0018. Each migrated skill reads its new home and, for one release, still reads the old file.Key interfaces:
userConfigschema and its setup skill.Acceptance criteria:
.claude/<topic>.*file except cascade-data files ADR 0018 keeps.Out of scope:
.claude/settings.json, hooks and rules.kyle-sexton commentedon Oct 4, 2026
The target home has changed. Standards
components/github-actions-conventions/README.md:131-136(merged2026-10-04) puts structured configuration in
docs/conventions/<concern>.yaml, validated by a JSON Schema,with its prose in
docs/conventions/<concern>.md, and it supersedes ADR 0044 for structuredconfiguration. The 2,000-PRs effort records this in a new ADR, "home plugin customization in
docs/conventions/.yaml", numbered at write time. Per-user values stay in plugin
userConfig.pluginConfigsis read only from user and managed settings, so it never carries a per-repository value.This issue now owns migrating these surfaces to that form:
.claude/source-control.md, which is read by about 41 files, including guardrails' commit-msg hook. Itmoves to
docs/conventions/source-control.yaml, which by then will already exist holding onlypr_open_state. Keep the old file with identical keys until a release carrying the new reader hasshipped and the git hooks have been reinstalled.
.claude/*files:ai-slop.json,attribution.json,bugs.md,docs-naming.jsonandaudit-pass.md. The effort movescode-metrics.yamlitself.docs/conventions/review-digest.md.The effort migrates testing's block itself.
docs/conventions/source-control/commit-convention.yml.Script readers use the shared reader
lib/parse-concern-value.sh. After the effort's change it readsdotted keys, lists, stdin and a validated
--ref.Done when (replaces the body's acceptance criteria for structured settings): no skill reads a team
setting from a
.claude/<topic>.*file or a fenced config block, and the PR lists each migrated settingwith its new
docs/conventions/<concern>.yamlhome and schema.fix(code-metrics): say the legacy team file is ignored
.claude/ai-slop.jsonsettings to docs/conventions/ai-slop.yaml #972851 remaining items
kyle-sexton commentedon Nov 5, 2026
Decision recorded. All 17 sub-issues are closed (the last, #9737, on 2026-11-05), but acceptance criterion 1 is not met yet: one plugin still reads a repo-relative
.claude/<topic>.*team file.Agent choice, not an owner answer.
Checked on
origin/mainon 2026-11-05:plugins/review/skills/explain-change/scripts/digest-policy.mjs:249-252lists.claude/review-digest.jsonamong the team layers ([TEAM_YAML, "docs/conventions/review-digest.md", ".claude/review-digest.json"]), and:41-42keeps both.claude/review-digest*.jsonfiles inCONFIG_PATHS. The review plugin's YAML reader shipped with the note "read only when the YAML file is absent from the base commit, for one release" (plugins/review/CHANGELOG.md:694), and releases through 7.4.0 have shipped since..claude/<topic>.*hit in plugin code is either a personal.localoverride or the mutation-testing finding-suppression record.claude/mutation-testing-arid.md. ADR 0075's personal layer covers the first; the second is cascade data ADR 0018 keeps. The rest name a retired or migrated file in prose.Left:
git grep -n "review-digest.json" -- plugins/review/skills/explain-change/scripts/digest-policy.mjsprints nothing (it prints 4 lines today), and thedocs/conventions/review-digest.mdfenced-block fallback is dropped with it, so the team layer isdocs/conventions/review-digest.yamlonly. The user-global layer is unchanged.node --test plugins/review/tests/explain-change.test.mjspasses in the PR's CI, with the old-file cases changed to assert that the old file is not read.scripts/check-changelog-fragments.sh --check-required origin/mainexits 0 (a review fragment).When these land, criterion 1 holds and this issue closes as completed.
github-actions commentedon Nov 5, 2026
github-actions commentedon Nov 5, 2026
melodic-automation-lanes commentedon Nov 5, 2026
The work-resolve-issue lane stopped on this issue (
verify-unmet): the issue is a finished parent, but the run found one of its own done-when items unmet, which it names, so it parks until a listed human's decision comment sends it back.It removed
agent-readyandstatus: readyand addedstatus: confirmed, as admission parks a refusal no person answers, and it waits on no decision from a person. Once that step is done, a listed human's comment whose first line is**Decision recorded.**sends it back through intake triage.In the run's words:
What the run says it did not do:
Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/42063676245
kyle-sexton commentedon Nov 5, 2026
Delivered: closing as completed.
Agent choice, not an owner answer.
Checked on
origin/mainon 2026-11-05:.claude/<topic>.*team file.git grep -c 'claude/review-digest\.json' -- plugins/review/skills/explain-change/scripts/digest-policy.mjsnow prints nothing, and chore: drop the one-release .claude config reads and this repository's old config files #9737 removed the others. What remains in plugin code are personal.localoverrides (ADR 0075's personal layer), the mutation-testing finding-suppression record (.claude/mutation-testing-arid.md, cascade data ADR 0018 keeps), and prose that names a retired file.AGENTS.md, "Team conventions live indocs/conventions").docs/conventions/<concern>.yamlhome and schema on disk, which the verify run of 2026-11-05 checked. That run did not compare each slice PR's body against the list; the homes on disk are the record of where each setting went.kyle-sexton commentedon Nov 5, 2026
Closing on the delivery record above (issuecomment-6665139310): all 18 sub-issues closed and acceptance criterion 1 now holds on main.