docs(conventions): add upstream-drift owner doc for verification stamps and recheck triggers - #1686
Conversation
…ps and recheck triggers
The dated verified-against-upstream stamp plus re-derivation trigger
pattern was practiced in five-plus docs-level places under three names
(recheck, revisit, re-derivation) with no owner doc — itself a violation
of the convention registry's one-owner-per-concern rule, which requires
an owner doc before a second adopter.
docs/conventions/upstream-drift/ now owns the concept: one canonical
name (recheck trigger, adopted from the standards repo's
documentation-and-citations.md rather than forking its vocabulary), the
four required parts of a conforming record (claim, basis, as-of date,
trigger), the observability bar a trigger must clear, the rule that a
date is an as-of record and never standing authority, the drift-signal
finding (no ETag and no per-page Last-Modified on the docs raw-markdown
endpoints, re-verified 2026-07-26 by header inspection, so content
hashing is the only viable mechanical signal — hash store deferred with
its own trigger), and the enforceability classification per the
standards enforceability-tiers routing rule.
Existing instances migrate to the single name and cite the owner doc,
content intact: hook-config-delivery (already canonical name),
ecosystem-commands ("Revisit triggers"), loop-lane ("Re-derivation
triggers", generic rationale moved to the owner), topic-docs ("What
would reopen it"), PLUGIN-PHILOSOPHY (staleness disclaimer + registry
row), OFFICIAL-DOCS (staleness warning), MIGRATION-PLAYBOOK (per-record
"Revisit trigger" labels). Convention changelogs carry docs-only patch
entries. History (CHANGELOG entries, ADRs, dated audit records) keeps
its shipped wording; living surfaces elsewhere adopt the name on touch.
Closes #1638
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…of rule Two verifier findings: the owner doc tightened the org standard's recheck-trigger form list (which accepts a bare date) without saying so, and the as-of-record rule was stated in full in three places. The boundary section now declares the tightening deliberate and leaves the upstream form list to the org standard; PLUGIN-PHILOSOPHY and loop-lane now carry only pointers, so the owner doc is the rule's single full statement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 56s —— View job Review — docs(conventions): add upstream-drift owner doc
Overall verdict: Approve with one minor note. The PR closes a real one-owner-per-concern violation cleanly, the owner doc is well-structured, all citations resolve, changelog bumps are correct, and the second-commit post-verifier fixes (silent tightening declared, duplicated as-of rule cut to a pointer) are the kind of nuanced pre-ship cleanup that marks a careful change. What was checkedStructural conformance. The new Naming consistency. All 13 files use "recheck trigger" as the canonical name. Every previous label ("Revisit trigger", "Re-derivation triggers", "What would reopen it") has been migrated in the in-scope surfaces and each changelog carries a correct patch entry explaining the rename. ✅ Cross-references / relative paths. Spot-checked all link targets:
Second commit correctness. The verifier findings were real: the Boundary section now explicitly declares the tightening (date alone doesn't qualify as a trigger under this repo's specialization); PLUGIN-PHILOSOPHY and loop-lane now carry only pointers, making the owner doc the single full statement of the as-of rule. The diff is surgical and accurate. ✅ Changelog version bumps. All four patch bumps are correct: 1.2.3, 1.0.1, 3.0.1, 2.3.1 each increment from the prior version and the entries describe the actual change accurately. ✅ Deliberate non-migrations. The PR correctly leaves ADR sections, CHANGELOG history, and dated audit records unchanged (history is never rewritten), and excludes Adopters table completeness. The seven rows in One minor noteMIGRATION-PLAYBOOK: Convention-seam and unused-component sections lack a citation. The "Deferred surfaces" intro sentence carries the one link to the owner doc — This doesn't affect correctness, and it's consistent with the PR's intent to avoid link noise. But given how far apart these sections are in a 1,479-line document, a link at the first Observations (non-blocking)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a37386fba2
ℹ️ 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".
Codex review (PR #1686, P2): the adopter table claimed every listed surface was migrated to the contract, but the ecosystem-commands deferral carries neither an as-of date nor an external basis, and the topic-docs record guards an entirely in-repo hoisting decision — both outside the upstream-derived boundary and short of the four required parts, so the table advertised conformance an audit could not rely on. Resolved by keeping the boundary tight rather than widening the contract to fit its exceptions: the table now distinguishes conforming four-part records from named triggers (canonical name, observability bar, and firing procedure on an in-repo decision) and states per row exactly what a reader can rely on. The four required parts are unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Addressed the P2 ("Align declared adopters with the contract boundary") in 31294f6: the adopter table no longer claims uniform conformance. It now distinguishes conforming four-part records from named triggers — surfaces that share the canonical name, observability bar, and firing procedure but guard an in-repo decision (ecosystem-commands' undated deferral, topic-docs' source-hoisting decision, and MIGRATION-PLAYBOOK's org-internal records) — and states per row what a reader can rely on. The upstream-derived boundary and the four required parts are unchanged; the contract was not widened to fit its exceptions. |
|
Claude finished @kyle-sexton's task in 2m 17s —— View job Review — 31294f6 (adopter-table fix)
Verdict: The fix is correct and complete. The commit directly resolves the Codex P2 finding with a surgical, two-file change. The boundary is kept tight; the contract is not widened. What changedThe adopter table (
Classification accuracy checkI verified each row's claim against the actual documents:
CHANGELOG handlingThe clarification is appended to the No new issuesThe prior review's minor note (MIGRATION-PLAYBOOK sections lacking links at their first |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31294f6fcc
ℹ️ 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".
|
Merge-lane thread worker claiming PR #1686 for one cycle: reviewing the 3 unresolved Codex review threads on |
… internal-trigger exemption Codex review (PR #1686, two P2 threads on the upstream-drift owner doc). The hash-store deferral's second disjunct read "stamped claims accumulate past what manual re-fetch at audit time covers" — no count, cadence, or capacity from which a reader could decide it had fired, which is exactly what the doc's own observability bar rejects. It now fires on an event the audit record settles: a fleet audit completing without re-fetching every stamped claim in its scope. No invented threshold count; "each fleet audit" is already a form the bar accepts. The on-touch migration instruction required every living synonym to adopt the required parts, contradicting the adopter table's own exemption for named triggers guarding in-repo decisions — an implementer touching ecosystem-commands or topic-docs would have had to invent an external basis and as-of date. On touch a surface now adopts the canonical name, the observability bar, and the firing procedure; only a surface restating an upstream-owned specific additionally adopts the required parts. Neither edit changes a required part, the canonical name, or an enforceability verdict; the contract is unreleased at 1.0.0 in this PR, so no changelog bump. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FtrbRf8pyuYmuWXodEPivm
|
Claude finished @kyle-sexton's task in 2m 4s —— View job Merge-lane thread review — 3 Codex P2s on
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 15b29e196a
ℹ️ 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".
|
🤖 Lane claim released — babysit-loop cycle |
Three review findings, one root defect: the firing procedure was written for a single record kind, then the adopters table grew several. A four-part record fires by re-fetching its cited basis and refreshing its as-of date. A named trigger on an in-repo decision has neither, so it now fires by re-deriving from the in-repo state the trigger names -- the procedure an agent can actually execute. Read-time validation is separated from a firing: a lookup that finds no drift obliges nothing, so consulting OFFICIAL-DOCS.md no longer implies editing it, while a fetch that DIVERGES from a row is that row's trigger and updates it. The migration playbook's workflow-engine record claimed conformance on an unsourced basis. Re-verified against live docs: the no-native-slot premise no longer holds -- plugins ship workflow scripts through a `workflows/` directory or the `workflows` manifest field. The record now cites both pages and re-derives its recheck trigger onto the native slot; the deferral itself stands on the usage question alone, which was always its real basis. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 3s —— View job Review —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4bf6923d78
ℹ️ 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".
…claims The adopters table promised a two-kind dichotomy over the migration playbook's records -- four-part records citing upstream bases, or named triggers on org-internal decisions -- and the playbook holds records that are neither. The knowledge-corpus record's pulumi-github decision was the real gap: an upstream-derived recorded decision (Git LFS is not expressible on the v6.14.0 `Repository` resource, verified against the provider schema) carrying claim, basis, and date but no recheck trigger. Its premise rots exactly as this contract warns -- a newer provider version shipping LFS support re-opens the IaC-versus-content-side call -- so it now names that event as its trigger rather than being reclassed out of conformance. The skill-quality retrofit record's deliberate "no recheck trigger" is a third kind the row did not name; it is named now. The shared-code record still said "Revisit iff" and "Revisit if" inline, which falsified the table intro's claim that adopters migrated to the single name at 1.0.0. The earlier pass renamed every labeled "Revisit trigger:" heading and missed the inline forms. Its bases move from page-plus-section names to URLs, which is what required part 2 asks for. hook-config-delivery advertised per-fact triggers while its list mapped only facts 1-6; fact 8 -- sensitive values in the OS keychain, which the matrix's "F cannot read them at all" rests on -- had none. The named-trigger firing procedure said to re-derive "from the in-repo state the trigger names", but two of its own instances name state that is not in-repo: ecosystem-commands' second trigger watches an upstream lefthook release, and the ratification record's watches org state. The step now names the state the trigger names, whatever kind it is, so it binds to every instance instead of reading as impossible for two. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 18s —— View job Review —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc050fc30f
ℹ️ 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".
Recognizing `workflows/` as a native plugin component left two canonical indexes incomplete. The component table in OFFICIAL-DOCS promises one row per component type and had none for workflows; the component-stances table in PLUGIN-PHILOSOPHY assigned it no stance, so an author following either map missed the packaging surface entirely. The stance is Adopt on need, not Wait: workflows carry no `experimental` key (that key covers only themes and monitors), and the deferred workflow engines are a named candidate with a live trigger, so the gap is identified rather than hypothetical. The constraint is availability, not maturity — paid-plan gating plus per-user and org-wide disable switches mean a consumer can end up with no `/plugin:name` at all, which is the `bin/` row's never-make-it-load-bearing rule in a different shape. Two consequences of the same recognition, in the record that made it: the workflow-engine citation split its two anchors onto the two facts they each document, and the unused-components record states it is a dated evaluation of the candidates raised that day, not an index — the component-stances table is the index. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 47s —— View job Review —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 656e2e9707
ℹ️ 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".
…fetchable basis
The playbook's plugin-acceptance review record labeled its reopening
event `**Re-trigger:**` -- a fourth prior name the owner doc's own
inventory did not list, so this branch shipped a doc whose motivating
claim ("five-plus places under three names") its own diff falsified. The
label becomes `**Recheck trigger:**`, cites the owner convention (that
section had no citation at all -- only the Deferred-surfaces intro did),
and states its kind: a named trigger on an in-repo decision, so no basis
or as-of date is owed. The inventory, the adopters row's "Was" cell, the
binds-on-touch list, and the 1.0.0 changelog entry all name "re-trigger"
now.
The shared-code symlink deferral rests on an upstream premise -- that
marketplace symlinks are skipped for `--plugin-dir` / local-path installs
-- that neither of its two triggers covered, so upstream could remove the
premise without firing anything. That divergence is now the third
disjunct. The record's as-of date is unchanged: adding a missing
disjunct is record completeness, not a re-derivation, and the date
refreshes with an outcome on a firing.
The knowledge-corpus LFS decision said only "verified against the
provider schema", which an updater cannot re-fetch. It now cites the
pinned-tag schema URL and the probe: at v6.14.0,
`github:index/repository:Repository` declares 48 properties and 39 input
properties, none matching `lfs`, and the whole schema document has no
case-insensitive `lfs` match. Fetched and probed 2026-07-29 -- the basis
carries its own date rather than inheriting the section's.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 39s —— View job Review —
|
The previous commit renamed `**Re-trigger:**` to the canonical name but moved the colon outside the bold and split it with a parenthetical, so `grep '\*\*Recheck trigger:\*\*'` matched the file's nine other sites and not this one. That is the same miss the finding raised, in a subtler shape, and it lands in the PR that stakes the deterministic enforceability tier on stamps and triggers using greppable forms. The label is now byte-identical to every sibling; the owner-doc citation and the record's kind move into the sentence after it, where they cost the grep nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 6s —— View job Review —
|
Two conflicts, both from convention changelogs advancing on main while this branch was in review, resolved preserving both sides: - topic-docs: main released 2.4.0 (the ephemeral tier row) and this branch had 2.3.1. The docs-only rename entry renumbers to 2.4.1 and sits above 2.4.0, so the file stays monotonic and main's release is untouched. - loop-lane: same shape -- 3.0.1 renumbers to 3.1.1 above main's 3.1.0. One semantic conflict the markers did not show: main's topic-docs 2.4.0 introduced a new `**Re-derivation trigger.**` label in that convention's README -- the superseded synonym, landing in a surface this branch's adopter table advertises as migrated to the single name. Merging as-is would have shipped an owner doc falsified by the tree it governs. The new record keeps its content and gains the canonical label plus the owner-doc citation, matching the sibling instance in the same file, and the 2.4.1 entry records that it was renamed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 4m 46s —— View job Review —
|
| Codex thread | Status |
|---|---|
Align declared adopters with the contract boundary (a37386f → 31294f6f) |
✅ Adopter table unchanged; conforming vs named-trigger distinction preserved |
Define a decidable threshold for the hash-store trigger (31294f6f → 15b29e1) |
✅ "fleet audit completes without re-fetching every stamped claim in its scope" still the trigger |
Preserve the internal-trigger exemption during on-touch migration (31294f6f → 15b29e1) |
✅ Two-tier on-touch instruction unchanged |
Define a firing path for stamp-less triggers (15b29e1 → 4bf6923) |
✅ Per-kind procedure intact |
Exempt read-time validation from durable refreshes (15b29e1 → 4bf6923) |
✅ §Read-time validation is not a firing unchanged |
Add missing basis for workflow-engine decision (15b29e1 → 656e2e9) |
✅ Three anchored URLs in MIGRATION-PLAYBOOK |
Add workflows to the component index (4bf6923 → 656e2e9) |
✅ OFFICIAL-DOCS and PLUGIN-PHILOSOPHY rows unchanged |
Include upstream symlink behavior in the trigger (656e2e9 → 7b4feffe) |
✅ Third disjunct in shared-code trigger intact |
Cite re-fetchable basis for LFS decision (656e2e9 → 7b4feffe) |
✅ Pinned-tag raw schema URL + probe intact |
Migrate the remaining security-review trigger label (dc050fc → 7b4feffe) |
✅ **Recheck trigger:** at MIGRATION-PLAYBOOK:1092, greppable form |
…hangelog order (#1758) ## Why The per-cycle usage-sample invariant (loop-lane 6.0.0, shipped in #1719) is self-contradictory as written. §4 permits reading the previous sample back **"for exactly one operation: subtracting its `five_hour_pct`"**, then states **"No other read is permitted"** — but the same invariant withholds a delta when the window rolled over, and deciding that requires a *second* comparison against that previous reading. No lane can satisfy both clauses. This is not theoretical. Both `babysit-loop` and `work-loop` were rewritten to hold the readback contract **by citation** ("Everything else — the single permitted readback … — is the convention's") while independently mandating the rollover comparison. The contradiction therefore has exactly one authoritative site, and every consuming lane inherits it. `chatgpt-codex-connector` raised this on #1719. The fix was drafted but never committed — the authoring agent was interrupted mid-edit and #1719 merged without it. ## What changed - **The permission is scoped by *purpose*, not by *operation*.** It now covers deriving `five_hour_delta_pct` — the subtraction **and** the rollover comparison — as one derivation. **The measure-only guarantee is unchanged**: the value still reaches no decision, at any threshold, in a lane or in any gate a lane runs. - **`at` disambiguated.** It is when the lane read the tee, not the snapshot's own `captured_at`, which the staleness rule permits to lag it. - **The delta's `null` condition widened.** "Either sample is missing" excluded a present sample carrying a `null` `five_hour_pct`; it is now `null` whenever either side's `five_hour_pct` is unavailable. ### Changelog version regression (separate defect, same file) `docs/conventions/loop-lane/CHANGELOG.md` on `main` read `6.0.0 → 3.1.1 → 5.0.0 → 4.0.0 → 3.1.0`. The `#1638` entry was authored against `3.1.0` and merged (#1686, 17:46:59Z) after `4.0.0` had already landed (17:44:23Z) — a stale-branch renumber miss, in a file with no CI gate for version order. Renumbered **`4.0.1`** and repositioned below `5.0.0`, which preserves both descending version order and the order entries actually shipped in. **Its wording is unchanged.** Verified by script — all three touched changelogs are now strictly descending with no duplicates. ## Deliberately not done The `source-control` `0.39.0` and `work-items` `0.29.0` entries describe the field as *"deliberately inert: no lane behavior reads it back"*, which the shipped contract contradicts. Those versions have already been published, so they are **left as shipped** and superseded by the new `0.40.2` / `0.30.2` entries rather than rewritten in place. ## Verification - `node scripts/validate-plugin-contracts.mjs` — 43 setup skills, 2150 files, pass - `bash scripts/check-changed-skills.sh origin/main` — 2 skills, 0 failures (`babysit-loop` 495/500, `work-loop` 434/500) - `npx markdownlint-cli2` over all 6 changed markdown files — 0 errors. Run standalone because `check-changed-skills.sh:67` sets `CHECK_SKILL_SKIP_MARKDOWNLINT=1` by design (documented at line 19; markdown is gated by the hygiene lane). - Changelog ordering verified by script against `sort -rV`. ## Related No linked issue — this corrects defects in already-merged work; both originating issues are closed. Refs #1651 (the usage-sample invariant this corrects, shipped via #1719) Refs #1638 (the changelog entry renumbered here, shipped via #1686) Refs #1720 (its post-merge review findings are tracked separately, not in this PR) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
## Why #1758 renumbered a `3.1.1` entry that had reached `main` sitting *below* `4.0.0`. This gate is the reason that could happen at all, and it closes it. The entry was authored against `3.1.0`, and merged (#1686, `17:46:59Z`) after `4.0.0` had already landed (`17:44:23Z`). Its number was a regression the instant it merged. Nothing caught it, because **no gate reads a changelog as a sequence**: - `--check` asks whether a versioned plugin has a changelog *at all*. - `--check-bump` asks whether this change set added an entry for *its own* new version. Both reason about one version in isolation, so neither can see that a branch staged a number already behind `main`, or that two branches staged the same one. A reviewer cannot see it either — the diff hunk shows the new entry, never the resulting order. That is not a one-off. The batch this came from had `source-control 0.34.0` claimed by four branches and `work-items 0.26.0` by five; those were caught only because a human renumbered them by hand, one merge at a time. ## What this adds `scripts/check-changelog-parity.sh --check-order` reads each changelog **whole** and fails on: - a version sitting below a later one (naming the offending pair), and - any version listed twice — the two-branches-staged-the-same-number case. Wired into `ci.yml` as a non-PR-scoped step, because the defect is a property of the merged file rather than of any one diff. ### Scope note It covers `docs/conventions/*/CHANGELOG.md` as well as `plugins/*/CHANGELOG.md`. That is deliberate and load-bearing: convention changelogs carry no manifest version, so the other two modes never look at them — and a convention changelog is exactly where this shipped. ## Verification Adversarial, not just green: **the gate fails on `main`'s pre-#1758 loop-lane changelog and passes once the renumber is applied.** ``` MISORDERED CHANGELOG: docs/conventions/loop-lane/CHANGELOG.md is not newest-first — 5.0.0 (below 3.1.1). ``` - `check-changelog-parity.test.sh`: **26 → 32 cases, 0 failures.** Includes the exact shape that shipped (`6.0.0 → 3.1.1 → 5.0.0 → 4.0.0`, unbracketed convention headings), a duplicate-version case, and a `10.0.0 > 9.0.0` case so the comparison cannot regress to lexical. - `shellcheck -x` on both scripts — clean, no suppressions added. - `--check-order` across the repo: all 71 changelogs pass. Both heading forms this repo uses are parsed: `## [1.2.3]` (plugins) and `## 1.2.3 — date` (conventions). Comparison is `sort -rV`. ## Related No linked issue — this is the preventive half of #1758, which fixed the instance. Refs #1758 Refs #1686 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
docs/conventions/upstream-drift/(README + CHANGELOG 1.0.0) as the owner doc for theverification-stamp + recheck-trigger pattern previously practiced in five-plus docs-level places
under three names with no owner — closing the convention-registry one-owner-per-concern violation.
docs/conventions/<name>/directory with README + CHANGELOG, a versioning section, an adopterstable, and a registry row in
docs/PLUGIN-PHILOSOPHY.md§Convention registry (the shapehook-config-delivery, loop-lane, and topic-docs already use); this doc matches it rather than
standing up a parallel form.
melodic-software/standardsconventions/engineering/documentation-and-citations.md§"Time-bound external claims need arecheck trigger", which already names the concept; a repo-level owner doc renaming the rule it
specializes would fork the vocabulary one level up. It is also the majority name in the fleet and
the
## Recheck triggersheading the docs-hygiene audit-noise section-exemption list alreadyrecognizes. "Revisit trigger", "re-derivation trigger", and "What would reopen it" become
superseded synonyms that migrate on touch; history (CHANGELOGs, ADRs, dated audit records) is
never rewritten.
date, trigger), the observability bar, the date-is-never-authority rule, the drift-signal finding
(no
ETag, no per-pageLast-Modifiedon the docs raw-markdown endpoints — re-verified2026-07-26 by header inspection — so content hashing is the only viable mechanical signal; hash
store deferred with its own recheck trigger), and the enforceability classification per the
standards
enforceability-tiers.mdrouting rule (presence check deterministic-but-deferred;observability and has-it-fired reasoning-only, the latter detect-then-judge once a hash store
exists).
intact:
hook-config-delivery(already-canonical heading gains the citation),ecosystem-commands("Revisit triggers"),loop-lane("Re-derivation triggers"; its restatedgeneric rationale moves to the owner doc),
topic-docs("What would reopen it"),PLUGIN-PHILOSOPHY(component-stances staleness disclaimer + new registry row),OFFICIAL-DOCS(staleness warning),
MIGRATION-PLAYBOOK(eleven "Revisit trigger" labels across the decisionrecords, including two that wrap across lines). The four touched convention changelogs carry
docs-only patch entries (1.0.1, 1.2.3, 3.0.1, 2.3.1).
never rewritten — stated in the owner doc);
docs/topics/**(excluded by thecontract-slice-prune gate); plugin-internal instances (most already use the canonical heading;
the rest adopt on touch, avoiding a fleet-wide version-bump cascade for a rename).
Test plan
npx markdownlint-cli2 <13 changed .md files>—Summary: 0 error(s).bash scripts/check-changelog-parity.sh --check-bump origin/main— pass ("Every plugin whoseversion changed vs origin/main has a '## []' CHANGELOG.md entry." — no plugin paths in
this diff).
bash scripts/check-contract-slice-prune.sh --check-diff origin/main— pass ("this change setleaves no path under docs/topics/").
bash scripts/check-skill-portability.sh origin/main— pass ("No skill files in scope").scripts/check-shell-portability.sh— not run: no shell files touched (markdown-only diff).lychee --config lychee.toml --offline <13 changed files>—0 Errors(offline lane;include_fragments = "full"so relative links and anchors, including the new#convention-registrylinks, resolve; external URLs are the online advisory lane's concern).curl -sIon threecode.claude.com/docs/en/*.mdendpoints — noETagheader;Last-Modifiedmatched eachrequest's own fetch time (a serving stamp, not a per-page content date).
one on convention-registry conformance / single ownership, one on instance-inventory
completeness. Both returned CONFIRMED overall, with two non-blocking findings fixed in the second
commit: the owner doc now explicitly declares its deliberate tightening of the org standard's
trigger-form list (a bare date does not qualify here) instead of tightening it silently, and the
as-of-record rule restatements in PLUGIN-PHILOSOPHY and loop-lane were cut to pointers so the
owner doc carries the only full statement. Lint and link checks re-run green after the fix.
Related
Closes #1638