feat(reach): RQ-65-MVPCORE (#1017) — MVP core re-derived on the executed path: single-module .wast routing (oracle first), merge refusals, start-function invocation; 14/114 -> 12/80 - #1232
Conversation
…ted path: single-module .wast routing (oracle first), merge refusals, start-function invocation; 14/114 -> 12/80 Both numbers in v0.63's "MVP core 14 / 114" were properties of the instrument. The denominator: 31 multi-memory-proposal twins and 3 relaxed-SIMD lane files sat in MVP core because the census's family regexes predate the Wasm 3.0 merge — MVP core is 80 files, and `multi-memory` is a family row. The numerator (#1225): the census's `synth compile file.wast` took the multi-module MERGE branch, written for synth's i32-only fixture suite, which handed the backends empty data segments, empty globals (the Cortex-M startup never wrote R9) and i32-only signature tables (`i64.add` on two i64 params lowered as `adds r3, r0, r1`). Exit 0, counted `ok`, on a path no execution oracle compiles. Oracle first: `scripts/repro/wast_single_module_path_identity_1225.py` (a single-module .wast must compile to exactly the bytes its module compiles to alone; three backends; wired into the Spec Suite workflow) was RED on the pre-fix driver (arm 49 / riscv 33 / aarch64 56 of 140), then a single-module .wast is routed through the single-module path (140/140/140 identical) and the merge refuses a module with active data segments, accessed globals or a non-i32 signature over its retained functions. Reach increment, oracle first: the self-contained Cortex-M Reset_Handler now BLs the (start ...) function after the data copy and the R9 table, before the entry BLX r0. The parity oracle stopped declining start modules and gained a floor that was red before (4 seen, 0 both-accepted) and is green after (2 both-accepted, 10/10 assertions ok, 0 divergences). Every other path keeps the #1046 refusal. MEASURED DELTA, per backend, on the corrected 80-file set: arm 13 -> 12 ok, riscv 10 -> 9, aarch64 18 -> 18 (old 114-file set: 14 -> 12, 11 -> 9, 21 -> 18). Every loss is a refusal of an object that was wrong; every gain a first real compile. The start increment moved ZERO files (its files are multi-module or multi-memory) — the file-vs-module gap v0.63's caution predicted, measured. Pins, README, FEATURE_MATRIX template, claims.yaml and the family doc move together; other_error stays 0 (the #406 multi-memory decline family is classified by its tag). Filed: #1229, #1230, #1231. Refs #1017, #1225, #1046, #1217 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…-corpus parity PASS recorded Fills `landed:` with the PR number (it did not exist until `gh pr create` returned) and records the parity evidence measured on the rebased tree: full corpus RESULT PASS, 330 modules both-accepted, 19155/19155 assertions, 622 pinned divergences across 103 pins, 0 unpinned, start-function line 2 both-accepted / 10 ok / 0 divergences. The CI job on the PR is the gate; these runs are its pre-flight. Refs #1017 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Coordinator verification of #1225 — reproduced independently, and it is a silent miscompile of the plainest possible shapeNot a re-read of the lane's report. Compiled synth's own The function is
this branch: Every parameter was being homed at A second symptom worth recording: the object produced by that path has no On the headline number. "MVP core is 14/114" was wrong in both halves and this artifact says so: And the reach increment gained ZERO files, reported as such — which is exactly what the artifact |
Coordinator: merge-order hazard between #1227 and #1232 — do not merge these in either order without re-derivingMeasured, not reasoned. Both PRs are green on their own base; together they break #1227 pins Its fixture #1232 makes that merge path REFUSE any module it would mis-home ( So once #1232 lands, the fixture no longer compiles, the audit cannot measure A correction to my own first reading, recorded because it changes the conclusion. I initially tested a Consequences to settle before either merge:
|
…n carry its own evidence `start_on_arm_selfcontained_is_invoked_from_reset_handler` failed once in CI on #1232 with a bare `expect("disasm names Reset_Handler")`, which says nothing about why. NOT reproducible locally. Ruled out, each by execution rather than reasoning: - flake / temp-dir race: 5 clean runs, temp dir removed each time, 10/10 - filename collision between the file's 10 tests: every test has a distinct fixture and a distinct derived output name - feature unification under `cargo test --workspace` (the CI command, and the recorded trap that feature-gated builds behave differently): 10/10 green So the cause is environment-specific and I will not guess at a fix. Make the next failure produce the evidence instead: - assert the object EXISTS and is non-empty before disassembling it, naming the path and listing the directory — the compile asserting success does not prove the conventional path was written - replace the bare expect() with the disasm exit code, stdout/stderr sizes, and the first 1200 chars of what was actually produced Also records the fact that made this confusing: `<Reset_Handler>:` is SYNTHESISED by `synth disasm` from the startup layout — the self-contained image carries no `.symtab` at all (verified: symtab ABSENT, disasm still prints the label). Its absence therefore means the image is not the self-contained shape, not that a symbol is missing. Refs #1017 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
… on the host's objdump; split it Root cause, from the diagnostics added in the previous commit rather than from a guess: disasm exit: Some(1), stdout 211 B, stderr 77 B INFO Detected triple: thumbv7m-none-eabi objdump: can't disassemble for architecture UNKNOWN! Error: objdump failed `synth disasm` SHELLS OUT to `objdump` (main.rs:8311, whose own comment says "works on macOS with Apple LLVM"). The GitHub-hosted runners carry a plain x86-64 binutils with no ARM support, so the disassembly the test parsed never existed there. It passed on macOS because Apple's objdump is LLVM's. This is the repo's recorded trap — disasm TEXT is host-dependent — reached through a CLI subcommand rather than directly. Split the test along that seam: HOST-INDEPENDENT, runs everywhere: the compiler's own acceptance decision, "the self-contained image's Reset_Handler invokes it before the entry call". This is what pins the #1046 refusal from coming back. BYTE-SHAPE, only where the disassembler works: the BL-before-BLX check, with an explicit NOTE printed when it is skipped, naming the disasm exit code. A silent skip would be the vacuity this release exists to find. The execution proof was never this test and the doc comment already said so: `selector_parity_197_differential.py` boots this very startup under unicorn and is CI-wired. Two things measured rather than assumed while fixing it: - the acceptance line goes to STDOUT (2917 B stdout / 0 B stderr on success); my first attempt read `stderr(&out)` and failed locally, which is why it was run locally before pushing - the self-contained image carries NO `.symtab`; `<Reset_Handler>:` is synthesised by the disassembler, so its absence never meant a missing symbol 10/10 locally. Refs #1017 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
… 1.98 rejects `clippy::useless_borrows_in_formatting` on the `eprintln!` argument added by the previous commit. My local gate missed it because I ran `-p synth-cli` while CI runs `--workspace`, and — the part that would have bitten either way — local clippy is 0.1.96 against CI's 1.98, so the lint does not exist here. That drift is a recorded trap in this repo; the mitigation is to scan the whole diff for the reported pattern rather than fix the one reported line, which I did: the only other `&`-prefixed additions are a function argument and a slice literal, neither a format argument. Refs #1017 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…1232 landed the fix this pin was waiting for Rebased onto main after RQ-65-MVPCORE (#1232) merged, which is the fix this pin's own rule anticipated: "a fix makes (b) == (c), this goes red, and the fix flips the pin (known-open -> closed) in its own PR." RE-DERIVED on the merged tree with `--print-self-test`, not asserted. Every leg (merged-wast, single-wast, same-text-wat): before m4-reloc (7, 6, 8) m4-self (4, 4, 8) wast < wat, open after all four legs (0, 8, 8) wast == wat, merged refused Two independent routes, both now clean: the single-module `.wast` path threads declared widths so `wast == wat`, and the multi-module merge REFUSES an i64-param module so `merged == 0`. The assertion becomes EQUALITY plus that refusal, which is strictly stronger than the old inequality — a narrower `wast` OR the merge silently accepting again now goes red. POTENCY is untouched: 192 planted writes, 0 without the plant, across 3 fixtures x 4 legs. Self-test RESULT: PASS on the rebased tree. Artifact prose corrected where it had become FALSE rather than merely dated: "#1226 stays OPEN" and "not fixed here" were true when written and are not now. The spec-suite functions the artifact said were "NOT fixed by #1222 and stay so until #1226 is fixed" ARE now correct, because #1226 is fixed. What remains of #1226 is a REACH note, not a correctness one: the merge refuses i64-param modules it previously accepted and mis-compiled — decline-honesty with the acceptance cost stated. Emulation floor re-derived on the rebased tree: 346751, unchanged. Refs #1189, #1226, #1232 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…floors after #1232; the population fell because modules are now REFUSED CI on the rebased tree reported the pin flip working — `WIDTH-1226: closed`, `POTENCY: PASS (192 planted writes, 0 without the plant)`, `hits: 0` — and then failed on the population floors, correctly: VACUOUS — declared floor stdout >= 8317, measured 7191 That is the floor doing its job. The cause is not scan rot: RQ-65-MVPCORE (#1232) merged first and makes the multi-module `.wast` merge REFUSE modules it would mis-handle (i64 params, data segments, accessed globals) instead of silently mis-compiling them. A refused module audits no functions, so this oracle's corpus shrank with them: modules compiled 1045 -> 940 (-105 refused) functions audited 8317 -> 7191 (-13.5 %) homes watched 8776 -> 8100 attributed instrs 261440 -> 219807 Re-derived from CI's own run on the merged tree, not computed. The floors move DOWN exactly once, here, with that reason written beside them in the script, the artifact and ci.yml; a further fall without a reason is scan rot and stays red. This is worth stating plainly rather than quietly re-pinning: it is the ACCEPTANCE COST of decline-honesty, measured. #1232 traded reach for correctness, and one place the bill lands is that a correctness oracle now watches 13.5 % fewer functions. Emulation floor unaffected (this oracle declares `stdout`, not `emulations`) and re-derived at 346751 on the rebased tree. Refs #1189, #1226, #1232 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…me-register consumer on four legs; fix aarch64 rotl (#1221) and i64-param local.set (#1222) red-first; pin #1223/#1226 open (#1227) * fix(selector): RQ-65-ALIASCLASS (#1189) — enumerate every uncopied home-register consumer on four legs; fix aarch64 rotl (#1221) and i64-param local.set (#1222) red-first; pin #1223 open THE QUESTION. `local.get` of a register-homed local pushes THE HOME REGISTER uncopied onto the operand stack; #677, #989 and #1189 were three consumers that wrote it, each found as a silent wrong answer and fixed at its own site. How many others exist, across arm-reloc, arm-self, RV32 and AArch64? Answered mechanically, not by re-reading arms. STATIC AUDIT (ARM direct selector). `synth_synthesis::home_alias`: an exhaustive, wildcard-free register-writes table for all 222 ArmOp variants (`gp_defs`/`vfp_defs`, #946-style source-scan pin) + a loop-back-edge- extended liveness walk independent of the selector's own `param_last_read`, hooked at the tail of `select_with_stack` under SYNTH_HOME_ALIAS_AUDIT. A write to a live local's home that is not the local's own set/tee, and not proven straight-line into an inline epilogue ON THE STREAM, is a loud decline naming op, instruction, register and local. Byte-invisible otherwise. Swept over the pinned spec suite + local corpus on {reloc, self} x {cortex-m4, cortex-m4f}: 4628 functions, 2372 homes, 227150 attributed instructions, 0 unexplained hits; 16 hits pinned KNOWN-OPEN against #1226 (home_alias_audit_corpus_1189.py, CI job home-alias-audit-1189). Potency against the real history: built at the pre-#1190 commit it flags exactly the 10 functions #1190 recorded wrong and none of its 7 clean ones. EXECUTION ORACLE (four legs). home_alias_class_1189_differential.py + 3 generated modules: 117 consumer-family functions re-reading their homes after every op, expected values from wasmtime, declines pinned EXACTLY per (module, leg), main's own objects kept as a permanent red half (10 pinned wrong vectors). Red-first on main af81978: 990 matched / 9 diverged: #1221 aarch64 i32/i64.rotl negates the count IN PLACE — the #776 fix's "now-dead register" is a param home in a leaf function; every result exactly rotl + a - b (7 vectors). #1222 direct selector local.set/tee of a register-homed i64 PARAM writes only the lo half, at index_to_reg(i) not the AAPCS pair, with the #989 snapshot reserving only val_lo; every leaf function assigning an i64 param (spec suite: fac-opt, loop `while`, type-param-i64, the 64-bit bulk-memory checkRanges) was silently wrong. #1223 optimized path folds (x - x) + x to 0 — an IR defect, NOT this class; filed, pinned KNOWN_OPEN (the recorded wrong value must persist until the fix flips the pin). #1226 surfaced BY the #1222 fix in the audit sweep: the multi-module .wast merge hands a later module's function the representative module's param-width table (#1168 re-threads arg counts, not width masks), so an i64 param is homed as i32 and its pair overlaps the next param. A CLI-merge defect, NOT this class; filed, 4 spec-suite functions x 4 legs pinned exactly until fixed. Green on the fixes: 999 matched / 0 diverged, 10/10 pinned wrong vectors still reproduce from main's bytes, 1629 emulations. CI job home-alias-class-1189-oracle; emulation floor 325121 -> 326750 (re-derived by oracle_wiring_check.py; ci.yml and claims.yaml in lockstep). FIXES, one site each. aarch64 rotl: a param count is negated into a scratch chosen with n, k and dst held live; a temp count keeps the #776 bytes. ARM direct: `write_i64_param_home` moves both halves at the `local_to_reg` home, ordered for partial overlap, both halves of val reserved for the alias snapshot. Byte-identity pre vs post over 1419 compiles / 10725 functions (arm-reloc, arm-self, aarch64): 58 functions changed, every one an aarch64 rotl function or an ARM i64-param set/tee; 0 newly declined / accepted, no skip-set moved. STRUCTURAL PINS for the clean legs, as tests: RV32 params COPY on local.get (the accident of implementation the artifact names) and a promoted s8 is written only by its own set + the epilogue; AArch64 TEMPS disjoint from x0..x7, 21 families never write a param home; the optimized path's local vregs are never freed (18 families walked with gp_defs). LEDGER. selector_lines_code 19740 -> 19917 by waiver (the class had no handling to delete); tracked totals 30565 -> 30857, 91 -> 93 (two `_ => None` in the new test). RQ-65-ALIASCLASS implemented; enumeration in docs/analysis/HOME_REGISTER_ALIAS_CLASS_1189.md; CHANGELOG [Unreleased]. Refs #1189, #1221, #1222, #1223, #1226 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(selector): RQ-65-ALIASCLASS (#1222) — gate the i64 pair-write on the DECLARED width; the fuzz harness was right and the fix over-applied Salvaged and completed by the coordinator after the lane hit a session rate limit mid-diagnosis. Three CI reds on #1227, all found only after the rebase. RED 3 — the substantive one, and the fuzz target was CORRECT. `i64_lowering_doesnt_clobber_params` asserted that nothing may write R1 while `LocalGet(1)` still reads it, and caught: Mov { rd: R0, op2: Reg(R4) }, Mov { rd: R1, op2: Reg(R5) } The convenient reading was that the harness encoded the pre-#1222 register model and should move with the fix. It did not. `i64_locals` carries body-INFERRED widths (`infer_i64_locals`), not only declared ones — so a param the signature calls i32, or whose width nobody declared (a direct `select_with_stack` caller, #1226's stale multi-module width table, invalid wasm), is homed NARROW by `aapcs_param_layout` and its "hi half" IS the next param's home. The #1222 pair-write fired there and genuinely clobbered local 1. So the fix was over-applied, not the harness stale. `declared_wide_params` now gates the pair arm on the declared width AND the layout having homed it as a pair; anything else keeps the single-move arm — yesterday's bytes. Regression test covers both configurations, which is the discrimination that was missing: undeclared widths write R0 only with nothing touching R1 before `local.get 1`; declared `(i64 i32)` writes the pair R0:R1 with local 1 in R2. RED 1 — the audit oracle ran VACUOUSLY in CI. `ROOT` was `Path(__file__).parent.parent`, which from `scripts/repro/` resolves to `scripts/`, so it looked for the suite at `scripts/tests/spec-testsuite`, found nothing and exited 1 having audited 0 functions. Now `.parent.parent.parent`, matching the working sibling `selector_parity_197_differential.py` in the same directory. Its FATAL message also stops guessing ("submodule not checked out?" — it was) and prints the path it actually looked at plus whether that path exists. RED 2 — `arm_corpus_sweep_973.py` auto-sweeps every `scripts/repro/*.wat`, so the new i64 fixture joined the corpus and legitimately declines its 10 `c_*` exports (i64 compare feeding `i64.extend_i32_u`, #952). Registered in EXPECTED_DECLINES with that reason; the other 38 exports compile and execute equal to wasmtime. Verified: fmt, clippy -D warnings clean, synth-synthesis 760 + suites 0 failed, exact-emulation-floor re-derived 346751 on the rebased tree, status_evidence and claim_check green. Refs #1189, #1221, #1222, #1226 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(gate): RQ-65-ALIASCLASS (#1222) — move the selector ratchet and regenerate status.json for the declared-width guard The previous commit changed select_with_stack.rs without moving the pins, and I pushed it because my `&&` chain guarded the `echo`, not the `git push` — the exact "captured the exit code, didn't gate" trap the standing rules name. The gate said FAIL and the push ran anyway as a separate statement. This commit is chained through to the push so it cannot repeat. Two real failures behind that FAIL, both re-derived, never hand-computed: selector_lines_code 19917 -> 19945 ceiling, must FALL -> waived selector_lines_total 30857 -> 30943 tracked, no direction -> value only artifacts/status.json stale -> regenerated with --emit-status The waiver is bound to 19945, so a further regression needs its own waiver. Its reason records that this +28 is a CORRECTION to the same artifact's own +177, not new capability: the #1222 pair-write was gated on `i64_locals`, which carries body-inferred widths, so it fired on params homed narrow and clobbered the next param's home. Narrowing the arm cannot be done by deleting — the correct behaviour needs the declared-width test the original arm lacked. Refs #1189, #1222 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(oracle): RQ-65-ALIASCLASS (#1189) — re-pin the home-register audit to the REAL corpus; the 12 first-full-corpus hits were the walk, fixed in the walk The corpus sweep's first run WITH the suite submodule and the corrected ROOT (previous lane: suite-only, 4628 functions) read 8317 functions / 8776 homes and `hits: 12 (unexplained: 12)` plus 16 pinned #1226 hits that did not occur — RESULT: FAIL (3). Classified one by one, nothing silenced: SHAPE A (8) — AUDIT FALSE POSITIVE, walk fixed. `Pop { regs: [R4..R8, PC] }` at a mid-function `Return` (cabi_arena_{bind,realloc}.wat func_0, m4/m4f self) and at a function-level `BrIf(0)` (home_alias_class_1189_promo.wat p_brif, 4 legs), "writes R4 = home of local N, read again at op M". The inline epilogue restores a promoted local's r4 and RETURNS in the same instruction, so op M is unreachable from it. `write_is_terminal` scanned only PAST the writer (next instruction = another op's, or the br_if's own skip label) and never asked whether the writer IS the terminator. It does now; `Pop` has no conditional form in `ArmOp` and both encoders emit it unconditionally. The existing terminal test planted the home at R0, never at the register the pop restores — that is why the unit test did not see it; the new test plants R4. SHAPE B (4) — LEGITIMATE-BUT-SAFE, proven on the stream instead of pinned. `F32Load { sd: S0, addr: [SP, #24|#28] }` at op `Call(11)` (f32_ops_719.wat xhome/xcall2, m4f-reloc/-self): `vstr s0, [sp, #0x18] … bl … vldr s0, [sp, #0x18]` — the caller-save RESTORE of the f32 home from the slot the same op saved it to. The audit had not stated the AAPCS VFP caller-saved clobber (s0–s15) on calls, so the `bl` that makes the restore necessary was INVISIBLE and its restore surfaced as the write; a MISSING restore was invisible too. `vfp_defs` now lists s0–s15 on Bl/Blx/Call/CallIndirect (re-swept with it stated: 0 new hits — every VFP home live across a call on this corpus is saved and restored), and `write_is_bracketed_by_save_ restore` discharges the round trip only when save and restore name the identical register and static slot, the save precedes every other write of the home in the op, and nothing between them touches the slot, its base or control flow. Unit-tested: the exempt shape (incl. an argument marshalled INTO the home between save and restore) and 9 broken variants — no restore, other slot, overlapping store, disjoint store (fine), SP move, stale save, split op, label — as still-flagged. Executed: the CI-wired f32_ops_719_differential.py runs xhome/xcall2 on m4f under unicorn, 238/238 bit-exact vs wasmtime. Each exemption's negative-control build reproduces exactly its own shape and nothing else: pop check off -> the 8 pop hits, 0 other; round trip off (clobber stated) -> the 4 VFP functions, now reported at the `Bl`, 0 other. The fixed walk sweeps the IDENTICAL population (1045 pairs / 8317 / 8776 / 261440 attributed) to 0 hits. SHAPE C — the 16 #1226 pins stopped occurring because `declared_wide_params` (c14f53a) reads the SAME stale width table #1226 describes, so on `checkRange` the pair-write no longer fires and nothing lands on `$to`'s R1. Verified on the bytes: the gate removed the HIT, not the MISCOMPILE — `checkRange` still compares `$to` at R1:R2 (`cmp r0, r1; it eq; cmpeq r1, r2`; AAPCS passes it in R2:R3), `local.set $from` is back to the single-half `mov r0, r5` (the `adc r6` hi half dropped), and the `i64.const -1` return sets R0 only. #1226 stays OPEN (bytes on the issue); the pins are removed here because no sweep line can see the defect any more, and the script says so. Pins re-derived on the rebased tree with the submodule present (never carried textually): in-script FLOORS 1045/8317/8776/261440, the `ci-checks: stdout` header >= 8317, ci.yml greps `functions audited: 8317`, `homes watched: 8776`, `hits: 0 (known-open: 0 [none], unexplained: 0)`; exact emulation floor re-derived by oracle_wiring_check.py: 346751, unchanged; selector ratchets unchanged (home_alias.rs is outside the ceiling; claim_check --metric 63/63, status.json no drift). Artifact verified-by, docs/analysis table (the VFP call-clobber row was WRONG: "no home exists to alias" is true of core registers only), CHANGELOG and the waiver prose now state what was measured. Verified: cargo fmt --check, clippy --workspace --all-targets -D warnings, synth-synthesis 766 + suites 0 failed, CI-form sweep via oracle_run with the four exact greps ALL MATCH, home_alias_class_1189_differential.py 999 matched / 0 diverged / 1629 emulations PASS, f32_ops_719 238/238, status_evidence_check green, duplicate-key-strict YAML parse of ci.yml, the artifact and claims.yaml. Refs #1189, #1222, #1226, #1227 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(oracle): RQ-65-ALIASCLASS (#1189) — wire the audit's potency (plant probe, 192 exact) and pin #1226 red-first on its REAL mechanism: the .wast path threads no width tables Coordinator review of #1227: the sweep's `hits: 0` proved the sweep RAN (work floors), not that the DETECTOR FIRES — and after the walk was relaxed to clear 12 false positives that was the property under suspicion. Two additions, and one correction the second one forced. POTENCY, wired. `SYNTH_HOME_ALIAS_AUDIT=verbose,plant` makes `home_alias::plant_probe` plant ONE synthetic write of a watched home at op 0 of every function that has a home still read later (`mov <home>, r12` / `F32Const` into the S-slot, on a COPY of the stream; shipped bytes untouched). The corpus script's self-test phase runs first and requires, per (fixture, leg), EXACTLY the pinned number of declines carrying the needle at `op 0` — i32 params r0-r3 58/7/58/7, promoted locals r4-r8 11/9/11/9, VFP homes 0/0/11/11 (soft-float m4 has none) — and 0 declines without the plant: 192 planted writes reported, through the same decline / needle / parse path the sweep relies on. ci.yml greps `POTENCY: PASS (192 …)` exactly. (I first wrote 172 by hand; the script's derived total is 192 — the pin is the derived number.) The selector's audit hook collapsed to one call into `home_alias::selector_hook` (63 -> 12 lines; `selector_lines_code` 19945 -> 19896, a FALL, waiver bound to the value as the engine requires; `selector_lines_total` 30943 -> 30894). #1226, STATED PLAINLY — and corrected. The walk is correct and #1226 was never a home-register WRITE: it is a mis-HOMING, which this audit cannot see because it trusts the selector's home table by construction; the 16 hits it carried were the #1222 pair-write (fired by body inference) landing in the neighbour's wrongly assigned R1, removed by the declared-width gate changing the EMISSION, not the walk — no coverage of home writes was lost. Trying to pin it exposed that the issue's mechanism is wrong: the two-module repro MERGED and the same functions STANDALONE as `.wast` are equally wrong; the discriminator is the extension. The synth-cli `.wast` driver path returns `Vec::new()` for EVERY declared- width table (func/type ret_i64, params_i64/_f32/_f64, the f32/f64 return masks — each annotated "WAST fixture suite is i32-only"), so on ANY `.wast`, single-module too, an i64/f32/f64 param or result whose width body inference cannot recover is homed as i32. Measured: the same module text as `.wat` gives `second3` homes=4 and `mov r0, r2; mov r1, r3`; as a `.wast` homes=2 and `mov r0, r1`; `fac-opt` is rescued by inference. Static upper bound: 1393 exported spec-suite functions in 74 files carry a wide param or result. Pinned RED-FIRST in the same self-test: one fixture (`home_alias_width_1226.wast`), its last module derived at run time as a single `.wast` and as the identical `.wat`; `homes=` must be `wast < wat` on every leg — (7, 6, 8) relocatable, (4, 4, 8) self- contained; ci.yml greps `WIDTH-1226: known-open (... on 4 legs)`; a fix makes them equal and must flip the pin. CONSEQUENCE for #1222, recorded in CHANGELOG / artifact / docs: the pair-write is gated on the DECLARED width, so on `.wast` input it never fires — the spec-suite functions the #1222 entry named as fixed (fac-opt, loop `while`, type-param-i64, the 64-bit bulk-memory `checkRange`s) are NOT fixed; they are wrong for #1226's reason until #1226 is fixed. #1222 holds for `.wat`/`.wasm` input (its own fixtures, executed). Verified: fmt --check, clippy --workspace --all-targets -D warnings, synth-synthesis 766 + suites 0 failed (16 home_alias unit tests incl. the probe and S_REGS inverse), CI-form sweep via oracle_run with all SIX exact greps matching (POTENCY 192, WIDTH-1226 known-open, 8317 / 8776 / hits 0 / RESULT: PASS), exact emulation floor re-derived 346751 (unchanged: the self-test is stdout-declared), claim_check 63/63 with status.json regenerated, status_evidence_check green, duplicate-key- strict YAML on ci.yml / artifact / claims. Refs #1189, #1222, #1226, #1227 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(oracle): RQ-65-ALIASCLASS (#1226) — flip the width pin to CLOSED; #1232 landed the fix this pin was waiting for Rebased onto main after RQ-65-MVPCORE (#1232) merged, which is the fix this pin's own rule anticipated: "a fix makes (b) == (c), this goes red, and the fix flips the pin (known-open -> closed) in its own PR." RE-DERIVED on the merged tree with `--print-self-test`, not asserted. Every leg (merged-wast, single-wast, same-text-wat): before m4-reloc (7, 6, 8) m4-self (4, 4, 8) wast < wat, open after all four legs (0, 8, 8) wast == wat, merged refused Two independent routes, both now clean: the single-module `.wast` path threads declared widths so `wast == wat`, and the multi-module merge REFUSES an i64-param module so `merged == 0`. The assertion becomes EQUALITY plus that refusal, which is strictly stronger than the old inequality — a narrower `wast` OR the merge silently accepting again now goes red. POTENCY is untouched: 192 planted writes, 0 without the plant, across 3 fixtures x 4 legs. Self-test RESULT: PASS on the rebased tree. Artifact prose corrected where it had become FALSE rather than merely dated: "#1226 stays OPEN" and "not fixed here" were true when written and are not now. The spec-suite functions the artifact said were "NOT fixed by #1222 and stay so until #1226 is fixed" ARE now correct, because #1226 is fixed. What remains of #1226 is a REACH note, not a correctness one: the merge refuses i64-param modules it previously accepted and mis-compiled — decline-honesty with the acceptance cost stated. Emulation floor re-derived on the rebased tree: 346751, unchanged. Refs #1189, #1226, #1232 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(oracle): RQ-65-ALIASCLASS (#1189) — re-derive the audit's corpus floors after #1232; the population fell because modules are now REFUSED CI on the rebased tree reported the pin flip working — `WIDTH-1226: closed`, `POTENCY: PASS (192 planted writes, 0 without the plant)`, `hits: 0` — and then failed on the population floors, correctly: VACUOUS — declared floor stdout >= 8317, measured 7191 That is the floor doing its job. The cause is not scan rot: RQ-65-MVPCORE (#1232) merged first and makes the multi-module `.wast` merge REFUSE modules it would mis-handle (i64 params, data segments, accessed globals) instead of silently mis-compiling them. A refused module audits no functions, so this oracle's corpus shrank with them: modules compiled 1045 -> 940 (-105 refused) functions audited 8317 -> 7191 (-13.5 %) homes watched 8776 -> 8100 attributed instrs 261440 -> 219807 Re-derived from CI's own run on the merged tree, not computed. The floors move DOWN exactly once, here, with that reason written beside them in the script, the artifact and ci.yml; a further fall without a reason is scan rot and stays red. This is worth stating plainly rather than quietly re-pinning: it is the ACCEPTANCE COST of decline-honesty, measured. #1232 traded reach for correctness, and one place the bill lands is that a correctness oracle now watches 13.5 % fewer functions. Emulation floor unaffected (this oracle declares `stdout`, not `emulations`) and re-derived at 346751 on the rebased tree. Refs #1189, #1226, #1232 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
… introduced instead of carrying it Rebased onto main after RQ-65-ALIASCLASS (#1227) and RQ-65-MVPCORE (#1232). ci.yml conflicted because both PRs inserted a job at the same point; resolved by taking main's file whole and re-inserting the mutation job after the home-alias-audit job, then verifying BOTH parse and are present (64 jobs). CHANGELOG kept one `[Unreleased]` header with both bodies. MEASURED on the rebased tree, not assumed. #1232 grew crates/synth-cli/src/main.rs 11143 -> 11405 and mutation sites are anchored by file:line:col: sites enumerated 1542 ci_subset entries still resolving 7 of 7 (3 controls + 4 mutants) R5-startup mutants still resolving 0 of 7 THE LIVE GATE IS INTACT, and for a structural reason worth recording: the three controls come from `control_sites()` rather than a line anchor, and the four subset mutants live in optimizer_bridge.rs / liveness.rs / arm_backend.rs, which #1232 did not touch. `mutation-survey-discrimination` still replays real mutations and still fails if a recorded killer stops killing. WHAT IS STALE, said in the report rather than fixed silently: all seven R5-startup mutants point at moved code. They are 7 of the 21 byte-changing mutants the rate is computed over (6 KILLED, 1 UNTESTED) — and that one UNTESTED is one of the FOUR published survivors. So the 19 % stands as a measurement of the tree it names, a third of its denominator is not replayable on main, and re-anchoring R5 is follow-up work rather than a re-run: #1232 restructured that region, so "the equivalent site" is a judgement, not a line-number shift. A survey whose denominator quietly stops being checkable is the failure this release exists to name. Recording it is the point. Floor re-derived on the rebased tree: 346751, unchanged (this job declares no emulations). Ratchets unmoved; mutants_untested 4 = pinned. Refs #1189, #1232, #1227 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…hat drifted; the baseline moved, not the site CI failed the survey's own replay with `changed-set moved: 53 vs ledger 49`. That is the gate working: all three controls still died to their recorded killers, both the EQUIVALENT and DEAD entries reproduced, and exactly one entry disagreed. CAUSE, measured rather than guessed. The site did not move. The BASELINE did: 13 of 609 corpus entries differ on the merged tree after #1232 and #1227, so the mutation's blast radius moved with them. Byte triage re-derived on the merged tree gives 53, and CI and a local run agree at 53 independently. Applied to both the mutant record and the ci_subset entry. `reanchor` separately relocated all 15 line-shifted sites by their stored `before` TEXT (0 not found), so last commit's "R5 mutants are not replayable" is obsolete and the report section is rewritten with the measured figures. NOT RE-VERIFIED, AND THE REPORT SAYS SO: that mutant's CLASSIFICATION was measured at `meta.commit` and is not re-established here. The CI replay checks byte triage for UNTESTED entries, not the oracle suite (that needs --full). The published rate stays relative to the commit the ledger names. A LOCAL FULL RE-SURVEY WAS ATTEMPTED AND DISCARDED AS INVALID, recorded because the near-miss matters: 147 of the 196 L1 steps invoke bare `python`, absent on this machine, so they exit 127 in 0.1s and the harness scores that as a KILL; and `fact_spec_div_494_differential.py` is red on the UNMUTATED tree here while green in CI. That run reported 0 of 29 surviving — dead oracles, not a result. The harness's own control check refused it: "1 control(s) not killed — the survey measures nothing; do not publish the rate". A gate that stops its author publishing a flattering number is the one worth having. Refs #1189, #1232, #1227 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…changing mutants survive a named suite (19 %, upper bound); 3 controls KILLED; survivors enumerated; ledger CI-pinned (#1233) * feat(mutants): RQ-65-MUTANTS (#1189) — mutation survey: 4 of 21 byte-changing mutants survive a named 5-job suite + workspace tests (19 %, upper bound); 3 red-first controls KILLED; survivors enumerated; ledger CI-pinned The v0.65 headline number, measured rather than asserted. scripts/mutation_survey.py flips one codegen decision at a time (REG / COND / DROPMOV / IMM / GUARD / BOUND) over five anchor-located regions supplied by RQ-65-PARITY, rebuilds, triages by emitted bytes over 200 corpus modules x 3 ARM configurations, and runs a suite DERIVED from ci.yml only on byte-changing mutants. Measured at 580d53f, re-anchored at 761c692, seed 1189: 38 drawn, 6 uncompilable, 32 compiled, 21 byte-changing; 17 KILLED (6 execution, 8 structure, 2 freeze-only, 1 compiler hang), 4 UNTESTED = 19 % survival relative to the NAMED suite (wast-conformance, repro-sweep-arm-corpus, join-alias-1189, cmp-select, frame-slot-dce-242 + cargo test --workspace) — an upper bound under the full CI board. 11 byte-identical: 5 EQUIVALENT, 4 DEAD, 2 UNRESOLVED (declared). Controls: the #1189 copy disabled, the select operands swapped, the startup R10 seed into R9 — all KILLED (the third only by byte goldens: no execution oracle in the suite boots the shipped Reset_Handler). CI pin: the mutation-survey-discrimination job replays the ledger's ci_subset (3 controls + 4 non-killed) and fails in either direction; claims.yaml gains the eighth kind: ratchet (mutants_untested, a ceiling over docs/status/mutation_survey.json) plus count-eq pins on 38 / 21 / 4, the controls and the subset floors. No new emulation declaration; the exact floor is untouched. Refs #1189 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * docs(mutants): RQ-65-MUTANTS (#1189) — record PR #1233 in the artifact's landed field Refs #1189 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * docs(mutants): RQ-65-MUTANTS (#1189) — state the ledger staleness #1232 introduced instead of carrying it Rebased onto main after RQ-65-ALIASCLASS (#1227) and RQ-65-MVPCORE (#1232). ci.yml conflicted because both PRs inserted a job at the same point; resolved by taking main's file whole and re-inserting the mutation job after the home-alias-audit job, then verifying BOTH parse and are present (64 jobs). CHANGELOG kept one `[Unreleased]` header with both bodies. MEASURED on the rebased tree, not assumed. #1232 grew crates/synth-cli/src/main.rs 11143 -> 11405 and mutation sites are anchored by file:line:col: sites enumerated 1542 ci_subset entries still resolving 7 of 7 (3 controls + 4 mutants) R5-startup mutants still resolving 0 of 7 THE LIVE GATE IS INTACT, and for a structural reason worth recording: the three controls come from `control_sites()` rather than a line anchor, and the four subset mutants live in optimizer_bridge.rs / liveness.rs / arm_backend.rs, which #1232 did not touch. `mutation-survey-discrimination` still replays real mutations and still fails if a recorded killer stops killing. WHAT IS STALE, said in the report rather than fixed silently: all seven R5-startup mutants point at moved code. They are 7 of the 21 byte-changing mutants the rate is computed over (6 KILLED, 1 UNTESTED) — and that one UNTESTED is one of the FOUR published survivors. So the 19 % stands as a measurement of the tree it names, a third of its denominator is not replayable on main, and re-anchoring R5 is follow-up work rather than a re-run: #1232 restructured that region, so "the equivalent site" is a judgement, not a line-number shift. A survey whose denominator quietly stops being checkable is the failure this release exists to name. Recording it is the point. Floor re-derived on the rebased tree: 346751, unchanged (this job declares no emulations). Ratchets unmoved; mutants_untested 4 = pinned. Refs #1189, #1232, #1227 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * fix(mutants): RQ-65-MUTANTS (#1189) — re-derive the one changed-set that drifted; the baseline moved, not the site CI failed the survey's own replay with `changed-set moved: 53 vs ledger 49`. That is the gate working: all three controls still died to their recorded killers, both the EQUIVALENT and DEAD entries reproduced, and exactly one entry disagreed. CAUSE, measured rather than guessed. The site did not move. The BASELINE did: 13 of 609 corpus entries differ on the merged tree after #1232 and #1227, so the mutation's blast radius moved with them. Byte triage re-derived on the merged tree gives 53, and CI and a local run agree at 53 independently. Applied to both the mutant record and the ci_subset entry. `reanchor` separately relocated all 15 line-shifted sites by their stored `before` TEXT (0 not found), so last commit's "R5 mutants are not replayable" is obsolete and the report section is rewritten with the measured figures. NOT RE-VERIFIED, AND THE REPORT SAYS SO: that mutant's CLASSIFICATION was measured at `meta.commit` and is not re-established here. The CI replay checks byte triage for UNTESTED entries, not the oracle suite (that needs --full). The published rate stays relative to the commit the ledger names. A LOCAL FULL RE-SURVEY WAS ATTEMPTED AND DISCARDED AS INVALID, recorded because the near-miss matters: 147 of the 196 L1 steps invoke bare `python`, absent on this machine, so they exit 127 in 0.1s and the harness scores that as a KILL; and `fact_spec_div_494_differential.py` is red on the UNMUTATED tree here while green in CI. That run reported 0 of 29 surviving — dead oracles, not a result. The harness's own control check refused it: "1 control(s) not killed — the survey measures nothing; do not publish the rate". A gate that stops its author publishing a flattering number is the one worth having. Refs #1189, #1232, #1227 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
RQ-65-MVPCORE (#1017) — the MVP-core row, re-derived on the path the oracles execute
Refs #1017, #1225, #1046, #1217. Filed on the way: #1225, #1229, #1230, #1231.
The measured delta, stated plainly (per backend,
ok/partial)580d53f9)okThe reach increment (start-function invocation) moved ZERO files on every backend. Its four sole-blocker files are multi-module (
start,annotations,binary) or a multi-memory twin (start0). The gain is module-level, in the parity oracle's own line:start-function modules: 4 seen, 2 both-accepted and booted ..., 10 assertion(s) ok— 0 both-accepted on the compiler before it. That is the file-vs-module gap v0.63's caution predicted, measured rather than assumed.The row went down, and every mover was inspected: losses are refusals of objects that were wrong (
int_exprsi64 signatures,const402 f32/f64-result modules,stackaccessed globals,binary-leb128/memory/address/float_memorydata — aarch64 refuses data-carrying modules on the real path since v0.53); gains are first real compiles (nop/load→okon arm once a realcall_indirecttable reached the backend; on aarch64f32,f32_bitwise,f32_cmp,f64_bitwise,f64_cmp,float_misc,conversions→ok, and 12 core files from whole-file refusal topartial).Why both numbers in "14 / 114" were properties of the instrument
address0,load0..2,memory_size0..3,data0/1,imports0..4,start0, ... — content-verified at 2..21 memories per module, suite commit4b24564) and 3 relaxed-SIMD lane files sat in MVP core becausespec_compile_census.py's family regexes predate the Wasm 3.0 merge (^multi.?memory|^memory_multimatched none;^data\bcannot matchdata0). MVP core is 80 files;multi-memoryis a family row and aFAMILY_OK_PINSentry. v0.63's top arm blocker (17 files sole) was a multi-memory decline mis-filed as scalar-core.synth compile file.wast— the census invocation — took the multi-module MERGE branch, written for synth's i32-only fixture suite and saying so beside everyVec::new()it passes. It handed the backends empty data segments, empty globals (the Cortex-M startup never wrote R9), i32-only signature tables and a default aarch64 substrate. One module compiled as.wastvs.wat: no data bytes and no R9 write on the.wastleg whileget_gwasldr.w r4, [r9]on both;tests/wast/i64_arithmetic.wast'si64.addon two i64 params lowered asadds r3, r0, r1(param 0's low half plus its own high half). Exit 0, countedok. The parity oracle compiles per-module.wat— the other path — so the number the project planned from was measured on objects no oracle runs (the shape The spec-suite gap was declared closed by a COMPILE census — the behavioural half stayed open and nothing sampled it until #197 #1217 asks to sweep for).Oracles landed FIRST, both red before
scripts/repro/wast_single_module_path_identity_1225.py(new, wired into theSpec Suiteworkflow,# ci-checks: compiles >= 600): a single-module.wastmust compile to exactly the bytes its module compiles to alone, three backends. Red on the pre-fix driver: arm 49 / riscv 33 / aarch64 56 of 140 mismatched. Then the driver routes a single-module.wastthrough the single-module path → 140 / 140 / 140 identical, RESULT PASS; the multi-module merge REFUSES a module carrying active data segments, accessed globals or a non-i32 signature over the functions it would retain (refuse_wast_merge_unrepresentable).selector_parity_197_differential.pystopped declining(start ...)modules and gainedSTART_MODULES_FLOOR. Red on the pre-invocation compiler (--only start: 4 seen, 0 both-accepted, both legsmodule-decline). Then the self-contained Cortex-MReset_HandlerBLs the start function after the data copy and the R9 table, before the entryBLX r0(a BL, neverBLX r0— the oracle's boot scanner stops at the firstblx r0), patched post-layout viaencode_thumb_bl; the closure is seeded with it. Green after: 2 both-accepted and booted, 10/10 assertions ok (getobserves threeincs from the start function on both selectors and in wasmtime), 0 divergences. Every other path —--relocatable, ET_REL degradation via imports (checked after compilation), an imported start, the single-function path, A32, RISC-V, AArch64 (neither of the last two emits a startup) — keeps the ALL backends SILENTLY DROP the (start ...) function — exit 0, never compiled, never run (same silent-drop class as #1041) #1046 refusal;start_section_refusal_1046.rspins both halves (10/10, two new refusals).Declined with measured reasons (
docs/status/SPEC_FAMILY_CENSUS.md, ranked on the v0.65 path)--cortex-mtarget: the same 80 files on--target cortex-m7dpmeasure 17 / 22 vs 12 / 21 — changing the invocation would move every pin to flatter one target;br_tablewith value-carrying targets (2 sole, 13 files, 90 functions), visible now that the merge's "declares no globals" refusal no longer hides it;call_indirectself-contained dispatch stays silicon-gated (fix(#275): self-contained --cortex-m call_indirect — loud-decline the R11/linmem silent miscompile #717); multi-memory in a self-contained image is a multi-memory decline (Multi-memory phase 2: per-memory MPU isolation is unreachable — --safety-bounds mpu and multi-memory have disjoint paths #1145, no memory-k oracle);VCR-RA-003 JoinValueNotAvailable, a caught would-be miscompile), aarch64 selector: operand-class confusion — 'local.set: expected GP operand, got FP' / 'fcompare: expected FP operand, got GP' across the float MVP-core files #1231 (aarch64 GP/FP operand class).Pins moved with the measurement, together
Census
PINS/AT_LEAST_ONE_EXPORT/FAMILY_OK_PINS(whole-suiteok22 / 12 / 27 → 16 / 9 / 21; at-least-one-export 84 / 74 / 57 → 47 / 43 / 47;other_error0 / 0 / 0 — the VCR-MEM-002multi-memory (#406)decline family reaches the census for the first time and is classified by its tag), README row,feature_matrix.md.tmpl(FEATURE_MATRIX.md regenerated byclaim_check.py --emit-status),claims.yaml(SYNTH-SPEC-FAMILY-MVP-CORE,SYNTH-SPEC-SUITE-CENSUS-README/-MATRIX, a new count-min on the identity oracle's wiring). Emulation floor re-derived on the rebased tree byoracle_wiring_check.py: equal to the ci.yml/claims pin, so it does not move (the new oracle declares acompilesfloor).Note on generation:
SPEC_FAMILY_CENSUS.mdis TRANSCRIBED from the census's per-family stdout (the v0.63 cold review corrected "generated" to "transcribed";FAMILY_OK_PINSin the script is the gate that reddens the census when a family count moves).FEATURE_MATRIX.mdIS generated and was regenerated from the template.Gates run on the rebased tree (
761c6922+ this branch), release binary rebuilt therescripts/spec_compile_census.py: RESULT PASS on the new pins, all three backends (MVP core 80 files: arm 12 / 21, riscv 9 / 23, aarch64 18 / 20;other_error0 / 0 / 0).scripts/repro/wast_single_module_path_identity_1225.py: RESULT PASS, 140 / 140 / 140 identical, 420 file-backend pairs compared.scripts/repro/selector_parity_197_differential.py, full corpus: RESULT PASS — 330 modules both-accepted, 19155/19155 assertions in parity, 622 pinned divergences across 103 pins (RQ-65-DECLINE's converted pins merged), 0 unpinned;start-function modules: 4 seen, 2 both-accepted and booted ..., 10 assertion(s) ok, 0 divergences. (Pre-rebase tree: also PASS, 722 pinned across 108 pins.)cargo test --workspace: 80 test binaries, 1293 passed, 0 failed.cargo clippy --workspace --all-targets -- -D warnings: clean.cargo fmt --check: clean.scripts/status_evidence_check.py: 0 failures (5 delivery-shaped commits in the window, 5 attributed; live floor restated 0 times).scripts/claim_check.py claims.yaml: 63/63 hold;--emit-statusleaves every generated file unchanged.scripts/oracle_wiring_check.py: every script declared and wired; the derived emulation floor equals the ci.yml/claims pin, so it does not move.rivet validate: 40 errors — the pre-existing cross-repo baseline; this artifact adds no links.Both pushes went through one
&&chain (fmt, clippy-D warnings, evidence check, claim check, push).🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L