The defect
RQ-60-CANARY is in v0.60's scope, status implemented, and its evidence is on main — so every gate passes. Its deliverable shipped in v0.59.0, and v0.59.0's own release notes already credit it.
Measured (commit timestamps, git merge-base --is-ancestor):
2026-08-26 08:50 #1061 VCR-TIER-001 increment 1: canary gate over pseudo-op encoder expansions
2026-08-26 15:19 v0.59.0 tagged <- the canary gate is an ANCESTOR of this tag
2026-08-26 18:56 #1070 plan(v0.60): ... 8 artifacts <- scopes RQ-60-CANARY as v0.60 work
CHANGELOG.md, ## [0.59.0] section, line 63:
VCR-TIER-001 increment 1 — the pseudo-op expansion canary gate.
And RQ-60-CANARY's own description says "DELIVERED as PR #1061". Three artifacts cite #1021 — RQ-59-POPCNT (the instance fix), RQ-59-TIERCENSUS (the census), RQ-60-CANARY (the gate) — and all three shipped in v0.59.0, but the third is booked to v0.60.
Left alone, v0.60's release notes credit v0.60 with a capability released in v0.59.0, and the readiness query counts 8 artifacts where 7 are v0.60 work.
Why every existing gate is blind to it
scripts/status_evidence_check.py (RQ-60-FLIPCOUPLE, #1064) asks "does the declared evidence exist on main?" It does. It never asks "did that evidence arrive in THIS release?" An artifact whose evidence predates the previous tag is indistinguishable, to R2, from one delivered yesterday.
This is the recurring shape one tier up: the check is present, correct, and cannot fail on the defect it would need to catch.
A second, related disagreement — measured, 6 live instances
The checker derives an artifact's release from its file path; rivet's readiness query reads the release: field. Nothing asserts they agree. Across all 60 release artifacts on main:
file/field release MISMATCHES: 6
RQ-561-ZEROMEM file=release-v0.57.yaml field=v0.56.1
RQ-57-SENTINEL file=release-v0.57.yaml field=v0.56.2
RQ-57-BRTARGET file=release-v0.57.yaml field=v0.56.2
RQ-57-I32CONST file=release-v0.57.yaml field=v0.56.2
RQ-57-RULEINV file=release-v0.57.yaml field=v0.56.2
RQ-57-WCET2OPS file=release-v0.57.yaml field=v0.56.2
Today these are benign (both sides are < v0.60, so the version-gated rules treat them identically). The harmful direction is the one nobody has hit yet: an artifact parked in a pre-v0.60 file carrying release: v0.60 is EXEMPT from every >= v0.60 rule while rivet counts it in v0.60's scope — a silent bypass of R1/R5 rather than a cosmetic disagreement.
Proposed rules (both mechanical, both red-first-able)
- R7 — evidence must belong to the release. For an artifact in release vX.Y with a
contains:/file: signature, find the commit that introduced the signature (git log -S<literal> -- <path>, first-parent, oldest). If that commit is an ancestor of the v(X.Y-1) tag, the artifact is mis-scoped: red, with the tag named. Escape hatch matching the existing waiver discipline: an explicit shipped-in: vX.Z field with a written reason, so the correction is a visible diff rather than a silent re-book.
- R8 — the
release: field must equal the file's version, or carry the same explicit exemption. Dispose of the 6 above in the same PR (they look like real patch-release artifacts parked in the next minor's file — that is a legitimate practice that just needs saying out loud).
Disposition of RQ-60-CANARY itself
Proposed, and deliberately NOT a silent re-book: keep the artifact in v0.60 (its id, its commit subjects and its trace links all point there) and record on the artifact and in the v0.60 release notes that its code shipped in v0.59.0 — v0.60 carries only the traceability closure, not the capability. Moving an id numbered RQ-60-* into release-v0.59.yaml would break the R4 delivery-subject linkage and trade one attribution error for a worse one.
Found while drafting v0.60's [Unreleased] section from merged code rather than from PR bodies — the same practice that caught four attribution errors in the v0.57 notes.
The defect
RQ-60-CANARYis in v0.60's scope, statusimplemented, and its evidence is onmain— so every gate passes. Its deliverable shipped in v0.59.0, and v0.59.0's own release notes already credit it.Measured (commit timestamps,
git merge-base --is-ancestor):CHANGELOG.md,## [0.59.0]section, line 63:And
RQ-60-CANARY's own description says "DELIVERED as PR #1061". Three artifacts cite #1021 —RQ-59-POPCNT(the instance fix),RQ-59-TIERCENSUS(the census),RQ-60-CANARY(the gate) — and all three shipped in v0.59.0, but the third is booked to v0.60.Left alone, v0.60's release notes credit v0.60 with a capability released in v0.59.0, and the readiness query counts 8 artifacts where 7 are v0.60 work.
Why every existing gate is blind to it
scripts/status_evidence_check.py(RQ-60-FLIPCOUPLE, #1064) asks "does the declared evidence exist on main?" It does. It never asks "did that evidence arrive in THIS release?" An artifact whose evidence predates the previous tag is indistinguishable, to R2, from one delivered yesterday.This is the recurring shape one tier up: the check is present, correct, and cannot fail on the defect it would need to catch.
A second, related disagreement — measured, 6 live instances
The checker derives an artifact's release from its file path; rivet's readiness query reads the
release:field. Nothing asserts they agree. Across all 60 release artifacts onmain:Today these are benign (both sides are < v0.60, so the version-gated rules treat them identically). The harmful direction is the one nobody has hit yet: an artifact parked in a pre-v0.60 file carrying
release: v0.60is EXEMPT from every>= v0.60rule while rivet counts it in v0.60's scope — a silent bypass of R1/R5 rather than a cosmetic disagreement.Proposed rules (both mechanical, both red-first-able)
contains:/file:signature, find the commit that introduced the signature (git log -S<literal> -- <path>, first-parent, oldest). If that commit is an ancestor of the v(X.Y-1) tag, the artifact is mis-scoped: red, with the tag named. Escape hatch matching the existing waiver discipline: an explicitshipped-in: vX.Zfield with a written reason, so the correction is a visible diff rather than a silent re-book.release:field must equal the file's version, or carry the same explicit exemption. Dispose of the 6 above in the same PR (they look like real patch-release artifacts parked in the next minor's file — that is a legitimate practice that just needs saying out loud).Disposition of
RQ-60-CANARYitselfProposed, and deliberately NOT a silent re-book: keep the artifact in v0.60 (its id, its commit subjects and its trace links all point there) and record on the artifact and in the v0.60 release notes that its code shipped in v0.59.0 — v0.60 carries only the traceability closure, not the capability. Moving an id numbered
RQ-60-*intorelease-v0.59.yamlwould break the R4 delivery-subject linkage and trade one attribution error for a worse one.Found while drafting v0.60's
[Unreleased]section from merged code rather than from PR bodies — the same practice that caught four attribution errors in the v0.57 notes.