Skip to content

An artifact can be 'implemented' in vX.Y on evidence that shipped in vX.Y-1 — every gate passes and the release notes are wrong #1085

Description

@avrabe

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 #1021RQ-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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions