Two defects found at the v0.66.0 tag gate, on the tag candidate itself, after the release PR, the clean-room review and all 67 CI checks had passed. Both were fixed before the tag in #1258. Neither was caught by anything, and both belong to a surface nothing watches: the release notes themselves.
This is filed as the gate hole, not as the two instances — the instances are closed. Sibling gate-hole issues: #1250, #1255, #1257.
Class 1 — a release PR can append instead of rename, and shipped work stays filed as unreleased
The v0.66.0 release PR (#1251) wrote a fresh ## [0.66.0] section BELOW the existing ## [Unreleased] heading instead of renaming it. Two lane-written entries — RQ-66-DELETE and RQ-66-WATCHED — stayed under [Unreleased]. v0.66.0 would have been the first release in four to publish its own shipped work under a heading asserting it is not shipped, and the first thing v0.67 would inherit.
It survived the cold review because the review edited inside that block (#1253 corrected a stale emulation floor there) without questioning the block.
Why nothing caught it: claims.yaml lists CHANGELOG.md as unpinned_ok ("append-only release narrative; no live current-state claims"), and no script or workflow greps the heading. That classification is right for the file's content and wrong for its structure.
Proposed gate (v0.67, ~5 lines): a loop_conformance_check.py step-8 slot asserting that at cut the topmost ## [ section is the release being cut, and that no ## [Unreleased] heading exists (the shape v0.63.0, v0.64.0 and v0.65.0 all shipped). Red-first is free: the check reddens on 0cfcc160, the v0.66 tag candidate, and greens on the fix.
Class 2 — a count of releases in prose that no derivation produces
Two of the five rows in v0.66's own scorecard carried a release count that matches nothing in the repository's history:
| published |
derived |
sel_dsl_rules "flat, thirteenth release" |
unchanged since v0.59.0 — eighth release at 80 |
selector_lines_code "eighth consecutive rise" |
eight releases since v0.58, not one fall — v0.63 was exactly +0 |
Both derive in one command over data the ledger already trusts: sel_dsl_rules from coq/vcr_sel_rules.manifest at every tag (50 for v0.47–v0.57, 74 at v0.58, 80 since v0.59), selector_lines_code from its own pin at every tag (+327 +911 +14 +14 +0 +513 +156 +201).
This is the same shape as the "84 of 89" defect this release's own cold review corrected: a real measurement whose base was never named, restated as though it were release-scoped. The ratchet mechanism already forces every value to be a visible claims.yaml diff. It says nothing about a count of releases, which is exactly where the prose drifted.
Proposed gate (v0.67): have claim_check --metric print, per ratchet, the tag at which the value last CHANGED and the number of releases since — derived from the pin's own history across tags. Then the release notes have a derived number to quote instead of a remembered one, and a wrong ordinal becomes a diff rather than prose.
What makes this worth a gate rather than more care
Both defects are in the artifact that states what the release did. Every other claim in this release is pinned, derived, or oracle-gated; the document describing those claims is the one surface with no gate at all. Three consecutive releases have now found a defect in their own release prose at or after the cold review (v0.64 a fabricated evidence line, v0.65 four prose defects, v0.66 these two plus the review's own "84 of 89"). That is a pattern, not three accidents.
Both were fixed in #1258 and v0.66.0 shipped with the corrected notes (tag v0.66.0 -> 2e1a8287, CONFORMS, 12/12 crates live). The gates proposed above are v0.67 work.
Refs #1189 #1250
Two defects found at the v0.66.0 tag gate, on the tag candidate itself, after the release PR, the clean-room review and all 67 CI checks had passed. Both were fixed before the tag in #1258. Neither was caught by anything, and both belong to a surface nothing watches: the release notes themselves.
This is filed as the gate hole, not as the two instances — the instances are closed. Sibling gate-hole issues: #1250, #1255, #1257.
Class 1 — a release PR can append instead of rename, and shipped work stays filed as unreleased
The v0.66.0 release PR (#1251) wrote a fresh
## [0.66.0]section BELOW the existing## [Unreleased]heading instead of renaming it. Two lane-written entries — RQ-66-DELETE and RQ-66-WATCHED — stayed under[Unreleased]. v0.66.0 would have been the first release in four to publish its own shipped work under a heading asserting it is not shipped, and the first thing v0.67 would inherit.It survived the cold review because the review edited inside that block (#1253 corrected a stale emulation floor there) without questioning the block.
Why nothing caught it:
claims.yamllistsCHANGELOG.mdasunpinned_ok("append-only release narrative; no live current-state claims"), and no script or workflow greps the heading. That classification is right for the file's content and wrong for its structure.Proposed gate (v0.67, ~5 lines): a
loop_conformance_check.pystep-8 slot asserting that at cut the topmost## [section is the release being cut, and that no## [Unreleased]heading exists (the shapev0.63.0,v0.64.0andv0.65.0all shipped). Red-first is free: the check reddens on0cfcc160, the v0.66 tag candidate, and greens on the fix.Class 2 — a count of releases in prose that no derivation produces
Two of the five rows in v0.66's own scorecard carried a release count that matches nothing in the repository's history:
sel_dsl_rules"flat, thirteenth release"selector_lines_code"eighth consecutive rise"Both derive in one command over data the ledger already trusts:
sel_dsl_rulesfromcoq/vcr_sel_rules.manifestat every tag (50 for v0.47–v0.57, 74 at v0.58, 80 since v0.59),selector_lines_codefrom its own pin at every tag (+327 +911 +14 +14 +0 +513 +156 +201).This is the same shape as the "84 of 89" defect this release's own cold review corrected: a real measurement whose base was never named, restated as though it were release-scoped. The ratchet mechanism already forces every value to be a visible
claims.yamldiff. It says nothing about a count of releases, which is exactly where the prose drifted.Proposed gate (v0.67): have
claim_check --metricprint, per ratchet, the tag at which the value last CHANGED and the number of releases since — derived from the pin's own history across tags. Then the release notes have a derived number to quote instead of a remembered one, and a wrong ordinal becomes a diff rather than prose.What makes this worth a gate rather than more care
Both defects are in the artifact that states what the release did. Every other claim in this release is pinned, derived, or oracle-gated; the document describing those claims is the one surface with no gate at all. Three consecutive releases have now found a defect in their own release prose at or after the cold review (v0.64 a fabricated evidence line, v0.65 four prose defects, v0.66 these two plus the review's own "84 of 89"). That is a pattern, not three accidents.
Both were fixed in #1258 and v0.66.0 shipped with the corrected notes (tag
v0.66.0->2e1a8287, CONFORMS, 12/12 crates live). The gates proposed above are v0.67 work.Refs #1189 #1250