Repository navigation
release(v0.70.0): "Evidence you can re-derive" — 9 artifacts, plus the cold review corrections that did not land - #1348
Merged
Merged
Conversation
…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 Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-1331before #1340 merged andproduced 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":
the i64 spill area unpoliced when
spill_area_reserved == false. All eightnon-test
spill.alloc()sites are dominated by a guard (two test the flagdirectly; six sit under a retry rung, and every rung implies the area because
select_with_stack.rs:296passes that disjunction asforce_spill_area).Measured, not just argued:
assert!(self.area_reserved)planted inSpillState::allocfired 0 times across 766 synthesis tests and 3428executed corpus vectors, with a
should_paniccontrol proving the assert canfire. Probe reverted; source sha256 restored byte-identical.
release since v0.61 with no
artifacts/release-v0.70/_release.yaml; the plan PRplan(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_DECLINESclaim in the #1321 repro, and an undisclosed behaviour changein RQ-70-NPA (below).
Two gate-potency fixes, red-first
scripts/artifact_citation_check.pyskipped any artifact it could notparse — a gate that ignores unreadable input cannot fail on it. It now uses
its sibling's
StrictLoader/DuplicateKeyError(no second definition todrift) and hard-fails. Both reds reproduced before and after.
liveness.rs'spolicedpredicate guardedSome([])but notSome(&[a..a])— a list of empty ranges names no offset, so
any()is false for everyslot 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_areastests unchanged.scripts/test_release_notes_from_rivet.py8 → 11 tests: both of thegenerator's refusals (stale rivet, zero-added diff) were called "demonstrated
live" but nothing pinned them. They now run the real
main()against a fakerivet 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.storestatic-data branches bypassgenerate_load_with_bounds_check/generate_store_with_bounds_check. Under--native-pointer-abi --safety-bounds software|maskan f32 static-data accessthat 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_coderose 9; the ratchet carries a waiversaying exactly that, because it counts hand-maintained decisions and this adds
none.
The version bump
0.69.0 → 0.70.0across the surface derived fromcheck_version_pins.pyitself:
[workspace.package], 27 path-depversion=pins,MODULE.bazel,npm/package.json,Cargo.lock(19 synth crates; verified no third-party cratesits at 0.69.0), plus
artifacts/status.json. Two independent gates cover it —and
status.jsonturned out to be generated, which claim_check caught when itwas hand-edited.
CHANGELOG.md## [0.70.0]is at the top. The narrative is written; theartifact list and the trace-graph delta are DERIVED by
scripts/release_notes_from_rivet.pyfromrivet diff— which this release addedso 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
opt.wasmstill skips 7 of 17 functions (GI-FPU-002: three named cascade entry points are the entire remaining gap to a complete falcon M7 image (attitude#tick, ekf#estimate, position#tick) — everything else in the chain now works #1069, GI-FPU-002) — unchanged, andnot what this release fixed. Synth is unable to compile a recent falcon-cascade binary #1318 stays open.
position#tickandekf#estimatenow reach the dissolved --relocatable objects carry full wasm linmem (64KB .data) + absolute MOVW relocs — MCU-unshippable + link-fragile (gale mutex silicon fault) #345 literal-pool wall, apre-existing limit the f32 decline was hiding. Native-pointer ABI fails to lower static-data f32.load/f32.store for fused falcon-cascade (#359 address relocation) #1331 stays open.
check_vfp_slot_aliasing(GI-FPU-002 + RA tail is now the ONLY gate between the falcon cascade and the M7 — 5 entry-point symbols; phase-2 D-register pressure is new in v0.52 (inline-f64 #869 lowering) #881) carries the same single-value-per-slot modelover the VFP word file and is not known to be clean.
deliverable.
Sub{SP,SP,Imm}rather than theprologue's) is recorded in the cold-review file as measured-and-deferred: safe
today because the only
rd: Reg::SPSubisselect_with_stack.rs:330, butnot structurally tied.
Verification
cargo fmt --checkrc=0,clippy --workspace --all-targets -D warningsrc=0,cargo test --workspace, ARM corpus sweep PASS (175/195 compiled, 3428/3428vectors, 0 mismatches),
claim_check75/75,status_evidence/check_version_pins/
oracle_wiring/artifact_citationall 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.mdlands 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