Skip to content

docs: ratify the convention-doc expression doctrine and retirement seam (ADR 0018) - #3587

Open
kyle-sexton wants to merge 1 commit into
chore/gitignore-line-convergencefrom
chore/customization-doctrine
Open

docs: ratify the convention-doc expression doctrine and retirement seam (ADR 0018)#3587
kyle-sexton wants to merge 1 commit into
chore/gitignore-line-convergencefrom
chore/customization-doctrine

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

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 main once 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.md shim; 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 hardcodes docs/conventions/) and a new "Retired conventions" subsection naming the seam (retirements.yaml + shared check-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-op apply is 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

  • PLAN.md 2a Sanity Check: ls docs/adr/ | grep -i convention hits the new ADR; grep -n "convention home\|@AGENTS.md" docs/conventions/config-cascade/README.md hits; grep -n "retirements\.yaml" docs/MIGRATION-PLAYBOOK.md docs/PLUGIN-PHILOSOPHY.md hits in both.
  • markdownlint-cli2 over the five touched files: 0 issues. ADR relative link from config-cascade resolves.
  • Stress-test-mandated content present in the 2a text: dual-read window (DA C1) with end condition in the ADR; criterion amendment (DA C2) with the overlay WARN; pointer-line robustness (DA H2/M4/M5).

Related

Refs docs/topics/customization-consistency/PLAN.md Phase 2a; tournament record docs/topics/customization-consistency/design/mechanism-validation.md; Phase 1 PRs #3582 #3583 #3584 #3585. The retired-conventions owner doc and convention-registry row land in the Phase 2b mechanism PR.

…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
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T17:32:25.062230Z 28c6cc8 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

kyle-sexton added a commit that referenced this pull request Sep 1, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014uBXt1tMEReShbpG5gsFUd

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +124 to +126
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),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +41 to +42
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +162 to +165
- **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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant