Skip to content

Migrate per-skill .claude config files to userConfig, one conventions doc, or the cascade (ADR 0018) #5906

Closed
18 of 18 issues completed

Description

@kyle-sexton

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

  1. Inventory every per-skill .claude/<topic>.* file and every skill body that names one.
  2. Classify each setting: userConfig scalar, convention prose, or cascade data (structured, per-operator, policy floor or state), against ADR 0018.
  3. 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.
  4. 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.

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 2, 2026
  2. kyle-sexton commented on Oct 4, 2026

    @kyle-sexton
    MemberAuthor

    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:

    • The repository's .claude/ holds the seven files the issue names plus cloud-bootstrap.sh and cutover-pathdet-ack.txt; the plan should say whether either is a skill configuration file.
    • The "about 38 skill bodies" count needs redoing: a rough grep for .claude/<topic>.(json|md|yaml) across plugin SKILL.md files matches 60 files, though that pattern also catches settings.json and similar, so it overcounts.
    • Two ADRs are numbered 0018 (the issue already says to cite the full filename).
      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 0018 at e3bef1210.

    Agent Brief

    Type: Task
    Summary: Move each per-skill one-off .claude/<topic>.* setting to its ADR 0018 home: owning plugin userConfig, 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:

    • Each plugin's userConfig schema and its setup skill.
    • The consumer conventions doc and its single pointer line.
    • The config-cascade, consumer-config-layering and plugin-reconfiguration conventions, and ADR 0018 (express team-shared conventions as consumer convention docs).

    Acceptance criteria:

    • An approved classification table lists every file and setting with its home.
    • 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, with the one-release compatibility read in place.

    Out of scope:

    • .claude/settings.json, hooks and rules.
    • Changing ADR 0018's categories unless the approved classification requires it.
  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    status: needs-decisionAwaiting a human or maintainer judgment call.
    work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 4, 2026
  4. kyle-sexton commented on Oct 4, 2026

    @kyle-sexton
    MemberAuthor

    The target home has changed. Standards components/github-actions-conventions/README.md:131-136 (merged
    2026-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 structured
    configuration. 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.
    pluginConfigs is 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. It
      moves to docs/conventions/source-control.yaml, which by then will already exist holding only
      pr_open_state. Keep the old file with identical keys until a release carrying the new reader has
      shipped and the git hooks have been reinstalled.
    • The other .claude/* files: ai-slop.json, attribution.json, bugs.md, docs-naming.json and
      audit-pass.md. The effort moves code-metrics.yaml itself.
    • The ADR 0044 fenced config blocks in the multi-agent plugin and in docs/conventions/review-digest.md.
      The effort migrates testing's block itself.
    • Guardrails' folder-form docs/conventions/source-control/commit-convention.yml.

    Script readers use the shared reader lib/parse-concern-value.sh. After the effort's change it reads
    dotted 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 setting
    with its new docs/conventions/<concern>.yaml home and schema.

  5. added theissue type on Oct 15, 2026
  6. 51 remaining items

  7. added
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Nov 5, 2026
  8. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 5, 2026
  9. kyle-sexton commented on Nov 5, 2026

    @kyle-sexton
    MemberAuthor

    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/main on 2026-11-05:

    • plugins/review/skills/explain-change/scripts/digest-policy.mjs:249-252 lists .claude/review-digest.json among the team layers ([TEAM_YAML, "docs/conventions/review-digest.md", ".claude/review-digest.json"]), and :41-42 keeps both .claude/review-digest*.json files in CONFIG_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.
    • Every other repo-relative .claude/<topic>.* hit in plugin code is either a personal .local override 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.mjs prints nothing (it prints 4 lines today), and the docs/conventions/review-digest.md fenced-block fallback is dropped with it, so the team layer is docs/conventions/review-digest.yaml only. The user-global layer is unchanged.
    • node --test plugins/review/tests/explain-change.test.mjs passes 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/main exits 0 (a review fragment).

    When these land, criterion 1 holds and this issue closes as completed.

  10. github-actions commented on Nov 5, 2026

    @github-actions
    Contributor
    No description provided.
  11. github-actions commented on Nov 5, 2026

    @github-actions
    Contributor
    No description provided.
  12. removed
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Nov 5, 2026
  13. melodic-automation-lanes commented on Nov 5, 2026

    @melodic-automation-lanes
    Contributor

    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-ready and status: ready and added status: 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:

    verify-unmet: done-when item 1 (no skill reads a team setting from a .claude/<topic>.* file or a fenced config block) is unmet for review-digest. plugins/review/skills/explain-change/scripts/digest-policy.mjs:205-241 (readTeamDigest, called at :262) still takes the team layer from the ```json config block in docs/conventions/review-digest.md, else from .claude/review-digest.json, whenever docs/conventions/review-digest.yaml is absent on the base commit, and docs/conventions/review-digest.md:85-98 still holds that block, which it says stays 'until the cleanup slice under #5906 removes it'. #9737's done-when grepped only for 'yaml config', so this json config reader was missed; no open slice owns removing it. Item 2 (each migrated setting listed with its docs/conventions/<concern>.yaml home and schema) was checked only against the files on disk, not against each slice PR's body.

    What the run says it did not do:

    • Did not compare each slice PR's body against the done-when's 'PR lists each migrated setting with its docs/conventions/<concern>.yaml home and schema'; only the homes and schemas on disk were checked
    • docs/conventions/source-control/commit-convention.yml (the folder-form file the 2026-10-04 comment listed) is still read as a fallback by lib/resolve-convention-pattern.sh:21-22, though the file no longer exists in this repository. It is not a .claude file or fenced block, so the done-when does not…

    Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/42063676245

  14. kyle-sexton commented on Nov 5, 2026

    @kyle-sexton
    MemberAuthor

    Delivered: closing as completed.
    Agent choice, not an owner answer.

    Checked on origin/main on 2026-11-05:

    • All 18 sub-issues are closed as completed, the last being chore(review): drop the one-release review-digest team fallbacks #13556 (2026-11-05T17:38Z), which removed the review plugin's one-release team fallbacks.
    • Acceptance criterion 1: no skill reads a one-off .claude/<topic>.* team file. git grep -c 'claude/review-digest\.json' -- plugins/review/skills/explain-change/scripts/digest-policy.mjs now 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 .local overrides (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.
    • Criterion 2: the root instruction file carries the one pointer line to the conventions home (AGENTS.md, "Team conventions live in docs/conventions").
    • Criterion 3: each migrated setting has its docs/conventions/<concern>.yaml home 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.
  15. kyle-sexton commented on Nov 5, 2026

    @kyle-sexton
    MemberAuthor

    Closing on the delivery record above (issuecomment-6665139310): all 18 sub-issues closed and acceptance criterion 1 now holds on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumReal value, no hard deadline; normal backlog flow.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Type

    Fields

    Work status

    confirmed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions