Skip to content

docs(conventions): add upstream-drift owner doc for verification stamps and recheck triggers - #1686

Merged
kyle-sexton merged 10 commits into
mainfrom
docs/1638-upstream-drift-owner-doc
Jul 29, 2026
Merged

docs(conventions): add upstream-drift owner doc for verification stamps and recheck triggers#1686
kyle-sexton merged 10 commits into
mainfrom
docs/1638-upstream-drift-owner-doc

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

Summary

  • Adds docs/conventions/upstream-drift/ (README + CHANGELOG 1.0.0) as the owner doc for the
    verification-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.
  • Placement reasoning: the repo's established shape for a cross-plugin convention is a
    docs/conventions/<name>/ directory with README + CHANGELOG, a versioning section, an adopters
    table, and a registry row in docs/PLUGIN-PHILOSOPHY.md §Convention registry (the shape
    hook-config-delivery, loop-lane, and topic-docs already use); this doc matches it rather than
    standing up a parallel form.
  • Canonical name: "recheck trigger" — adopted from melodic-software/standards
    conventions/engineering/documentation-and-citations.md §"Time-bound external claims need a
    recheck 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 triggers heading the docs-hygiene audit-noise section-exemption list already
    recognizes. "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.
  • The owner doc fixes the four required parts of a conforming record (claim/decision, basis, as-of
    date, trigger), the observability bar, the date-is-never-authority rule, the drift-signal finding
    (no ETag, 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 recheck trigger), and the enforceability classification per the
    standards enforceability-tiers.md routing rule (presence check deterministic-but-deferred;
    observability and has-it-fired reasoning-only, the latter detect-then-judge once a hash store
    exists).
  • Migrates the existing instances to the single name, each citing the owner doc with content
    intact: hook-config-delivery (already-canonical heading gains the citation),
    ecosystem-commands ("Revisit triggers"), loop-lane ("Re-derivation triggers"; its restated
    generic 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 decision
    records, 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).
  • Deliberately not migrated: ADR sections, CHANGELOG history, and dated audit records (history is
    never rewritten — stated in the owner doc); docs/topics/** (excluded by the
    contract-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 whose
    version 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 set
    leaves 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-registry links, resolve; external URLs are the online advisory lane's concern).
  • Empirical re-verification of the recorded drift-signal finding: curl -sI on three
    code.claude.com/docs/en/*.md endpoints — no ETag header; Last-Modified matched each
    request's own fetch time (a serving stamp, not a per-page content date).
  • Two independent fresh-context verifier subagents (reasoning withheld, briefed to refute):
    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

kyle-sexton and others added 2 commits July 26, 2026 21:33
…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

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 56s —— View job


Review — docs(conventions): add upstream-drift owner doc

  • Gather context and understand the request
  • Read the new upstream-drift convention files
  • Read migrated convention files (ecosystem-commands, hook-config-delivery, loop-lane, topic-docs)
  • Read updated cross-cutting docs (MIGRATION-PLAYBOOK, OFFICIAL-DOCS, PLUGIN-PHILOSOPHY)
  • Verify structural conformance with existing convention patterns
  • Check naming consistency and cross-references
  • Post review findings

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 checked

Structural conformance. The new upstream-drift/ directory follows the established convention-doc shape exactly: ## Boundary, ## Required parts, ## Versioning, ## Adopters, and ## External authority match the pattern in hook-config-delivery and siblings. The convention-registry row in PLUGIN-PHILOSOPHY.md is correct (same table, same format). ✅

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:

  • ../upstream-drift/README.md from ecosystem-commands/, hook-config-delivery/, loop-lane/, topic-docs/ — all correct.
  • conventions/upstream-drift/README.md from docs/PLUGIN-PHILOSOPHY.md and docs/OFFICIAL-DOCS.md — correct.
  • ../../PLUGIN-PHILOSOPHY.md#convention-registry from the new owner doc — resolves correctly. ✅

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 docs/topics/** (contract-slice-prune gate). Plugin-internal instances adopt on touch. These exclusions are stated in the owner doc and are consistent with the repo's own conventions. ✅

Adopters table completeness. The seven rows in upstream-drift/README.md §Adopters match the seven surfaces migrated in the diff. ✅


One minor note

MIGRATION-PLAYBOOK: Convention-seam and unused-component sections lack a citation.

The "Deferred surfaces" intro sentence carries the one link to the owner doc — [recheck trigger](conventions/upstream-drift/README.md) — which is the correct pattern for a section that lists multiple triggers. But two other sections in the same long document — ## Unused official plugin components — decision record (line 1337) and ## Convention-seam ratification & the shared-identity limitation (line 1467) — have renamed **Recheck trigger:** labels with no link and no local intro that links. A reader who lands directly on either of those sections encounters the term without a pointer to its meaning.

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 **Recheck trigger:** occurrence in each of those two sections would help future readers. Worth a follow-up or a quick fix before merge, but not a blocker.


Observations (non-blocking)

  • topic-docs uses singular "Recheck trigger" while other convention docs use the plural "Recheck triggers" for their section labels. This is intentional — there is one trigger in that section vs. multiple elsewhere — but the docs-hygiene audit-noise exemption list explicitly keys on the plural heading ## Recheck triggers. If that exemption check is exact-match, the singular form in topic-docs (which is prose, not a heading) won't trip it — just worth confirming the exemption works on the inline-bold form too.

  • hook-config-delivery/CHANGELOG.md uses ## 1.0 for the initial version and ## 1.0.1 for the bump. Strictly 1.0 is not valid SemVer (missing patch segment); 1.0.0 would be canonical. This pre-exists this PR but is now surfaced by the new entry sitting next to it.

@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: 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".

Comment thread docs/conventions/upstream-drift/README.md Outdated
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>
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

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

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 17s —— View job


Review — 31294f6 (adopter-table fix)

  • Gather context and understand the request
  • Read the updated adopter table in upstream-drift/README.md
  • Verify the classification schema is internally consistent and accurate
  • Check cross-references remain correct after the change
  • Post review findings

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 changed

The adopter table (upstream-drift/README.md lines 120–136) was reworked to distinguish two row classes:

  • Conforming record — carries all four required parts for an upstream-derived claim (basis, date, trigger, claim).
  • Named trigger — shares the canonical name, observability bar, and firing procedure, but guards an in-repo decision; the four-part requirement does not bind here because there is no upstream-owned source to restate.

Classification accuracy check

I verified each row's claim against the actual documents:

Row Classified as Verified
hook-config-delivery Conforming Facts table carries per-fact basis, date, and event triggers. ✅
loop-lane Conforming Dated stamps with stated triggers; firings go to its changelog. ✅
PLUGIN-PHILOSOPHY component stances Conforming Per-row linked page + date + standing re-fetch-before-acting disclaimer. The standing rule is a valid trigger (the observability bar explicitly accepts "a recurring occasion such as each fleet audit"). ✅
OFFICIAL-DOCS Conforming Same shape as component stances: link + date + standing re-fetch rule. ✅
MIGRATION-PLAYBOOK Mixed Dated component-decision records cite upstream bases ✅; org-internal ratification record has no upstream basis — named trigger only ✅.
ecosystem-commands Named trigger Undated deferral, no external basis. Correctly excluded from the four-part claim. ✅
topic-docs Named trigger In-repo source-hoisting decision. Correctly excluded. ✅

CHANGELOG handling

The clarification is appended to the 1.0.0 entry rather than bumping to 1.0.1. This is correct: the four required parts are unchanged; only the accuracy of the adopter description was fixed. No adopter needs to change its implementation; no version signal is needed.

No new issues

The prior review's minor note (MIGRATION-PLAYBOOK sections lacking links at their first **Recheck trigger:** occurrence) was not addressed here, which is consistent with the commit's narrow scope. It remains a non-blocking follow-up.


@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: 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".

Comment thread docs/conventions/upstream-drift/README.md Outdated
Comment thread docs/conventions/upstream-drift/README.md Outdated
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Merge-lane thread worker claiming PR #1686 for one cycle: reviewing the 3 unresolved Codex review threads on docs/conventions/upstream-drift/README.md at head 31294f6f.

… 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

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 4s —— View job


Merge-lane thread review — 3 Codex P2s on upstream-drift/README.md

  • Gather context
  • Read docs/conventions/upstream-drift/README.md at HEAD (15b29e1)
  • Verify Codex thread 1: "Align declared adopters with the contract boundary"
  • Verify Codex thread 2: "Define a decidable threshold for the hash-store trigger"
  • Verify Codex thread 3: "Preserve the internal-trigger exemption during on-touch migration"
  • Post verdict

Verdict: All three Codex P2 threads are resolved at HEAD (15b29e1). One non-blocking observation noted below.


Thread 1 — Align declared adopters with the contract boundary (a37386f31294f6f)

Previously confirmed resolved by the prior cycle's review of 31294f6f. At HEAD, the adopter table is unchanged from that commit: it distinguishes conforming records (four required parts, upstream-derived) from named triggers (canonical name + observability bar + firing procedure; guards an in-repo decision). ecosystem-commands and topic-docs are correctly classified as named-trigger-only rows. The contract was not widened. ✅


Thread 2 — Define a decidable threshold for the hash-store trigger (31294f6f15b29e1)

Codex objected that the original trigger phrase ("stamped claims accumulate past what manual re-fetch at audit time covers") provided no count, cadence, or threshold a reader could check.

Commit 15b29e1 replaces it (line 104–106):

a stale stamp causes a real defect a stored hash would have flagged, or a fleet audit completes without re-fetching every stamped claim in its scope

This is a decidable event: after each fleet audit, a reader can check whether every stamped surface was re-fetched; if any were skipped, the trigger has fired. It also matches the observability bar's own example ("a recurring occasion such as each fleet audit"). The new phrasing passes the bar. ✅


Thread 3 — Preserve the internal-trigger exemption during on-touch migration (31294f6f15b29e1)

Codex objected that the blanket on-touch instruction required all living synonyms to adopt "required parts," forcing implementers touching ecosystem-commands or topic-docs to either invent an external basis/as-of date or violate the rule — a direct conflict with the exemption in the adopter table.

Commit 15b29e1 splits the instruction into two tiers (lines 138–144):

adopt the canonical name, the observability bar, and the firing procedure the next time they change; a surface restating an upstream-owned specific additionally adopts the required parts.

This aligns exactly with the adopter table's classification: all living surfaces adopt the name, bar, and procedure; only those restating upstream-owned specifics also carry the four-part record. ecosystem-commands and topic-docs are correctly excluded from the four-part obligation. ✅


Non-blocking observation — CHANGELOG not updated for the 15b29e1 clarifications

The upstream-drift/CHANGELOG.md 1.0.0 entry was amended in 31294f6f to add the adopter-table distinction bullet (correctly logged as a pre-ship clarification rather than a 1.0.1 bump). But the two clarifications landed in 15b29e1 — making the hash-store trigger decidable and splitting the on-touch migration rule — have no corresponding entry. By the same pattern, they belong either appended to the 1.0.0 entry or as a 1.0.1 patch entry before merge. Not a thread finding, and the versioning section says "docs-only clarification is a patch" so either form is correct — just worth a quick line before ship.


@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: 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".

Comment thread docs/conventions/upstream-drift/README.md Outdated
Comment thread docs/conventions/upstream-drift/README.md Outdated
Comment thread docs/conventions/upstream-drift/README.md Outdated
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

🤖 Lane claim released — babysit-loop cycle melo-lap-001-merge-20260727T125629Z complete for this PR. No lane work in flight here; another lane may take it. Cycle summary: #1214

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

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 3s —— View job


Review — 4bf6923 (firing-procedure fix)


Verdict: All three Codex P2 findings resolved. Ready to merge.

The commit message correctly diagnoses the root defect: a single-kind firing procedure was written before the adopter table grew multiple kinds. 4bf6923 fixes that uniformly, and a live re-verification during the P2 fix surfaces a factual update in MIGRATION-PLAYBOOK worth calling out explicitly.


P2 #1 — Define a firing path for stamp-less triggers ✅

## When a trigger fires now has two explicit branches:

  • Four-part record: re-fetch cited basis, re-derive, refresh as-of date.
  • Named trigger guarding an in-repo decision: re-derive from the in-repo state the trigger names, record outcome durably. No cited basis to re-fetch, no as-of date to refresh.

The adopter table's intro now links to "its own firing procedure" for named-trigger rows, so a reader landing on ecosystem-commands or topic-docs has a direct path to the correct procedure. The two kind labels in the table are self-consistent with the two bullets in the procedure section.

P2 #2 — Exempt read-time validation from durable refreshes ✅

### Read-time validation is not a firing draws the line cleanly: a lookup that finds no drift obliges no edit; divergence, never the lookup, is what fires. This matches the update to the PLUGIN-PHILOSOPHY and OFFICIAL-DOCS staleness disclaimers, which now both explicitly state "a fetch that diverges from a row is that row's recheck trigger." The adopter table rows for both surfaces are updated to call the re-fetch-before-acting rule "read-time validation" and name divergence-at-fetch as the stated trigger. The three passages are now consistent.

P2 #3 — Add the missing basis for the workflow-engine decision ✅ (with a substantive finding)

The re-verification found more than a missing citation. The workflow-engine record's "no-native-slot" premise is now explicitly refuted by current docs: plugins can now ship workflow scripts via a workflows/ directory or the workflows manifest field, backed by two cited URLs. The deferral was re-derived onto the stronger remaining basis (the usage question: do the engines still earn their keep?), and the recheck trigger is updated to migrate through the native slot rather than the now-obsolete scriptPath dispatch path. This is a clean re-derivation — the deferral stands, the record is now checkable when the trigger fires.

CHANGELOG ✅

The 1.0.0 entry now carries the firing-procedure-per-kind bullet (added in 4bf6923). The hash-store trigger decidability and on-touch migration split from 15b29e1 are still not called out as separate CHANGELOG bullets — the same non-blocking gap the prior cycle noted. Given that all of these are pre-1.0.0 clarifications accumulated before first publish, the gap is cosmetic. The drift-signal and adopter-table entries in the existing bullet set describe their substance implicitly.

No new issues introduced

All five files changed in 4bf6923 are within the scope set by prior commits. No cross-references broke; the adopter table accurately describes each row's kind and the procedure it uses.


@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: 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".

Comment thread docs/MIGRATION-PLAYBOOK.md Outdated
…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

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 18s —— View job


Review — dc050fc (adopter-claims gap fix)

  • Gather context and read the PR diff
  • Read upstream-drift/README.md at HEAD
  • Check the Codex P2 about workflows component index (OFFICIAL-DOCS + PLUGIN-PHILOSOPHY)
  • Verify dc050fc scope and correctness
  • Post findings

Verdict: dc050fc is correct. One Codex P2 remains open.

The commit commit message accurately describes the two verifier gaps it closes: the three-kind dichotomy issue (now terminal exclusions are named), the missed inline "Revisit iff / if" forms in the shared-code record (now labeled and URL-backed), and the named-trigger firing procedure's "in-repo state" constraint (now universal). Each fix is surgical and accurate.


What dc050fc changed and whether it's right

Adopters table — third kind (README.md:155)

The MIGRATION-PLAYBOOK row now reads: "Mixed — the dated component-decision records cite upstream bases and conform; the org-internal records (e.g. the ratification record) are named triggers; the skill-quality retrofit record is a third kind, terminal exclusions that state 'no recheck trigger' by design — decided out, so nothing fires."

This is accurate. The two-kind dichotomy the prior table implied did not cover records explicitly designed to have no trigger. The skill-quality retrofit record is genuinely a third category, and naming it explicitly prevents a future auditor from treating it as a conformance gap. ✅

Inline "Revisit iff / if" → **Recheck trigger:** in shared-code record (MIGRATION-PLAYBOOK.md:1254, 1263)

The two inline forms now carry proper labeled triggers with bare URLs instead of page-plus-section prose references. The adopter table intro at upstream-drift/README.md:140 claimed adopters "migrated to the single name"; these were missed in the earlier rename pass. The fix is complete and accurate. ✅

Knowledge-corpus pulumi-github missing trigger (MIGRATION-PLAYBOOK.md:1395)

Now carries **Recheck trigger:** a pulumi-github release notes LFS support on Repository, or the pinned provider version moves past v6.14.0 → re-derive the IaC-vs-content-side call. This is a well-formed trigger — the firing event is decidable from a release notes check. ✅

Named-trigger firing procedure (README.md:93-98)

Changed "re-derive the decision from the in-repo state the trigger names" → "re-derive the decision from the state the trigger names — the decision guarded is in-repo; the firing event can live anywhere, upstream included." This resolves the self-contradiction where two adopters name upstream/org state in their triggers. The clarifying note — "A re-derivation that ends up restating an upstream specific adopts the four required parts in the refreshed record" — is a correct and important addition: if a named-trigger firing surfaces an upstream fact, it converts the refreshed record to a four-part conforming record. ✅

hook-config-delivery CHANGELOG bump: 1.0.11.1.0

The prior cycle's review called the 1.0.1 bump "correct." dc050fc correctly overrides that: the hook-config-delivery versioning rule at the top of its CHANGELOG says "adding a channel, a fact, or a recheck trigger additively is a minor bump." Adding the facts 7–8 trigger is additive; it was never present before. 1.1.0 is the right version. The prior cycle missed this distinction. ✅


Remaining open item — Codex P2 on workflows component index

This finding was raised on commit 4bf6923 and remains unaddressed at HEAD.

docs/OFFICIAL-DOCS.md component table (line 22) opens with "One row per plugin component type" — but the Workflows (workflows/) component is absent from the table. The Workflows doc page appears only in the "Authoring" table at line 55. The MIGRATION-PLAYBOOK re-verification in 4bf6923 explicitly confirmed that plugins now ship workflow scripts via workflows/ (line 1325), so the component exists and the component table is now incomplete.

docs/PLUGIN-PHILOSOPHY.md component stances table (line 125) likewise has no Workflows row. Every other recognized component has a stance and rationale; a reader following the native-first guidance has no verdict for whether to adopt workflows/.

Both gaps were surfaced by the 4bf6923 Codex P2 and remain open. They don't block the upstream-drift convention correctness, but they're the stated outstanding P2 from the previous review cycle. Adding a Workflows component row and stance before merge closes the loop the playbook re-verification opened.


Observations (non-blocking)

  • The upstream-drift CHANGELOG 1.0.0 entry absorbs all pre-publication clarifications (three rounds of verifier fixes) rather than growing patch entries. This is consistent with the prior cycle's reasoning that these are pre-1.0.0 clarifications. The entry now accurately describes all three kinds and the corrected firing procedure. ✅
  • The Boundary section edit ("records its rechecks' drift outcomes" instead of "records the outcome of its rechecks") correctly narrows the claim to match the firing procedure: refreshing a date with no verdict change is no changelog entry, so only drift outcomes land there. Small but correct. ✅

@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: 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".

Comment thread docs/conventions/upstream-drift/README.md Outdated
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

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 47s —— View job


Review — 656e2e9 (workflows component row)

  • Gather context and understand the request
  • Read OFFICIAL-DOCS.md at HEAD to verify Workflows row
  • Read PLUGIN-PHILOSOPHY.md at HEAD to verify Workflows stance
  • Check MIGRATION-PLAYBOOK changes for correctness
  • Check remaining Codex P2 from dc050fc review
  • Post review findings

Verdict: Correct. Closes the last verified open P2. The commit resolves the workflows component index P2 that was the outstanding item from the dc050fc review cycle. One Codex observation from dc050fc remains (noted below), but it is out of scope for the upstream-drift convention.


What 656e2e9 changes and whether it's right

docs/OFFICIAL-DOCS.md — Workflows component row (line 37)

Added | Workflows (\workflows/`) | https://code.claude.com/docs/en/workflows | 2026-07-27 |` at the correct position in the table. The prose note above the table (lines 26–30) correctly explains why Workflows has no dedicated per-component section in the Plugins reference — the component lives in the standard-layout and file-locations tables there — so a reader isn't left wondering why the pattern breaks. The Authoring table's duplicate entry (line 60) gets its verified date updated to match. ✅

docs/PLUGIN-PHILOSOPHY.md — Workflows stance (line 130)

Stance is Adopt on need, not Wait. The rationale is correct on all three claims:

  • Not Wait: Workflows carry no experimental key (the Wait criteria), and the deferred engines are a named candidate with a live trigger — the gap is identified, not hypothetical.
  • Availability constraint: paid-plan gating + disableWorkflows / CLAUDE_CODE_DISABLE_WORKFLOWS + org-wide managed-settings disable means a consumer could have no /plugin:name at all — mirroring the bin/ row's never-make-it-load-bearing rule exactly.
  • None ship today: accurate to the fleet state.

The pointer to MIGRATION-PLAYBOOK.md#deferred-surfaces--decision-record-2026-07-12 for the named workflow-engine candidates is correct and closes the loop opened by the 4bf6923 re-verification. ✅

docs/MIGRATION-PLAYBOOK.md — citation split and unused-components preamble

The workflow-engine citation now has three separate anchors, each documenting the specific fact it backs:

  • #standard-plugin-layout → the workflows/ directory slot
  • #component-path-fields → the workflows manifest field
  • #distribute-a-workflow-in-a-plugin → plugin-namespaced invocation

This resolves the weak "two URLs for two facts" pattern the commit message calls out. ✅

The unused-components preamble scope correction ("this is that evaluation, not an index of every component the marketplace does not use") is accurate and prevents a reader from treating the section as the authoritative stance index. The pointer to PLUGIN-PHILOSOPHY.md#component-stances is correct. ✅


Codex P2 from dc050fc review — **Re-trigger:** at MIGRATION-PLAYBOOK.md:1091

This observation remains unaddressed at HEAD. The Codex P2 raised on dc050fc noted that the security-review acceptance record (line 1091) uses **Re-trigger:** rather than the canonical **Recheck trigger:**.

On review, this appears to be a conceptually distinct use. The upstream-drift convention owns verification stamps on external claims — claims citing an upstream-owned source with an as-of date and a drift trigger. The security-review **Re-trigger:** identifies conditions that reopen a plugin-acceptance review (re-introducing Bash/PowerShell pre-approval, shipping the deferred hook, adding an MCP surface) — not an upstream staleness check. It is not among the three synonyms the owner doc migrates on touch ("revisit trigger", "re-derivation trigger", "what would reopen it"), and the adopter table does not classify security-review re-triggers as in-scope records.

Two mitigations are available, neither blocking:

  1. Leave **Re-trigger:** as-is with a brief note in the text that it is not an upstream-drift trigger (avoids false audit hits, adds one sentence).
  2. Rename to **Recheck trigger:** anyway for uniform label scan results, accepting that the label's domain differs from the convention's scope.

Either choice is defensible. Worth noting for the author to decide, but not a P2 under this PR's scope.


Summary

656e2e9 correctly closes the last verified open P2 from the prior review cycle. The Codex observation about **Re-trigger:** at line 1091 is outside the upstream-drift convention's scope as defined by its own adopter table and migration rules. The PR is ready to merge.

View job

@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: 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".

Comment thread docs/MIGRATION-PLAYBOOK.md Outdated
Comment thread docs/MIGRATION-PLAYBOOK.md Outdated
…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

claude Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 39s —— View job


Review — 7b4feffea (fourth-synonym + LFS basis + symlink trigger fix)

  • Gather context and read the PR diff at HEAD
  • Verify Codex P2: "Migrate the remaining security-review trigger label" (**Re-trigger:****Recheck trigger:**)
  • Verify Codex P2: "Include upstream symlink behavior in the trigger"
  • Verify Codex P2: "Cite a re-fetchable basis for the LFS decision"
  • Check owner-doc inventory claim update ("four names" vs "three")
  • Check CHANGELOG handling for 7b4feffea clarifications
  • Post findings

Verdict: All three Codex P2s resolved. Ready to merge.

This commit closes the last open items from the 656e2e9 review cycle. The prior cycle's review suggested **Re-trigger:** was "conceptually distinct" and might not need migration — 7b4feffe correctly refutes that: it is a fourth synonym for the same kind of trigger (a named trigger on an in-repo decision), and the owner doc's motivating claim ("five-plus places under three names") was itself falsified by leaving it unaddressed.


P2 #1 — Migrate the remaining security-review trigger label ✅

MIGRATION-PLAYBOOK.md:1091–1093 is now:

Recheck trigger (upstream-drift — a named trigger on an in-repo decision): re-introducing a Bash or PowerShell pre-approval, shipping the deferred validating PreToolUse hook, or adding an MCP surface each re-opens this review.

Three improvements over the prior **Re-trigger:** label: canonical name, link to owner convention, and explicit kind declaration. The kind statement is important — it tells a future updater that no basis or as-of date is owed when this trigger fires, because the decision guarded is in-repo. The three stated events (re-introducing a pre-approval, shipping the hook, adding an MCP surface) are all in-repo observable. ✅

The four companion updates are all consistent:

  • upstream-drift/README.md:8 — "four names" (not three) ✅
  • README.md:11–12"re-trigger" listed in the inventory alongside its surface ✅
  • README.md:156 — MIGRATION-PLAYBOOK adopter row's "Was" cell updated to include "Re-trigger" on the plugin-acceptance review record
  • README.md:160 and CHANGELOG.md:15"re-trigger" added to binds-on-touch list and superseded-synonym list ✅

P2 #2 — Include upstream symlink behavior in the trigger ✅

MIGRATION-PLAYBOOK.md:1264–1267:

Recheck trigger: the dev loop stops depending on --plugin-dir, the documented --plugin-dir / local-path handling changes so marketplace symlinks are no longer skipped (the upstream premise this deferral rests on), or the Windows constraint lifts.

The new third disjunct closes the gap: the deferral rested on an upstream-owned premise (symlinks skipped for --plugin-dir installs, cited to #share-files-within-a-marketplace-with-symlinks) that neither of the prior two disjuncts covered. Without this disjunct, upstream could remove that premise without firing the trigger — the exact failure mode this convention exists to prevent.

The parenthetical ("the upstream premise this deferral rests on") is useful: it tells the reader why this disjunct exists and which part of the record to re-derive if it fires. ✅

The as-of date on the shared-code record is unchanged, consistent with the owner doc's rule that adding a missing disjunct is record completeness, not a re-derivation. ✅


P2 #3 — Cite a re-fetchable basis for the LFS decision ✅

MIGRATION-PLAYBOOK.md:1402–1406:

Basis: the provider schema at the pinned tag — https://raw.githubusercontent.com/pulumi/pulumi-github/v6.14.0/provider/cmd/pulumi-resource-github/schema.json, where github:index/repository:Repository declares 48 properties and 39 input properties, none matching lfs, and the document contains no case-insensitive lfs match at all (fetched and probed 2026-07-29; re-run the same fetch against the then-pinned tag when the trigger below fires).

All four required parts of a conforming record are now present:

  • Claim: Repository has no LFS property — present (implicit in the count + probe result)
  • Basis: pinned-tag raw schema URL — ✅ (immutable; the Pulumi Registry API-docs URL was correctly rejected because it doesn't version-pin and would drift off v6.14.0)
  • As-of date: 2026-07-29 for the basis fetch — ✅ (correctly separate from the decision date 2026-07-13; the commit message explains why collapsing them would overstate what the older date attests)
  • Recheck trigger: a pulumi-github release noting LFS support, or the pin moving past v6.14.0 — ✅ (decidable from release notes)

The "re-run the same fetch against the then-pinned tag when the trigger below fires" instruction is a correct and pragmatic addition: it tells an updater exactly how to reproduce the probe. ✅


CHANGELOG ✅

upstream-drift/CHANGELOG.md 1.0.0 entry: "re-trigger" added to the superseded-synonym list. Correct: no bump is needed because the convention contract (required parts, observability bar, firing procedure) is unchanged. The synonym list in 1.0.0 was incomplete; adding "re-trigger" is a factual correction of the entry, not a new convention decision. ✅

The symlink and LFS changes are record completeness fixes in MIGRATION-PLAYBOOK, not changes to the upstream-drift convention contract itself. They correctly carry no changelog entry in upstream-drift/CHANGELOG.md. ✅


No new issues

No cross-references broke. The three Codex threads from the dc050fc cycle that kyle-sexton marked resolved today (2026-07-29) are accurately resolved:

  • P2 on **Re-trigger:** → confirmed fixed ✅
  • P2 on upstream symlink behavior → confirmed fixed ✅
  • P2 on LFS re-fetchable basis → confirmed fixed ✅

The PR is structurally complete: one owner doc, one canonical name, seven adopter surfaces migrated and classified, all four required parts present in every conforming record, and every Codex P2 from all eight review cycles confirmed resolved.

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

claude Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 6s —— View job


Review — 86a31da (greppable label form fix)

  • Gather context and understand the request
  • Read the new commit diff and changed files
  • Verify the label-form decision and its rationale
  • Check consistency with adopter table and CHANGELOG
  • Post review findings

Verdict: 86a31da is correct. One remaining gap in the same family.

The fix is technically sound: the prior commit's label **Recheck trigger** (…): had the colon outside the closing **, so grep '\*\*Recheck trigger:\*\*' correctly found the file's nine other inline labels but silently missed this one. Moving the colon inside (**Recheck trigger:**) and pushing the citation and kind-declaration into the sentence that follows closes that gap without any information loss.

All 10 inline **Recheck trigger:** labels in MIGRATION-PLAYBOOK.md are now byte-identical. The change to upstream-drift/README.md is purely editorial line-wrapping with no content change.


Remaining gap — topic-docs/README.md:413 still uses the non-greppable form

The same colon-placement issue that 86a31da just fixed for MIGRATION-PLAYBOOK is still present in topic-docs/README.md:413:

**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)):
a canonical source under [`lib/`](../../../lib/)

The colon is outside the bold — grep '\*\*Recheck trigger:\*\*' misses it, for exactly the reason the commit message diagnoses. This label was introduced by this PR (renamed from "What would reopen it"), using the same **Recheck trigger** (…): form that was the defect in 7b4feffe for MIGRATION-PLAYBOOK. The commit's own description says "The label is now byte-identical to every sibling" — but topic-docs is a sibling that still doesn't match.

The fix is the same pattern 86a31da applied to MIGRATION-PLAYBOOK:

-**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)):
-a canonical source under [`lib/`](../../../lib/)
+**Recheck trigger:** an in-repo source-hoisting decision
+([upstream-drift](../upstream-drift/README.md)) — a canonical source under [`lib/`](../../../lib/)

Or, since topic-docs is a named-trigger row (no external basis), the kind-declaration is optional and the citation can stay parenthetical after the colon:

-**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)):
+**Recheck trigger** ([upstream-drift](../upstream-drift/README.md))**:**

No — the cleanest fix is moving the colon inside the bold and letting the parenthetical follow, matching the pattern 86a31da established. Fix this →

This doesn't affect the convention's correctness — the presence check is deferred — but the commit's own stated goal is uniform greppable forms, and this is the only inline label in the changed files that doesn't conform to it.


Summary

86a31da correctly closes the MIGRATION-PLAYBOOK enforceability gap. One analogous instance (topic-docs/README.md:413) uses the same pre-fix form and would be missed by the same grep. All prior Codex P2 threads remain resolved.

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

claude Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 4m 46s —— View job


Review — ddc747d (merge origin/main into docs/1638-upstream-drift-owner-doc)

  • Gather context and understand the request
  • Read current diff vs origin/main
  • Check topic-docs/README.md colon-placement gap from prior review
  • Read changed files at HEAD and verify merge conflict resolution
  • Post review findings

Verdict: One open finding — two non-greppable label instances in topic-docs/README.md, one pre-existing and one introduced by the merge. All prior Codex P2s remain resolved.


Merge commit quality

The ddc747d merge commit handled two structural conflicts and one semantic conflict correctly:

  • CHANGELOG conflicts — topic-docs 2.4.1 (rename entry) sits above main's 2.4.0 (ephemeral tier); loop-lane 3.1.1 (rename entry) sits above main's 3.1.0 (prompt-fresh patch). Both stay monotonic. ✅
  • Semantic conflict — main's ecae344 shipped a new **Re-derivation trigger.** label in topic-docs/README.md — a superseded synonym in a surface the adopter table advertises as migrated. The merge correctly renamed it to the canonical label with the owner-doc citation. ✅

Open finding — topic-docs/README.md has two non-greppable label forms

The upstream-drift convention's enforceability section (line 135) names **Recheck trigger:** (colon inside bold) as the greppable form needed for deterministic presence-checking. grep '\*\*Recheck trigger:\*\*' misses both of these:

Line 529 — pre-existing, flagged in the 86a31da review cycle, unfixed:

**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)):
a canonical source under [`lib/`](../../../lib/)

Colon is after the closing ** — grep misses it. Fix this →

Line 154 — introduced by the ddc747d merge, inheriting the sibling's non-greppable form:

**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)). An
upstream versioned interface for the scratchpad...

Period after the parenthetical, no colon inside bold — grep misses it. The merge commit message explains this was written "matching the sibling instance in the same file" — but that sibling (line 529) is itself non-greppable, so the match is consistent but wrong. Fix this →

Why this matters: the convention's own enforceability table says the presence check is deterministic "once stamps and triggers use greppable forms." The adopter table lists topic-docs as migrated. A grep over the repo for **Recheck trigger:** finds the MIGRATION-PLAYBOOK's 10 instances but returns zero for topic-docs — auditors following the enforcement guidance would see a false-clean result for this surface.

The fix pattern (same as 86a31da applied to MIGRATION-PLAYBOOK:1091):

-**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)):
+**Recheck trigger:** ([upstream-drift](../upstream-drift/README.md))
-**Recheck trigger** ([upstream-drift](../upstream-drift/README.md)). An
+**Recheck trigger:** ([upstream-drift](../upstream-drift/README.md)) An

All prior Codex P2s remain resolved ✅

Verified at HEAD:

Codex thread Status
Align declared adopters with the contract boundary (a37386f31294f6f) ✅ Adopter table unchanged; conforming vs named-trigger distinction preserved
Define a decidable threshold for the hash-store trigger (31294f6f15b29e1) ✅ "fleet audit completes without re-fetching every stamped claim in its scope" still the trigger
Preserve the internal-trigger exemption during on-touch migration (31294f6f15b29e1) ✅ Two-tier on-touch instruction unchanged
Define a firing path for stamp-less triggers (15b29e14bf6923) ✅ Per-kind procedure intact
Exempt read-time validation from durable refreshes (15b29e14bf6923) ✅ §Read-time validation is not a firing unchanged
Add missing basis for workflow-engine decision (15b29e1656e2e9) ✅ Three anchored URLs in MIGRATION-PLAYBOOK
Add workflows to the component index (4bf6923656e2e9) ✅ OFFICIAL-DOCS and PLUGIN-PHILOSOPHY rows unchanged
Include upstream symlink behavior in the trigger (656e2e97b4feffe) ✅ Third disjunct in shared-code trigger intact
Cite re-fetchable basis for LFS decision (656e2e97b4feffe) ✅ Pinned-tag raw schema URL + probe intact
Migrate the remaining security-review trigger label (dc050fc7b4feffe) **Recheck trigger:** at MIGRATION-PLAYBOOK:1092, greppable form

@kyle-sexton
kyle-sexton merged commit 8f4b2be into main Jul 29, 2026
31 checks passed
@kyle-sexton
kyle-sexton deleted the docs/1638-upstream-drift-owner-doc branch July 29, 2026 17:47
kyle-sexton added a commit that referenced this pull request Jul 29, 2026
…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>
kyle-sexton added a commit that referenced this pull request Jul 30, 2026
## 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>
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.

docs(conventions): upstream-drift re-derivation triggers are practiced in five places with no owner doc

1 participant