Skip to content

release(v0.70.0): "Evidence you can re-derive" — 9 artifacts, plus the cold review corrections that did not land - #1348

Merged
avrabe merged 4 commits into
mainfrom
release/v0.70.0
Sep 22, 2026
Merged

avrabe merged 4 commits into
mainfrom
release/v0.70.0

Conversation

@avrabe

@avrabe avrabe commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

The v0.70.0 release cut: version bump, CHANGELOG, and the cold review's corrections.

This PR is not just a version bump — read this part first

The plan was "no lane work lands here". That is not what this PR is, and the
reason matters. A cold review was run on feat/npa-1331 before #1340 merged and
produced 21 findings. None of its fixes landed — #1340 merged with all nine
artifacts and none of the corrections. That is precisely the v0.69 failure mode
(six false statements shipped), about to repeat in a release titled "Evidence you
can re-derive"
.

So this PR carries them. Every finding was independently re-derived before
being acted on
, and two were refuted and recorded as such rather than
"fixed":

  • Finding 16 (refuted) — the ALIAS scope narrowing was suspected of leaving
    the i64 spill area unpoliced when spill_area_reserved == false. All eight
    non-test spill.alloc() sites are dominated by a guard (two test the flag
    directly; six sit under a retry rung, and every rung implies the area because
    select_with_stack.rs:296 passes that disjunction as force_spill_area).
    Measured, not just argued: assert!(self.area_reserved) planted in
    SpillState::alloc fired 0 times across 766 synthesis tests and 3428
    executed corpus vectors, with a should_panic control proving the assert can
    fire. Probe reverted; source sha256 restored byte-identical.
  • Finding 14 (recorded, deliberately not back-filled) — v0.70 is the first
    release since v0.61 with no artifacts/release-v0.70/_release.yaml; the plan PR
    plan(v0.70): scope the release — "Evidence you can re-derive" (7 artifacts, every candidate measured against source first) #1336 omitted it. It is not created here: it is a plan-time document
    ("HONEST RISKS, recorded before the work"), no gate reads it, and authoring one
    at the tag would manufacture a plan-time record. v0.71's plan PR creates one.

Corrections that did land include five false counts in RQ-70-CITEGAP, a false R9
causation claim in RQ-70-DONEWHEN replaced by a measured disclosure, a false
EXPECTED_DECLINES claim in the #1321 repro, and an undisclosed behaviour change
in RQ-70-NPA (below).

Two gate-potency fixes, red-first

  • scripts/artifact_citation_check.py skipped any artifact it could not
    parse
    — a gate that ignores unreadable input cannot fail on it. It now uses
    its sibling's StrictLoader/DuplicateKeyError (no second definition to
    drift) and hard-fails. Both reds reproduced before and after.
  • liveness.rs's policed predicate guarded Some([]) but not Some(&[a..a])
    — a list of empty ranges names no offset, so any() is false for every
    slot and the check polices nothing while looking configured. Now one arm
    covering both shapes, with a test that FAILS against the old guard (verified
    by restoring it) and leaves the other four ra003_areas tests unchanged.
  • scripts/test_release_notes_from_rivet.py 8 → 11 tests: both of the
    generator's refusals (stale rivet, zero-added diff) were called "demonstrated
    live" but nothing pinned them. They now run the real main() against a fake
    rivet and a throwaway tagged repo, plus a negative control proving the two
    reds are the refusals firing and not the harness failing to reach them.

An undisclosed behaviour change, now disclosed

RQ-70-NPA's new f32.load/f32.store static-data branches bypass
generate_load_with_bounds_check/generate_store_with_bounds_check. Under
--native-pointer-abi --safety-bounds software|mask an f32 static-data access
that previously loud-declined now emits an UNGUARDED access — a class
extension of #744/#746. Written at both call sites and in the artifact. Those 13
comment lines are why selector_lines_code rose 9; the ratchet carries a waiver
saying exactly that, because it counts hand-maintained decisions and this adds
none.

The version bump

0.69.0 → 0.70.0 across the surface derived from check_version_pins.py
itself
: [workspace.package], 27 path-dep version= pins, MODULE.bazel,
npm/package.json, Cargo.lock (19 synth crates; verified no third-party crate
sits at 0.69.0), plus artifacts/status.json. Two independent gates cover it —
and status.json turned out to be generated, which claim_check caught when it
was hand-edited.

