Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docs/conventions/upstream-drift/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,40 @@ Notable changes to the upstream-drift contract (SemVer). Changing a required par
name, or an enforceability verdict is a major bump; additive guidance is a minor bump; docs-only
clarification is a patch.

## 1.4.0 — 2026-08-12

Closes the **adoption** gap rather than a design one: the contract already owned verification
stamps, recheck triggers, and the rule that the name binds on touch, but plugins restating upstream
harness facts in bare prose had no route into the Adopters table and nothing made a stale claim
surface ([#2273](https://github.com/melodic-software/claude-code-plugins/issues/2273)). Additive
guidance; no required part, canonical name, or enforceability verdict changed.

- **The Adopters table now says how a post-1.0.0 row gets there, and what disqualifies one.** The
preamble read "Migrated at this contract's 1.0.0", which any appended row would have quietly
falsified. It now separates the migrated rows from later on-touch adoptions and requires each
later row to name the release that added it. It also states the bar the third column already
implied but never wrote down: **a surface is tabled only once it conforms**, so a carrier known to
be unstamped is a tracked issue rather than a row. That column is a promise to a reader, and
tabling an unstamped surface would assert exactly what the reader would then not get.
- **The fleet's open carriers are recorded where that rule sends them.** A sweep of `plugins/**` for
surfaces stating an upstream harness behaviour with no source, date, or trigger found 12 carriers
across 11 plugins, filed with quoted lines at
[#2297](https://github.com/melodic-software/claude-code-plugins/issues/2297) — along with the
files checked and found *conforming*, and the sweep's own limitation (a file-level citation gate
under-represents mixed files, so the list is a lower bound and says so). None is tabled here.
- **An adoption CI gate is deferred, recorded as a decision with its own trigger.** The
load-bearing finding is that the check §Enforceability already names — flag a `Verified <date>`
with no trigger — **would not have caught the case that prompted the question**
([#2207](https://github.com/melodic-software/claude-code-plugins/issues/2207)): that surface
carried no stamp at all, so a stamp-anchored grep had nothing to match. The named check is shaped
for a half-conforming record; the failure that ships is the zero-part one, and separating an
upstream restatement from an in-repo fact is a judgment about meaning — reasoning-only under the
tiers doc. A harness-vocabulary grep fires on every correct citation too, and a gate that forces
routine suppression trains authors to bypass it. Recorded with a basis and an event trigger — a
third unstamped carrier reaching `main`, or a demonstrated detector needing no suppression list —
so the deferral expires on evidence rather than on a date. The existing named-not-built check and
its own build trigger are unchanged.

## 1.3.0 — 2026-08-11

Closes two holes in [§Reading the basis — the fetch route](README.md#reading-the-basis--the-fetch-route)
Expand Down
43 changes: 42 additions & 1 deletion docs/conventions/upstream-drift/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,50 @@ Classified per `melodic-software/standards` `conventions/engineering/enforceabil
| The trigger clears the observability bar | **Reasoning-only** — whether an event is decidable from evidence is a judgment about meaning. |
| A trigger has fired | **Reasoning-only** today; **detect-then-judge** if a hash store lands — the hash mismatch flags, and judgment decides whether the page change touches the claim, because a changed page is not a changed fact. |

### Recorded decision — an adoption gate is deferred, and the check named above would have missed the case that prompted it

**Decided 2026-08-12 UTC: no CI gate is built for adoption of this convention, in either candidate
shape.** Recorded as a decision rather than left implicit, because this repo's `*-gate` CI pattern
is the standing precedent for promoting a convention to a check and the question was asked directly
([#2273](https://github.com/melodic-software/claude-code-plugins/issues/2273)).

The premise that settles it: the candidate check named in the table above — *flag any
`Verified <date>` line or row whose surface states no trigger* — **would not have caught
[#2207](https://github.com/melodic-software/claude-code-plugins/issues/2207)**, the finding that
prompted the question. That surface carried no stamp at all, so a stamp-anchored grep had nothing to
match on. The named check is shaped for a *half-conforming* record; the failure that actually ships
is the *zero-part* one. It therefore stays named-not-built on its own build trigger, unchanged, and
is not evidence that mechanization covers this class.

The zero-part shape has no deterministic check available. Deciding whether a sentence restates an
upstream-owned specific — as against an in-repo fact, a description of the surface's own behaviour,
or ordinary prose — is a judgment about meaning, which is **reasoning-only** under the tiers doc. A
grep for harness vocabulary (`PostToolUse`, `${CLAUDE_*}`, `settings.json`, and so on) fires on
every correct citation and every in-repo mention alike, and a gate whose false-positive rate forces
routine suppression trains authors to bypass it — worse than no gate, because it converts a real
signal into noise with an approved silencer.

- **Basis** — `melodic-software/standards` `conventions/engineering/enforceability-tiers.md` (the
reasoning-only tier and the worth-mechanizing routing rule), plus the worked instance above.
- **Recheck trigger** — a third unstamped upstream-fact carrier reaches `main` after this decision
(two are already on the record: `plugin-quality`, corrected in its 0.4.0, and `architecture`,
whose false claim was removed in its 0.5.1), **or** a detector is demonstrated that separates an
Comment thread
kyle-sexton marked this conversation as resolved.
upstream restatement from an in-repo one without a suppression list. Either event reopens the
shape question; neither is a date.

## Adopters

Migrated at this contract's 1.0.0 to the single name, each citing this doc with content intact.
The rows below were migrated at this contract's 1.0.0 to the single name, each citing this doc with
content intact. **A row added after 1.0.0 is a surface that adopted on touch** — the mechanism the
note under the table already requires — and names the release that added it, so the table never
implies a surface was migrated at 1.0.0 when it was not.
Comment thread
kyle-sexton marked this conversation as resolved.

**A surface is tabled only once it actually conforms.** The third column is a promise to a reader
about what they can rely on, so a carrier *known* to be unstamped belongs in a tracked issue, never
in a row: tabling it would assert the very thing the reader would then not get. The fleet's open
carriers are recorded that way in
[#2297](https://github.com/melodic-software/claude-code-plugins/issues/2297).

The rows are not all the same thing, and the table says which is which. A **conforming record**
carries the four required parts for an upstream-derived claim or decision. A **named trigger**
shares the canonical name, the observability bar, and
Expand Down