docs: own consumer-config layering as a Convention registry concern - #692
Conversation
The tracked-rich-config seam fixes the resolution order for every consumer-config surface in the fleet, and `PLUGIN-PHILOSOPHY.md` states that fleet audits check conformance per registry row. This rule had no row, so nothing audited it, and the fleet drifted: of twelve consumer- tracked config surfaces, five are single-layer, three carry declared deviations, and two diverge with no rationale recorded anywhere. Extracts the layering axis into an owner doc and registers it. The contract governs layering and precedence only — layer set, order, override semantics, overlay naming, and the resolution algorithm. Keys and schema stay with each concern's own owner doc, which is what keeps this from colliding with one-owner-doc-per-shared-concern. Seam 2 now points at the contract instead of restating it. Deviations are recorded as observed, not ratified; ruling on them stays a separate human-gated decision. The implementers table names every surface and its current conformance state, so the gap is tracked rather than the doctrine pretending it is closed. Also narrows security criterion 4, per the maintainer ruling on #660. Its "no absolute paths / no reading consumer files outside CLAUDE_PROJECT_DIR" wording read as forbidding the `~/.claude/` user-global that seam 2 mandates and that criterion 3 already uses for credentials — a self-contradiction a reviewer surfaced in practice. The criterion now says consumer *repository* files and carves out the operator's own Claude Code home explicitly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 6m 39s —— View job PR Review
SummarySolid structural addition — a cross-cutting layering contract that was missing a registry row is now owned in one place, the shape matches Findings1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a1e8481a1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The layer table gave the user-global path as `~/.claude/<name>` with `<name>` described as the surface's filename. For a folder-form surface that resolves to `~/.claude/<ecosystem>.yaml` while the team layer reads `.claude/ecosystems/<ecosystem>.yaml` — two different files for one surface. `<name>` is now defined as the whole path relative to `.claude/`. The recommended consumer `.gitignore` was `.claude/*.local.*` plus a recursive line "as well", which asks for two lines and leaves a nested overlay unignored for anyone who adds only the first. Verified against git that `.claude/**/*.local.*` alone matches flat, one-deep, and two-deep overlays while leaving team files tracked, so the contract now recommends that single line. `codebase-health` was recorded as leaving its merge semantics undocumented. It does not: `skills/audit/SKILL.md:75-80` declares glob union, example-claim concatenation with duplicate collapse, and an explicit empty-list opt-out. Corrected to conforming in both the deviations section and the implementers table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 34s —— View job PR Review — after corrections (
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b02f19435
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…nded The implementers table credited `source-control` with all three layers, but its layering change is still in flight and unmerged — on `main` the plugin reads only the repo-root team file. A registry row that runs ahead of the code reports a closed gap that is still open, which defeats the point of tracking conformance at all. The row now reads single-layer with the migration named, and the table states the as-on-main rule so the next row does not repeat it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 54s —— View job PR Review — after corrections (
|
|
Control tower — HOLD for operator review (checkpoint 2026-07-20 ~16:30Z). Digest: the extraction itself is faithful (no rule changed; deviations recorded as observed, not ratified — does not pre-empt #649). Two reasons this stays in the operator queue rather than decide-and-log:
RECOMMENDED: review with #649 in the morning batch (batch item 3); merge after ruling, folding any named-exception-class language into the contract in the same pass. |
…ascade (#1190) ## Summary Renames the marketplace-wide consumer-config layering seam from the clunky three-noun `consumer-config-layering` to **`config-cascade`**. Name chosen via `/naming:name-it-better` (blind 3-lens fan-out): "cascade" (CSS `@layer`/`!important`) is the one established term of art that natively carries **both** per-key override **and** a ratified precedence-inversion — matching the seam's user→team→local + policy-floor model. Runner-ups: `config-layering`, `layer-cascade`, `config-precedence`. - `git mv docs/conventions/consumer-config-layering → config-cascade`. - All **live** references updated (name + path): MIGRATION-PLAYBOOK, PLUGIN-PHILOSOPHY, loop-lane seam, code-tidying (SKILL + docs-prose lane), testing (README + run-e2e SKILL/context), `.gitignore`. - Seam README records the former name (discoverability); CHANGELOG records the rename with **no `contract_version` bump** — name/path only, contract unchanged. - code-tidying `0.7.1→0.7.2`, testing `0.3.1→0.3.2` (patch) so consumers receive the corrected doc-URL. - **Historical** topic docs / CHANGELOGs retain the former name as frozen record (bare-text mentions, not links). **Provenance context:** the rename was gated (issue #1187) on whether the seam was legitimately ratified. Finding: all 12 `docs/conventions/*` seams are PR-introduced across the repo's whole history; `consumer-config-layering` (#692) is unremarkable. The shared `kyle-sexton` identity (human + agents) makes metadata-level "human-ratified vs agent-accreted" undecidable — a **repo-wide** property, not a disqualifier for this seam. The operator's direct direction this session is the ratification. ## Test plan - `lychee --offline './**/*.md'` — **0 errors** (2754 links checked); no dead relative link to the old path. - `grep -rn '](.*conventions/consumer-config-layering' .` — none (no dead relative links). - `scripts/check-changelog-parity.sh --check-bump origin/main` — both bumped plugins have entries. - Remaining `consumer-config-layering` mentions are historical bare-text only (topic PLANs, CHANGELOGs, `.work/`). ## Related - Closes #1188 - Provenance context: #1187 (audit finding recorded above) - Follows #1185 (well-known path, which dogfoods the `docs/conventions/<concern>/` location) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Closes #648
Summary
The tracked-rich-config seam in
docs/MIGRATION-PLAYBOOK.mdfixes the resolution order for every consumer-config surface in the fleet.docs/PLUGIN-PHILOSOPHY.mdstates that fleet audits check conformance per registry row — and this rule had no row, so nothing audited it.Adds
docs/conventions/consumer-config-layering/(README + CHANGELOG, following thehook-telemetryshape), registers it in the Convention registry, and points seam 2 at it rather than restating the rules in two places.The contract owns the axis, never the keys. Layer set, precedence, override semantics, overlay naming, and the resolution algorithm. Which keys a surface has and how they validate stay with that concern's own owner doc. That boundary is what keeps this from colliding with "One owner doc per shared concern" — layering is genuinely cross-cutting; keys are not.
Deviations are recorded as observed, not ratified. Ruling on them is a separate human-gated decision (#649) and nothing here rules on anything.
Correction to the issue's evidence table
The issue cites 15 surfaces. A direct re-census found 12, and two of the issue's verdicts do not survive reading the files:
songwriting— undeclared deviation, "first-match-wins, freezes the template"songwritinghas no consumer-config surface at all. Its only.claude/read is the consuming project'sCLAUDE.md/.claude/rules(skills/setup/SKILL.md:58) — that is seam 3 steering, not seam 2 tracked config. Not a row.code-tidying— undeclared deviation ("overrides this file entirely")skills/tidy/lanes/docs-prose.md:14), but the thing being overridden is the plugin's own bundled lane file, not a consumer layer. That is a bundled-default rung, structurally the same astoolchain's rung 4. Recorded as single-layer over a bundled default.work-items(×2),standards.yaml,out-of-scopecounted as separate single-layer surfacesout-of-scopeis not a plugin.standards.yamlis the root-relocation knob of thestandardssurface, not a second surface.work-itemsis one surface — and it is the one the census nearly missed, because its config is.work-item-tracker.jsonat the repo root rather than under.claude/. It is in the table.Net: fewer surfaces, and one genuinely new finding —
ai-briefingadvertises an overlay layer it does not implement. Its setup recommends a.claude/ai-briefing/**/*.local.*gitignore line, but no read path resolves a.local.*file and nothing defines what one would do. That is the only surface telling consumers to gitignore a layer that has no effect.Every file:line in the table was re-read directly rather than taken from a summary.
Also: security criterion 4
Narrowed per the maintainer ruling on #660. Its "no absolute paths, no reading consumer files outside
${CLAUDE_PROJECT_DIR}" wording read as forbidding the~/.claude/<plugin>.mduser-global that seam 2 mandates and that criterion 3 already uses for consumer credentials — a self-contradiction a reviewer hit in practice on #660. It now says consumer repository files and carves out the operator's own Claude Code home explicitly, so the next plugin author does not re-litigate it.Test plan
markdownlint-cli2acrossdocs/**/*.mdwith the repo config — 0 errors.typos --config _typos.toml docs/— clean.link-checkis a weeklyfail: falsecron, so nothing gates this at PR time.toolchain/reference/resolution-ladder.md:32,autonomy/skills/setup/SKILL.md:355,docs/conventions/standards/README.md:35,disk-hygiene/skills/clean/SKILL.md:77,code-tidying/skills/tidy/SKILL.md:58,docs/conventions/topic-docs/README.md:224,ai-briefing/skills/generate/SKILL.md:63,codebase-health/skills/audit/SKILL.md:70,repo-fleet-hygiene/skills/setup/SKILL.md:20.Docs-only; no plugin behavior changes.
Related
source-control); independent of this PR, and currently held under ado-not-mergelabel