CHANGELOG.md ## [0.70.0] is at the top. The narrative is written; the
artifact list and the trace-graph delta are DERIVED
by
scripts/release_notes_from_rivet.py from rivet diff — which this release added
so the list stops being retyped (#1337). It immediately caught its own artifact:
the delta had been recorded as 25 warnings in three-plus-one classes with the
fourth attributed to an artifact v0.70 never touched; re-derived on the cut tree it
is 26, and that fourth class is two warnings on two of this release's own
artifacts.

What is NOT claimed

Verification

cargo fmt --check rc=0, clippy --workspace --all-targets -D warnings rc=0,
cargo test --workspace, ARM corpus sweep PASS (175/195 compiled, 3428/3428
vectors, 0 mismatches), claim_check 75/75, status_evidence / check_version_pins
/ oracle_wiring / artifact_citation all rc=0, rivet parse errors 0 and "ours"
link errors 0 (all 40 remaining are foreign-prefix cross-repo links, per #1012).

docs/reviews/v0.70-cold-review.md lands on this PR before the tag.

Refs #1321
Refs #1331
Refs #1333
Refs #1334
Refs #1335
Refs #1337
Refs #1318
Refs #1136
Refs #1339

🤖 Generated with Claude Code

https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L

avrabe and others added 2 commits September 22, 2026 21:11
…mented, 2 deferred with measurements, plus the cold review's 21 findings

The version bump, the CHANGELOG with a DERIVED artifact list, and the cold
review's corrections — which did not land before #1340 merged, the exact v0.69
failure mode this release is named against.

Every correction was independently re-derived before it was applied, so two
ended as refutations rather than fixes:

  - finding 16 REFUTED: all 8 non-test `spill.alloc()` sites are dominated by a
    guard, and an `assert!(self.area_reserved)` planted in `SpillState::alloc`
    fired 0 times over 766 tests and 3428 executed vectors, with a should_panic
    control proving the assert can fire. Probe reverted, sha256 restored.
  - finding 14 RECORDED, not back-filled: v0.70 has no `_release.yaml` and one
    is not written here, because it is a plan-time document and no gate reads
    it. v0.71's planning PR creates one.

Two gates that could not fail, both fixed red-first:

  - `artifact_citation_check.py` silently skipped any artifact it could not
    parse, and used last-wins `yaml.safe_load` beside a strict sibling. It now
    hard-fails and shares the sibling's StrictLoader — no second definition.
  - `liveness.rs`'s `policed` guarded `Some([])` but not `Some(&[a..a])`: a list
    of EMPTY ranges names no offset, so the check policed NOTHING while looking
    configured. One arm now covers both shapes; the new test FAILS against the
    old guard.

`test_release_notes_from_rivet.py` 8 -> 11: both generator refusals are pinned
against a fake rivet, with a negative control so the reds cannot be an
unreachable harness.

DISCLOSED: RQ-70-NPA's new f32 static-data branches bypass the bounds-check
helpers, so under `--native-pointer-abi --safety-bounds software|mask` an f32
access that previously loud-declined now emits UNGUARDED (class extension of
#744/#746). Those 13 comment lines are the whole +9 on `selector_lines_code`,
waived with that reason.

Re-derived at the cut, not carried: trace-graph delta 26 new warnings in four
classes (recorded as 25 with the fourth misattributed), citation gate 7242 test
names, corpus sweep compiled=175/195 executed=3428/3428 mismatches=0.

cargo fmt rc=0, clippy -D warnings rc=0, cargo test --workspace 168 suites /
0 failures, claim_check 75/75, status_evidence + check_version_pins +
oracle_wiring + artifact_citation all rc=0, rivet "ours" errors 0.

Refs #1321
Refs #1331
Refs #1333
Refs #1334
Refs #1335
Refs #1337
Refs #1318
Refs #1136
Refs #1339

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
… module, and named the next wall themselves

Documentation and artifact evidence only — no code, no gate, no version change.

The blocked party rebuilt from c18c185 on their own toolchain (meld 0.56.2,
wac-cli 0.10.1, cortex-m7) and reported back on 2026-09-19:

  rc=0, "Compiled 21 functions" with 0 skipped, 68374 bytes of code, 70172-byte
  ELF, 66 relocations, and "verify-embedder OK: 0 reserved-register writes in
  19140 instructions across 21 symbols"

  "Previously this was rc=1, 1 of 21 functions skipped with `SpillSlotAliased`,
   no object — i.e. the #1321 fix lands."
  "The f32 static-data declines are gone ... the `GI-FPU-002 phase 1b` messages
   from the original report are gone."

That is an INDEPENDENT reproduction by the person the release was ordered
around, which is the only acceptance test these two lanes ever had.

The byte counts differ from the artifacts' own [REPORTER-ONLY] figures because
it is a NEWER build of their component (cascade-v1139-fused.wasm, 41055 bytes).
Both are recorded as two measurements rather than reconciled into one — the
release's own rule about not carrying a number between trees.

TWO THINGS THIS ALSO SETTLES:

  - The next wall on `--native-pointer-abi` is the one RQ-70-NPA PREDICTED, and
    the reporter hit it independently: `LdrSym literal pool out of range (#345)`
    in a single 50722-byte function. #1331 stays OPEN on their evidence, not on
    our caution.
  - v0.70 asked whether `--native-pointer-abi` is load-bearing for their build
    or merely preferred, and shipped without an answer. It is answered by
    demonstration: they are shipping via `--embedder-data-init
    --embedder-global-init` today. So it is a PREFERENCE blocker, which should
    have lowered this lane's rank against ALIAS — recorded so the v0.71 ranking
    starts from it rather than re-deriving it.

claim_check 75/75, status_evidence + check_version_pins + artifact_citation +
oracle_wiring all rc=0, rivet delta re-derived and unchanged at +26 warnings /
0 new errors. No Rust changed, so fmt/clippy/test are unaffected.

Refs #1321
Refs #1331

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

avrabe and others added 2 commits September 22, 2026 21:38
…atements, one of them reddening a required gate — all corrected

Two fresh-context reviewers ran on 62993ad. Neither returned a BLOCKER in the
code, and the prose pass found the release doing the thing the release is named
against.

BLOCKING, and the gate caught it before I did. The review record declared two
passes, cross-referenced "pass 2, finding A", and contained no pass 2 — while
naming only `4e865f31`, an unmerged branch head. Conformance step 7 read
DERIVED-FAIL, "exists but names no commit that is an ancestor of the release
commit". Pass 2 is now written and the record declares `Commit reviewed:
62993ad`.

THE SHARED ROOT CAUSE, in the reviewer's words: "a number measured before the
last edit to the thing it measures."

  - `npa_static_f32_1331.wat`'s "41 total, 38 non-blank" was written by the hunk
    that split a comment line in two — it ADDED the lines it was counting.
    Correcting it in place to 43/40 made the file 47/44 and wrong a second time,
    in the same session. The header now quotes only the CODE-line count, the one
    figure that survives editing the prose around it.
  - CITEGAP's "5243 -> 7242" is derivable from NO single tree: 5243/7239 are
    this release's parent, 5245/7242 the cut. Only the `after` half had been
    re-derived. Both halves are now measured on the cut.
  - ALIAS's "ra003 34 -> 39" was right at the parent and made 40 by THIS
    release's own finding-18 test.

OTHER FALSE STATEMENTS, all corrected:

  - the cold review claimed NPA's "20-line reduction" was corrected; only the
    .wat header had been, and `RQ-70-NPA.yaml:75` still said it.
  - ARCHMODEL said "release artifacts only exist from v0.63". False —
    `release-v0.56.yaml` onwards exist, and RQ-69-ARCHMODEL had EXPLICITLY
    retracted that exact sentence. It returned because this artifact was written
    from its predecessor's SHAPE rather than its predecessor's CORRECTION.
  - "four sit under a retry rung" while listing five (2+4+1 against an asserted
    eight).
  - "all EIGHT non-test `spill.alloc()` sites": there are FIVE call sites, and
    all eight cited lines are GUARDS. Three of the five allocators are helpers
    reached from more than one guarded caller. The reviewer re-derived every
    caller set and agreed the narrowing is sound — the substance held, the
    citation did not.

MISLEADING, corrected: reporter-only figures presented as re-derivable (an
unmarked `opt.wasm` bullet under a "[REPORTER-ONLY] except where marked" header,
and the CHANGELOG's headline table unlabelled); "the committed 54-line fixture"
stating a convention on one fixture and not the other; "three gates that could
not fail" when there were four.

DISCLOSED rather than fixed: the `assert!(self.area_reserved)` probe was
reverted, so the central evidence for this release's one REFUTED finding is
unreproducible from the shipped tree. The static argument and guard line numbers
are re-derivable; the silent probe run is not. A permanent `debug_assert!` is a
v0.71 candidate, not a change to make at a cut.

Also from the code pass: the citation gate globbed only `*.yaml` while the
sibling it shares a loader with globs `*.yml` too — so a `.yml` artifact was
legal to the release gate and INVISIBLE here, unparseable ones included. Both
extensions now, through a single `artifact_files(root)` used by the scan AND the
reported count, which had been two separate globs. Proven: a `.yml` artifact
citing a non-existent test now reds. An empty or comment-only artifact also
vanished silently (`yaml.load` -> None); it now hard-fails, EXCEPT for
`_release.yaml`, whose required shape is comments-only — the first version of
that guard reddened all nine of them, a checker failing on the correct answer.

The fixture repo now neutralises the ambient git config wholesale
(GIT_CONFIG_GLOBAL/SYSTEM, NOSYSTEM) rather than `commit.gpgsign` alone, and the
stale-rivet test uses a non-empty diff so its returncode assertion is
load-bearing — verified by mutation: removing the version refusal now fails on
that line, where before only the message assertion could catch it.

The `selector_lines_code` waiver's own accounting was false: "13-4 across two
sites" against an actual +17/-8 across THREE, the third being a doc comment that
had claimed the float arms still decline. Total was right, the account of it was
not.

No Rust changed. claim_check 75/75, status_evidence + check_version_pins +
artifact_citation + oracle_wiring rc=0, gate unit tests rc=0, rivet +26/-0
re-derived, citation 7242 names / 136 files re-derived, ra003 40 passed.

Refs #1321
Refs #1331
Refs #1333
Refs #1337

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…s edits moved a pinned site four lines down

The `mutation survey` job went RED on the release PR while main (da110b8) and
c18c185 / 1da8c4c / bd65e45 were all GREEN on the same job, so the red
belonged to this PR and not to the runners. Asked that question first.

IT WAS NOT A COVERAGE REGRESSION, though the failing step says "controls must
die, survivors must reproduce", which is exactly what a coverage regression
looks like.

`docs/status/mutation_survey.json` pins every mutant by `file:line:col`. The
subset entry `R4-shared/REG/liveness.rs:7346:36` targeted

    let aapcs_dead_at_return = [Reg::R2, Reg::R3, Reg::R12, Reg::LR];

and this release's `policed` fix plus its red-first test added +27/-5 lines to
`liveness.rs`, ALL ABOVE that line. The statement moved to 7350; line 7346 now
holds `let ends_in_return = matches!(`. The pin was aimed at different code.

`reanchor` is the sanctioned remedy and says so in its own docstring — "the id
embeds the line number, so a shifted site must be re-resolved rather than
trusted". It re-locates by each mutant's stored `before` text:

    reanchor: 5 sites moved, 0 not found, tree c51823a
    ci_subset: R4-shared/REG/liveness.rs:7346:36 -> :7350:36

NOTHING WAS RE-BASELINED. mutants 34 -> 34, controls 3 -> 3, ci_subset 10 -> 10,
UNTESTED 4 -> 4 (the `mutants_untested` ratchet), claim_check 75/75. The replay
now passes on its own terms:

    MUTANTS-CI subset=10 controls=3 non-killed=7 failures=0
    MUTANTS-REACH-WIDE entries=4 reached=4 unreached=0
    MUTANTS-GATE ok — floors met, exact fields exact, reach complete

Filed for v0.71 rather than changed at a release cut: CI never runs `reanchor`
(`grep -c reanchor .github/workflows/ci.yml` = 0) and the failure names neither
line drift nor the remedy, so any PR that inserts a line above a pinned site
gets a red that reads as lost coverage — and the tempting fix, `pin-subset`,
would silently RE-BASELINE coverage instead of re-locating a site. That is the
same shape as this release's own `.wat` header counting the lines its hunk had
just added: an anchor that quietly means something else after an unrelated edit.

No Rust changed. All five gates rc=0.

Refs #1189
Refs #1321

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
@avrabe
avrabe merged commit 6470e17 into main Sep 22, 2026
73 checks passed
@avrabe
avrabe deleted the release/v0.70.0 branch September 22, 2026 21:33
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.

1 participant