docs: ratify the convention-doc expression doctrine and retirement seam (ADR 0018) - #3587
docs: ratify the convention-doc expression doctrine and retirement seam (ADR 0018)#3587kyle-sexton wants to merge 1 commit into
Conversation
…am (ADR 0018) Phase 2a of the customization-consistency program. Amends the three owner docs and records the decision in one ADR: - config-cascade (contract 1.2, additive): new "Expression doctrine" section — team-shared prose config is expressed as a natural-language convention doc at the consumer's convention home, bound by a single pointer line in a marked machine-owned region of the root instruction file (the line is the binding); per-operator-keyed, structured, policy-floor, and state surfaces stay files. Pointer-line rules (AGENTS.md canonical over a pure @AGENTS.md shim, duplicate and missing-target handling as ask-don't-infer FAILs, branch-scoped), root-file shape as the downstream repo's call, the WARN-visible dual-read deprecation window, the migrated-surface overlay WARN, and the machine-scope exclusion. Implementers table gains the per-row expression note each migration PR fills. - MIGRATION-PLAYBOOK: convention-resolution ladder amended (convention doc -> gated infer-and-persist house style -> ask -> default) and the retired-conventions seam named (retirements.yaml + shared check-retirements.sh; owner doc lands with the mechanism PR). - PLUGIN-PHILOSOPHY: ownership-table row for team-shared prose, mandatory retirement declaration, the one sanctioned dual-read, and ratification of the no-no-op-apply rule Phase 1b applied. - ADR 0018 records the decision, alternatives (one-liner grammar, candidates A and C, migrate-everything), and consequences, citing the tournament record. Gates: markdownlint clean on all five files; PLAN.md 2a sanity greps hit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014uBXt1tMEReShbpG5gsFUd
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014uBXt1tMEReShbpG5gsFUd
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28c6cc8596
ℹ️ 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 layers above describe **where** a surface's values live relative to each other. This section | ||
| describes **how** a surface is expressed at all, and it ratifies a second expression form | ||
| alongside the dedicated file ([ADR 0018](../../adr/0018-express-team-shared-conventions-as-consumer-convention-docs.md), |
There was a problem hiding this comment.
Reconcile the expression doctrine with the contract boundary
This adds expression selection to a contract that still declares at README lines 16–19 that it governs layering and precedence only, while the changelog likewise says contract_version governs only that axis. Consequently version 1.2 now represents a non-layering compatibility rule even though consumers are told that it does not, making future version checks and ownership decisions ambiguous. Either broaden the documented boundary/versioning semantics or give expression selection its own owner/version.
Useful? React with 👍 / 👎.
| 4. **Retirements are declared, not narrated.** A plugin that retires a consumer-facing convention | ||
| appends an append-only record to its `retirements.yaml`; one shared deterministic helper |
There was a problem hiding this comment.
Define a valid transition for append-only retirement records
Once a retirement reaches the required fleet-wide report-only phase, its record must change state, but this decision simultaneously requires each record to be append-only and later names a report-only demotion field. Without defining an appended transition record or explicitly allowing that field to mutate, the mechanism cannot implement both requirements consistently, and different plugins may either violate append-only history or never demote old records.
Useful? React with 👍 / 👎.
| - **Both root files.** `AGENTS.md` is canonical when present; a `CLAUDE.md` whose whole content is | ||
| the `@AGENTS.md` import is a pure shim and is not consulted for a pointer. When both files carry | ||
| a marked region, `AGENTS.md` wins and `CLAUDE.md`'s copy is reported as a duplicate finding | ||
| (remediation: remove it). Two pointer lines inside one region is a FAIL, never first-wins. |
There was a problem hiding this comment.
Preserve CLAUDE.md-canonical repositories when AGENTS.md exists
For a repository that intentionally keeps the marked pointer region only in CLAUDE.md while also having a non-shim AGENTS.md, the unconditional statement that AGENTS.md is canonical when present conflicts with lines 173–176, which promise that a CLAUDE.md-canonical shape is served identically after discovery. The resolver precedence should be defined in terms of which file owns the discovered region, reserving AGENTS precedence for the stated duplicate-region case; otherwise a conforming CLAUDE.md binding can be ignored or reported missing.
Useful? React with 👍 / 👎.
Closes #3586
Summary
Phase 2a of the customization-consistency program: the three owner docs are amended and ADR 0018 records the doctrine — team-shared prose configuration is expressed as a consumer convention doc bound by a pointer line, everything else stays a file, and retirements are declared in a per-plugin manifest evaluated by one shared helper. Lands before any surface migrates (the mechanism PR follows; the pilot after that).
Stacked on the Phase 1a PR (#3582) because 1a already touched config-cascade's README; retarget to
mainonce 1a merges.Fix
docs/conventions/config-cascade/README.md(+ CHANGELOG, contract 1.2 additive): new "Expression doctrine" section — the criterion (team-shared prose → convention doc; per-operator-keyed / structured / policy-floor / state → file), the pointer line as the binding inside a marked machine-owned region (rules-index-block precedent), pointer-line rules (AGENTS.md canonical over a pure@AGENTS.mdshim; both-files precedence and duplicate handling; pointer-absent-but-known-home and missing-target are ask-don't-infer FAILs; branch-scoped binding), root-file shape as the downstream repo's call, the WARN-visible dual-read deprecation window with its end conditions, the migrated-surface overlay WARN, and the machine-scope exclusion. Implementers table intro gains the per-row expression note each migration PR fills.docs/MIGRATION-PLAYBOOK.md: convention-resolution ladder amended (convention doc → gated infer-and-persist house style → ask → default; nothing hardcodesdocs/conventions/) and a new "Retired conventions" subsection naming the seam (retirements.yaml+ sharedcheck-retirements.sh, owner doc to land with the mechanism PR, repo-scope only).docs/PLUGIN-PHILOSOPHY.md: ownership-table row for team-shared prose; "Retirement declaration is mandatory" paragraph; the clean-break sentence now names the one sanctioned WARN-visible dual-read; the check-only carve-out now states a no-opapplyis non-conforming (ratifies Phase 1b, fix: drop the no-op apply action from the five check-only setups #3583).docs/adr/0018-express-team-shared-conventions-as-consumer-convention-docs.md: context, the six-part decision, alternatives (one-liner CLAUDE.md grammar, candidates A and C, migrate-everything), consequences.Verification
ls docs/adr/ | grep -i conventionhits the new ADR;grep -n "convention home\|@AGENTS.md" docs/conventions/config-cascade/README.mdhits;grep -n "retirements\.yaml" docs/MIGRATION-PLAYBOOK.md docs/PLUGIN-PHILOSOPHY.mdhits in both.Related
Refs
docs/topics/customization-consistency/PLAN.mdPhase 2a; tournament recorddocs/topics/customization-consistency/design/mechanism-validation.md; Phase 1 PRs #3582 #3583 #3584 #3585. Theretired-conventionsowner doc and convention-registry row land in the Phase 2b mechanism PR.