Repository navigation
v0.82 JESSDIVERGE4 lane (#1436): the named measurement was half a measurement - #1487
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
avrabe
force-pushed
the
lane/v0.82-jessdiverge4
branch
from
October 8, 2026 04:22
3d4a5ec to
7d0cbde
Compare
avrabe
added a commit
that referenced
this pull request
Oct 8, 2026
…surement THE ASK IS SIX WORDS AT SIX PCs, NOT THREE SLOTS. Derived from the module's own disassembly, digests verified against the thread (c.wasm d854e5bb…, c.loom.wasm 791ab6b5…), each of the three gravity blocks reads TWO operands and the slots carried forward from v0.81 are only the MULTIPLICANDS: pc 0x2498 -> offset 940 ADDEND [sp,#200] @0x2490 MULTIPLICAND [sp,#152] @0x2494 pc 0x24c4 -> offset 936 ADDEND [sp,#216] @0x24bc MULTIPLICAND [sp,#232] @0x24c0 pc 0x24f0 -> offset 944 ADDEND [sp,#192] @0x24e8 MULTIPLICAND [sp,#208] @0x24ec Two independent reasons three words could not answer the lane's question. A wrong ADDEND and a wrong MULTIPLICAND are INDISTINGUISHABLE in the stored result, so sampling only the multiplicands cannot name which operand is wrong. And these are general-purpose spill homes, not dedicated operand slots: [sp,#152] is referenced 130 times in this object, [sp,#208] 34, [sp,#232] 20 — so "the value of [sp,#152]" names no single value and each word must be sampled AT THE PC OF ITS OWN LOAD. WHAT THIS LANE DID NOT OBTAIN, STATED PLAINLY IN THE ARTIFACT. The runtime values were NOT measured: qemu-system-arm and qemu-arm are both absent on the release machine and the reporter's repository is not cloned here, so the image cannot be executed. A request naming the six PCs was DRAFTED AND NOT SENT — it is correspondence with an external reporter, surfaced to the maintainer rather than posted by the loop. The thread stands at ten comments and this release added none. THE REFUTING COMMAND HELD: the shipped oracle still reports the lowering FAITHFUL (9 assertions, 0 failures) with every refuted mechanism injectable, so v0.81's refutation stands and the premise is intact. THREE INSTRUMENT ERRORS, RECORDED RATHER THAN BURIED. A first grep reported FOUR materializations of 9.81f; truncation by `head -8` hid five, and the real count is NINE. A first store-offset attribution gave {932, 940, 936} and briefly made the carried claim look wrong; the scan window began BEFORE its own anchor and picked up the preceding block's `addw`. Forward-only scanning gives 940, 936, 944 — CONFIRMING the carried claim. The brief was right and the first measurement was not. Also corrected in the artifact: the done-when now demands all six words at their six PCs, and the sentence calling three words "the whole lane" is gone. THE CLAIM SHAPE WAS WRONG ON THE FIRST PUSH, AND CI CAUGHT IT. This artifact first went out as `status: implemented` with `issue-scope: outlives` and a PARTIAL verdict. #1487 reddened on `Claim Check` — a REQUIRED context — because `verdict_prose_check` reds an INCOMPLETE prose verdict beside a claiming status with no `disposition`, while R11 FORBIDS a disposition beside a claiming status. `LEGAL_BESIDE_CLAIMING` has exactly ONE member, `REFUTED`, so A LANE THAT NARROWS HAS NO LEGAL CLAIMING VERDICT AT ALL. The gates permit a strictly safer shape and nothing pointed at it: status: proposed disposition: partial landed: <the increment> issue-scope: OMITTED R4-lane satisfied by `landed:` — its own message is a disjunction, "flip the status OR record the increment" R11 satisfied: a `disposition` IS present beside a NON-claiming status R12 `outlives` beside non-claiming would RED, so `issue-scope` is omitted verdict_prose incomplete + non-claiming passes; no carve-out needed R14 status not claiming, so out of population R3 cannot fire on a `manual:` done-when Under this shape #1436 is NEVER placed in the authorised close set at all, where the claiming shape authorises retirement and then relies on `issue-scope` to take it back. That is a better answer to #1484 than the rule this release shipped for it, and R14 is looser than its sibling: it accepts any of the 7 INCOMPLETE tokens given a declaration, where `verdict_prose` accepts 1 — a conjunction defect introduced by the fix for conjunction defects, recorded rather than quietly corrected. AND THE PRE-PUSH CHECK THAT MISSED IT: CHECK4's squash simulation runs 2 scripts (`merge_gate`, `status_evidence`); the `Claim Check` job runs 33. A green CHECK4 is a true statement about a narrower subject. This push is verified against the artifact-gate subset of that job, with CI's own flags. Refs #1436 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…surement THE ASK IS SIX WORDS AT SIX PCs, NOT THREE SLOTS. Derived from the module's own disassembly, digests verified against the thread (c.wasm d854e5bb…, c.loom.wasm 791ab6b5…), each of the three gravity blocks reads TWO operands and the slots carried forward from v0.81 are only the MULTIPLICANDS: pc 0x2498 -> offset 940 ADDEND [sp,#200] @0x2490 MULTIPLICAND [sp,#152] @0x2494 pc 0x24c4 -> offset 936 ADDEND [sp,#216] @0x24bc MULTIPLICAND [sp,#232] @0x24c0 pc 0x24f0 -> offset 944 ADDEND [sp,#192] @0x24e8 MULTIPLICAND [sp,#208] @0x24ec Two independent reasons three words could not answer the lane's question. A wrong ADDEND and a wrong MULTIPLICAND are INDISTINGUISHABLE in the stored result, so sampling only the multiplicands cannot name which operand is wrong. And these are general-purpose spill homes, not dedicated operand slots: [sp,#152] is referenced 130 times in this object, [sp,#208] 34, [sp,#232] 20 — so "the value of [sp,#152]" names no single value and each word must be sampled AT THE PC OF ITS OWN LOAD. WHAT THIS LANE DID NOT OBTAIN, STATED PLAINLY IN THE ARTIFACT. The runtime values were NOT measured: qemu-system-arm and qemu-arm are both absent on the release machine and the reporter's repository is not cloned here, so the image cannot be executed. A request naming the six PCs was DRAFTED AND NOT SENT — it is correspondence with an external reporter, surfaced to the maintainer rather than posted by the loop. The thread stands at ten comments and this release added none. THE REFUTING COMMAND HELD: the shipped oracle still reports the lowering FAITHFUL (9 assertions, 0 failures) with every refuted mechanism injectable, so v0.81's refutation stands and the premise is intact. THREE INSTRUMENT ERRORS, RECORDED RATHER THAN BURIED. A first grep reported FOUR materializations of 9.81f; truncation by `head -8` hid five, and the real count is NINE. A first store-offset attribution gave {932, 940, 936} and briefly made the carried claim look wrong; the scan window began BEFORE its own anchor and picked up the preceding block's `addw`. Forward-only scanning gives 940, 936, 944 — CONFIRMING the carried claim. The brief was right and the first measurement was not. Also corrected in the artifact: the done-when now demands all six words at their six PCs, and the sentence calling three words "the whole lane" is gone. THE CLAIM SHAPE WAS WRONG ON THE FIRST PUSH, AND CI CAUGHT IT. This artifact first went out as `status: implemented` with `issue-scope: outlives` and a PARTIAL verdict. #1487 reddened on `Claim Check` — a REQUIRED context — because `verdict_prose_check` reds an INCOMPLETE prose verdict beside a claiming status with no `disposition`, while R11 FORBIDS a disposition beside a claiming status. `LEGAL_BESIDE_CLAIMING` has exactly ONE member, `REFUTED`, so A LANE THAT NARROWS HAS NO LEGAL CLAIMING VERDICT AT ALL. The gates permit a strictly safer shape and nothing pointed at it: status: proposed disposition: partial landed: <NAMES THE DELIVERING PR> issue-scope: OMITTED R4-lane satisfied by `landed:` — its own message is a disjunction, "flip the status OR record the increment" — BUT ONLY IF the text names the PR the gate DERIVES. MEASURED, after this lane red on it: `_acknowledge` takes `PR_NUMBER.findall(subject)[-1]` with `PR_NUMBER = r"\(#(\d+)\)"` — the LAST PARENTHESISED number in the squash subject, which is the one the SQUASH APPENDS, i.e. THIS PR — and requires it in `landed_prs(fields)`. My first `landed:` named #1436, the ISSUE, and satisfied nothing. And no local run could have told me: R4-lane needs a DELIVERY COMMIT ON MAIN, so it cannot fire in the checkout at all — only in CHECK4's squash simulation. The local "ALL PASS" was a true statement about a tree with no delivery commit. R11 satisfied: a `disposition` IS present beside a NON-claiming status R12 `outlives` beside non-claiming would RED, so `issue-scope` is omitted verdict_prose incomplete + non-claiming passes; no carve-out needed R14 status not claiming, so out of population R3 cannot fire on a `manual:` done-when Under this shape #1436 is NEVER placed in the authorised close set at all, where the claiming shape authorises retirement and then relies on `issue-scope` to take it back. That is a better answer to #1484 than the rule this release shipped for it, and R14 is looser than its sibling: it accepts any of the 7 INCOMPLETE tokens given a declaration, where `verdict_prose` accepts 1 — a conjunction defect introduced by the fix for conjunction defects, recorded rather than quietly corrected. AND THE PRE-PUSH CHECK THAT MISSED IT: CHECK4's squash simulation runs 2 scripts (`merge_gate`, `status_evidence`); the `Claim Check` job runs 33. A green CHECK4 is a true statement about a narrower subject. This push is verified against the artifact-gate subset of that job, with CI's own flags. Refs #1436 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
avrabe
force-pushed
the
lane/v0.82-jessdiverge4
branch
from
October 8, 2026 05:56
7d0cbde to
f03f598
Compare
avrabe
added a commit
that referenced
this pull request
Oct 8, 2026
…on defects was one (#1488) R14 shipped keying on the whole INCOMPLETE set and was therefore LOOSER THAN ITS SIBLING BY SIX OF SEVEN TOKENS. `verdict_prose_check` reds an incomplete prose verdict beside a claiming status with no `disposition:` for every token EXCEPT `LEGAL_BESIDE_CLAIMING`, which has exactly ONE member, REFUTED. R11 FORBIDS the `disposition:` that would satisfy verdict_prose beside a claiming status. So for those six tokens there is no legal claiming shape at all, and R14 firing there told authors to ADD A DECLARATION when the only correct answer is TO STOP CLAIMING. A rule written to catch "two rules whose conjunction is false" was one. Measured, not argued: INCOMPLETE has 7 members, LEGAL_BESIDE_CLAIMING has 1, so the two gates disagreed on 6 — and this release pushed `PARTIAL` + `implemented` + `issue-scope: outlives`, which satisfied R14 and reddened `Claim Check`, a REQUIRED context, on #1487. NARROWED to the carve-out, IMPORTED as the same object (asserted by identity, not equality): R14 now fires only where `verdict_prose` is SILENT and a claiming status AUTHORISES closure — which is exactly v0.81's near-miss shape, REFUTED beside implemented with no declaration. AND THE SAFER SHAPE IS NOW PINNED BY A TEST, because nothing in the repo pointed at it: status: proposed disposition: partial landed: <names the delivering PR> issue-scope: OMITTED R4-lane satisfied by `landed:` — its message is a DISJUNCTION, "flip the status OR record the increment" — provided the text names the PR `_acknowledge` derives, which is `PR_NUMBER.findall(subject)[-1]`, the number the SQUASH appends R11 a `disposition` IS present beside a NON-claiming status R12 `outlives` beside non-claiming would RED, so `issue-scope` is omitted verdict_prose incomplete + non-claiming passes; no carve-out needed R14 out of population R3 cannot fire on a `manual:` done-when Under that shape the issue is NEVER placed in the authorised close set, where the claiming shape authorises retirement and then takes it back with a second field. THREE MUTANTS, each killed by the test that owns it: * R14 disabled -> the two red-first tests fail * R14 WIDENED back to INCOMPLETE -> the carve-out test AND the identity test fail * as shipped -> 128 tests OK Refs #1484 Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
avrabe
added a commit
that referenced
this pull request
Oct 8, 2026
…ded field `_acknowledge` derives `PR_NUMBER.findall(subject)[-1]` — the last PARENTHESISED number in the squash subject — and that number differs by CONTEXT: on the lane branch it is the ISSUE, after the squash it is the DELIVERING PR. A `landed:` naming only one of the two is red in the other context, which this release learned the hard way on #1487. This wave's subject names no single lane, so R4-lane does not fire on it (verified in a squash simulation off origin/main, rc=0, 0 FAIL lines, rather than assumed). The stamp is therefore for the RECORD rather than for the gate: each artifact now names both its issue and the PR that delivered the increment. Applied by a script that asserts `count == 1` per edit and reports PER ARTIFACT, because an aborting batch leaves a MIXTURE — dry-run on all eight first, gates re-checked, idempotence confirmed, then reverted before the real run. Refs #1458 #1439 #1456 #1136 #1441 #1460 #1453 #965 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
avrabe
added a commit
that referenced
this pull request
Oct 8, 2026
… is the binding constraint (#1492) * v0.82 VALUELESSKEY lane (#1458): removing the idiom DISARMED the gate that derives its population from it THE REFUTING COMMAND RAN FIRST AND DID NOT REFUTE: the idiom is live, `str(None).strip()` is still `'None'`, and PyYAML still yields None for a bare key. THE POPULATION, DERIVED WITH `ast` AND NOT A REGEX, and it REPRODUCED this artifact's own figure: 32 unguarded `str(<expr>.get(...))` calls across `scripts/**/*.py` (15 more already `or`-guarded, excluded BY CONSTRUCTION). The done-when's narrower set — read, then TESTED for truth or membership — is 15 AT ONE HOP, and the walker says it is one-hop: a 16th, `str(art.get("status",""))`, reaches `status in CLAIMING` at a SECOND hop through the loaded tuple, so 15 is a FLOOR, not an exact figure. That 16th is also immune, because neither `"None"` nor `""` is in the status vocabulary. AFTER: 17 unguarded, truth-tested 15 -> 2. v0.81'S OWN REMEDY IS WRONG IN THE OTHER DIRECTION, and this is the class behind the instance. All five v0.81 fixes used `str(x.get(k) or "")`, which reads a legitimate `0` or `False` as ABSENT — the sentinel/value-`0` collision this project has corrected across three releases. HONEST SCOPE: no current site can receive a falsy non-None value, every key in the population being string-valued by schema. So it is a property of the IDIOM, not a live defect; `field_str` removes the question rather than leaving it to the next author. ONE LATENT HOLE IN A REQUIRED GATE. `Claim Check` refuses a waiver with no reason via `if not str(w.get("reason", "")).strip()`. A `reason:` written BARE parses to None, reads as `"None"`, and THE WAIVER READS AS JUSTIFIED. Shown both ways on one input: old idiom `'None'` -> accepted; accessor `''` -> refused. AND THE FINDING THAT IS THIS RELEASE'S THEME IN THE MIRROR. Replacing the idiom BROKE R13. `_derive_field_keys` DERIVES R13's enforced key set by ast-walking the consumers for `fields.get("literal")` — so removing that shape silently dropped `issue-scope`, `landed` and `disposition`. Three of R13's four unit tests went red while the module's ANTI-VACUITY GUARD STAYED GREEN, because it tests only EMPTINESS. That is the exact defect `_derive_field_keys`'s own docstring already names ("the anti-vacuity guard only tests non-emptiness ... the very 'cannot see population shrinkage' defect") — reached through the fix for a different one. Satisfying one gate DISARMED another, and only another rule's tests noticed. BOTH REMEDIES, because either alone is insufficient: * FIELD_ACCESSORS teaches the derivation that `field_str`/`field_text` ARE field reads, so a normalisation does not narrow R13 * FIELD_KEYS_FLOOR a DECLARED SUBSET of the derived set: losing a key REFUSES and names it, while ADDING one stays free. Without it the next normalisation re-breaks R13 silently; without FIELD_ACCESSORS the floor turns every normalisation into a stop the author must widen. POTENCY, PAIRED — AND THE FIRST CONTROL WAS REJECTED. Mutating one `landed` read gave rc=1, but from R4, not the floor: `landed` is read TWICE so the key was never lost. A changed output via a DIFFERENT rule is as misleading as an unchanged one. Re-run on `shipped-in` — the only key read exactly once — the floor fired with its own message naming `['shipped-in']`, rc=0 on restore. The tripwire forbidding the raw idiom in the artifact gates was proven red-first ONCE PER GATE by reverting one site in each, and its recognizer carries a POSITIVE CONTROL, because a tripwire asserting ZERO must be shown able to find one. DECLARED TOLERANT RATHER THAN FIXED, named so the exclusion is not silent: `cr["name"]` in loop_conformance_check (GitHub JSON — None means the API omitted it, and `.startswith` on `"None"` and `""` fail identically) and `manifest["safety_bounds"]` in repro/bulk_mask_679_differential (membership in a closed two-word vocabulary). Both immune, neither in an artifact gate. ONE CONSTRAINT FOUND AND RESPECTED: `test_mcdc_gate.py` runs a MUTATED COPY of the gate in a temp dir, so a sibling import does not resolve. The sibling is staged beside the copy — keeping the normalisation single-sourced instead of mirroring it — and the mutation test was RE-PROVEN POTENT afterwards by breaking the gate's refusal string and watching it fail. 26 call sites across FOUR gates now read through the one accessor. Gates: 31 of 31 Claim Check scripts pass, 75/75 claims hold, test_status_evidence_check 132 OK (6 new), test_mcdc_gate OK. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: partial` + `landed:` naming the delivering PR, `issue-scope` OMITTED. #1458 is already CLOSED (retired by v0.81), so this is carried analysis and places nothing in any close set. Refs #1458 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 BAZELPOTENCY lane (#1456): the artifact said two cold builds; the job runs in two MINUTES THE REFUTING COMMAND RAN FIRST AND DID NOT REFUTE. The protection API still lists nine required contexts with `Bazel Build & Proofs` among them; `~/.cache/bazel` DOES NOT EXIST so the cache is cold as recorded; nix answers 2.33.1 after sourcing `nix-daemon.sh`; bazel is on PATH. Every stated precondition holds. The gate stays recorded UNPROVEN — no paired control was run and nothing here claims potency. THIS ARTIFACT'S OWN COST MODEL WAS WRONG BY AN ORDER OF MAGNITUDE. It says a paired control "needs TWO full cold Bazel+Nix+Rocq proof builds". MEASURED from CI's own job records on TWO commits — ee9a955 (the v0.81 release commit) and 93c5e4b — the job completes in 2.3 and 2.0 MINUTES, `runs-on: ubuntu-latest`, with `setup-bazel` restoring a workflow-keyed `disk-cache` and a `repository-cache`. The expensive route was never the only route: the cost belongs to the LOCAL reproduction, not to the control. AND THE BUILD GRAPH MAKES A ONE-FILE CONTROL CHEAP, read from `coq/BUILD.bazel` rather than assumed: a chain of per-module `rocq_library` targets with EXPLICIT `deps` over 34 `.v` files, not one monolithic target. Breaking one proof rebuilds that library and its reverse deps only. Which targets are LEAVES needs `bazel query` (a server start plus the external repos), so it is NAMED as the next step rather than guessed. ONE POTENCY SUB-FINDING, BY INSPECTION AND LABELLED AS SUCH. `Verify Rocq proofs` is a bare `run: bazel test //coq:verify_proofs` — no `|| true`, no `|| [ $? -eq 4 ]` — so it cannot pass vacuously on Bazel exit 4, "no tests matched". That matters because THE STEP DIRECTLY BELOW IT in the same job documents exactly that bug (#945: a tolerated exit 4 made the Renode step "pass while selecting nothing") and guards it on purpose. The proof step is on the right side of that line. INSPECTION, not a control: it shows the step cannot swallow a failure, not that a broken proof produces one. THE LOCAL ROUTE IS REFUTED ON MEASURED DISK, which this artifact did not know: the data volume is at 99% with 7.3 GiB available, and `/nix/store` is already 21 GiB. A cold Bazel+Nix+Rocq build does not fit. 16 GiB sits in a SIBLING project's `rivet/target` and was deliberately NOT purged — another repository, another session, no compiler running in it when checked, and buying someone else's rebuild is not this lane's call. Nothing left in the release path needs a local build, so disk is not blocking. SO THE BLOCKER IS SCHEDULING, NOT COST. `ci.yml` triggers on `push: branches: [main]` and `pull_request: branches: [main]`, so pushing a scratch BRANCH raises no workflow at all — the control needs a PULL REQUEST, which queues 73 job keys: 46 `ubuntu-latest`, 18 `[self-hosted, linux, x64, rust-cpu]`, 3 `light`. The rust-cpu partition is SEVEN of the org's twelve runners and was measured 7/7 BUSY while this release's own merge sat at 15 of 72 checks after 83 minutes. Spending 18 of those slots on a deliberately-broken-proof PR during the release's own merge would delay the thing the control exists to protect. WHAT WOULD SETTLE IT, affordable and unblocked once the queue drains: a scratch PR breaking ONE leaf proof — a broken `Qed`, NOT an added `sorry`, because this repo has shipped a "fail on sorry" gate where all twelve `sorry`s carried a self-exempting comment — confirm the job reds with an attributable diagnostic, record the run link, close the PR unmerged, confirm the unmodified tree passes. Two ~2-minute job runs on GitHub-hosted runners, zero local disk. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: partial` + `landed:` naming the delivering PR, `issue-scope` OMITTED. #1456 stays open; the gate stays UNPROVEN. Refs #1456 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 ARCHMODEL lane (#1136): the twentieth filing, ordinal derived by artifact identity at 6034b22 THE ORDINAL IS DERIVED BY ARTIFACT IDENTITY AND STATED WITH ITS COMMIT, never by counting releases, because the next filing invalidates it and v0.81's artifact had to be corrected for omitting the commit: `ls artifacts/release-v*/RQ-*ARCHMODEL*.yaml | wc -l` returns TWENTY at 6034b22 — an unbroken run from RQ-63-ARCHMODEL through RQ-82-ARCHMODEL. spar#445 WAS RE-CHECKED STATE-FIRST, the #345 lesson: a body is written once and never updated, so the STATE is the fact. `gh issue view 445 --repo pulseengine/spar` reports STATE=OPEN with no `closedAt`. The blocker stands, so steps 1-2 are N/A rather than merely unattempted. AND THE FILING IS SHOWN SEEN BY RUNNING THE MATCHER, NOT BY READING THE TAGS — which is exactly what RQ-69-ARCHMODEL failed when it lost the `feature-loop` tag and the filing that exists to keep a deferral visible became invisible to the gate that reads it. `python3 scripts/loop_conformance_check.py v0.82.0` prints: step 1-2 spar AADL->WIT filed decision NA-FILED decided, artifact scoped, not yet built: RQ-82-ARCHMODEL (#1136, status proposed) [scoped to v0.82, evaluated at checkout] Re-run AFTER the edit as well, because a number is invalidated by the edit that writes it: still NA-FILED. The matcher requires `feature-loop` AND one of `{aadl, spar}` AND a `fields.issue`; this artifact carries `process, feature-loop, spar, aadl` and `issue: "#1136"`. AND IT REPORTS AN OUTCOME rather than being silent, which is the shape v0.81's SILENT lane made mechanical: `disposition: deferred` with a DEFERRED leading verdict, so an artifact with no outcome field is red at the tag and this filing is no longer that shape. ONE MEASUREMENT TAKEN WHILE THE MATCHER RAN, about THIS RELEASE'S TAIL rather than about #1136: the same gate reports step 3 "reported outcome" DERIVED-FAIL with 10 of 12 artifacts recording no outcome. That is TRANSIENT, not a defect — the gate evaluates at HEAD and ten of this release's artifacts carry their outcome fields on lane branches not yet merged. It must clear as the lanes land; if it has NOT cleared by the tag it is a real finding. Step 0 (workspace still 0.81.0), step 7 (no cold-review record) and step 8 (changelog topmost section still [0.81.0]) are DERIVED-FAIL for the same pre-tag reason. WHAT WOULD END THE RECURRENCE, unchanged and not re-litigated: a synth-owned `.aadl` model tracked in-repo, which makes the matcher take branch (a) instead of branch (b). The recorded maintainer decision on #1136 is "not permanently N/A; timing first", so this is a deferral with a named blocker, not an exemption. Gates: status_evidence rc=0 (0 FAILs), verdict_prose 0 disagree over 68, claim_check 75/75. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: deferred` + `landed:` naming both the issue and (on the PR) the delivering PR, `issue-scope` OMITTED. #1136 stays open. Refs #1136 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 PAGESIZE4 lane (#1441): the pre-read first, the relocation left alone, and the capability declined on its own done-when THE MANDATED PRE-READ RAN BEFORE ANY CODE WAS CONSIDERED — the rule v0.81 violated by building first. `git grep -n -F 'refuse_custom_page_size' -- artifacts/` returns SIX files spanning v0.69, v0.70, v0.71, v0.80 and v0.82: a carried family five releases deep, which is itself the signal that a decision already exists. gale's words, re-read at `artifacts/release-v0.81/RQ-81-PAGESIZE3.yaml:72`: "Refused or honoured? HONOURED — and please do not spend the effort on relocating the refusal. Refusing in the library closes a door gale wants open." THE RELOCATION STAYS OFF THE TABLE and was not attempted a third time. THE REFUTING COMMAND COULD NOT RUN, AND IT FAILED CLOSED — the right outcome for an oracle, and not to be read as a pass. `pagesize_oracle_1441.py` exits 1: "REFUSE: no synth binary at target/{debug,release}/synth — build it first; an oracle that silently skips because its subject is missing is the 'checker reports success about work it never did' class". So the premise is NEITHER confirmed NOR refuted by execution. AND THE CAUSE DIFFERS FROM v0.81's: that release misreported an uninitialised `tests/spec-testsuite` as the oracle refusing; here the submodule IS initialised (345367358, 265 entries). The blocker is the absent binary. SCOPE RE-DERIVED AT THIS COMMIT rather than carried, because the artifact's figures are marked "measured at the v0.80 cut": page_size_log2 sites 5 2 in the CLI refusal, 2 in synth-core/wasm_decoder (struct field + propagation), 1 comment. The DECLARATION reaches the decoder and is ignored thereafter. memory.size lowering sites 4 arm_encoder.rs:1758 and :3830, select_default.rs:398, cortex_m.rs:152/155 — each a hardcoded LSR #16 / >>16 on R10 max_bytes 1 mention in the whole crate tree: the DEFINITION. ZERO callers, confirming the carried measurement initial_bytes 13 mentions — the twin shape is real; both must move together WHY DEFERRED, AND NOT MERELY "NO TIME". The done-when demands TWO pieces of EXECUTION evidence — the CI-wired oracle flipping to capability mode, and an execution differential over a non-default page size — and both need a built `synth`. The machine cannot build one: the data volume is at 99% with 5.1 GiB available, DOWN from 7.3 GiB during this session. The dominant consumers are other projects' — a loom scratchpad at 29 GiB, witness at 10 GiB, and a sibling `rivet/target` at 18 GiB that grew 2 GiB while this was measured — none of it this lane's to purge. A full workspace debug build measured 12 GiB when last taken. AND THE PRINCIPLED REASON, which stands even with free disk: shipping this capability WITHOUT execution evidence is precisely the v0.78 shape, where a lane built a reach gain, its own execution oracle then showed sign-wrong code, and the gain was REVERTED. A reach increment owes execution evidence, so declining the increment beats shipping it unexecuted and claiming the done-when. RESIDUE THIS LANE CLEANED, because it was this session's own: an idle `bazel(synth)` server THIS session started with a `bazel info` query was shut down, and the three v0.81 worktrees under the scratchpad were removed after confirming each branch's content SHIPPED by merged PR head — 1482, 1483, 1481. Their `git log origin/main..HEAD` counts read 5, 6 and 2 "unpushed", which is the squash-merge trap rather than lost work. Gates: status_evidence rc=0 (0 FAILs), verdict_prose 0 disagree over 68, claim_check 75/75. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: deferred` + `landed:` naming the issue and (on the PR) the delivering PR, `issue-scope` OMITTED. #1441 stays open. Refs #1441 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 NPM lane (#1460): rotating the token would have changed nothing — v0.81's compliance fix SKIPS the npm job entirely THE REGISTRY GAP, RE-DERIVED AGAINST THE LIVE REGISTRY WITH THE REQUEST SHAPE STATED, because a 403 or a missing User-Agent is not evidence of "not published": `curl -s -H "User-Agent: synth-release/0.82" https://registry.npmjs.org/@pulseengine%2fsynth` returns `dist-tags {'latest': '0.69.0'}` over 39 published versions, against a shipped workspace version of 0.81.0. TWELVE minor releases behind (0.70 through 0.81), re-derived not restated. THE SECOND BLOCKER, AND IT IS A CONJUNCTION NOBODY READ TOGETHER. `release-npm.yml` gates its only job on if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' and v0.81's RQ-81-COMPLIANCE deliberately gave `compliance.yml` the ability to FAIL THE RELEASE PATH — its own comment says so, because "a gate that cannot fail is this programme's recurring defect". Each fact is correct; their conjunction is not. DERIVED per tag: v0.78.0 Release success compliance jobs 0 v0.79.0 Release success compliance jobs 0 v0.80.0 Release success compliance jobs 0 v0.81.0 Release FAILURE compliance jobs 1 — and the ONLY failing job in the entire run is `Compliance report / Generate compliance report` So npm's condition evaluated FALSE for the first time and the job SKIPPED with ZERO steps (run 37655372920, 1 second). It never reached its preflight. AND THE FAILURE GOT QUIETER, which is the part that matters. Before v0.81 the npm job RAN and failed loudly at "Preflight — verify npm auth" with ELEVEN steps and a diagnostic naming the token type (run 37560641837). Now it reports `skipped`, no steps, naming nothing. A credential blocker that announced itself every release now announces nothing — the same "a workflow that never starts has no conclusion to be red" shape RQ-81-COMPLIANCE existed to remove, reappearing one workflow over as a consequence of that very fix. THIS ARTIFACT'S OWN DESCRIPTION IS THEREFORE STALE AND IS CORRECTED IN PLACE, not quietly: it says `Release NPM` "fails at its 'Preflight — verify npm auth' step ... which means the preflight is doing its job". At v0.81.0 the preflight did not run at all. AND RQ-82-COMPLIANCE2 IS NOW A PREREQUISITE FOR THIS LANE, unknown when either was scoped. If the externals sync lands and compliance succeeds, the Release run concludes success, npm's condition becomes true, and the preflight runs — at which point the credential is once more the only blocker. ROTATING THE TOKEN WITHOUT THAT FIX WOULD CHANGE NOTHING. THE UNBLOCKING ACTION, NAMED PRECISELY ENOUGH FOR SOMEONE ELSE TO EXECUTE: the repository secret is NPM_TOKEN, in Settings -> Secrets and variables -> Actions, and it must be a CLASSIC AUTOMATION token (or a granular token with read-write on `@pulseengine/*`), regenerated at npmjs.com -> Access Tokens. A classic PUBLISH token is NOT sufficient — the org enforces 2FA on publish and that type fails in CI with EOTP. Quoted from the workflow's own preflight so the action does not require reading CI to find. WHY `issue-scope: outlives` IS NOT CARRIED, against this artifact's own done-when which asks for it "either way": it is FORBIDDEN beside a non-claiming status, and the gate says why. Probed on this tree, `issue-scope: outlives` with `status: proposed` gives `FAIL R12 RQ-82-NPM: ... the issue of an undelivered artifact stays open anyway, so this declaration` is redundant. The non-claiming shape achieves what `outlives` achieves and more strongly — the issue never enters the authorised close set at all — so the done-when's INTENT is met and its LETTER is not. Stated out loud rather than silently dropped. Gates: status_evidence rc=0 (0 FAILs), verdict_prose 0 disagree over 68, claim_check 75/75. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: deferred` + `landed:` naming the issue and (on the PR) the delivering PR, `issue-scope` OMITTED per R12. #1460 stays open. Refs #1460 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 PINBYVALUE lane (#1439): the premise said SEVERAL and it is ONE — and half the argument was pinned THE REFUTING COMMAND RAN FIRST AND DID NOT REFUTE: `-0.0 == 0.0` is still True and `float("nan") in [float("nan")]` is still False, so both mechanisms are live. THE PREMISE IS REFUTED WHERE IT SAID "SEVERAL". DERIVED with `ast` over `scripts/repro/`: 14 float-valued tables, 12 containing `-0.0` or NaN — but the number that ASSERT over such a table is ONE FILE, the already-known `vfp_local_pressure_1069_differential.py`. There is no second site to convert. The population is ONE, not several, and that is reported as a number rather than quietly dropped. TWO OF MY OWN DETECTORS WERE WRONG BEFORE THAT NUMBER WAS RIGHT, so the method ships with it. Detector 1 looked for `ast.Compare` and found NOTHING — the real guard is SET ARITHMETIC over packed bytes, not a comparison. Detector 2 text-scanned each assert for `struct.pack` and classified the one guard I KNEW was correct as VALUE-based, because the packing happens on a PREVIOUS line. A transitive closure over derived names then over-reached to 25 names and swept in five per-value input guards. The figure comes from READING the bounded set the narrow scan produced; a near-empty derived population is a refusal, and it twice meant my instrument was wrong rather than the tree clean. WHAT WAS ACTUALLY UNPINNED, measured per row by DELETING IT and watching for a red, against origin/main and then against this change: 0.0 -- -0.0 pin 1.0 -- -1.0 pin 0.5 -- -0.25 pin 1.5 -- 0.001 -- -3.14159265 pin 1e-30 -- -1e30 pin inf -- -inf pin nan -- BEFORE: 8 of 14 unpinned ... every row `pin` after AFTER: 0 of 14 THE NaN ROW WAS PROTECTED BY NOTHING. The file's own header says NaN is deliberate — it exercises the spilled reload paths, each local's round-tripped value feeding the product. Deleting it reddened nothing. Same family as the `-0.0` escape, OPPOSITE failure mode: `-0.0` was pinned VACUOUSLY TRUE because `-0.0 == 0.0`; NaN cannot be pinned by membership AT ALL because `nan != nan` would make the guard vacuously FALSE on a CORRECT fixture. `struct.pack` settles both. AND HALF THE ARGUMENT WAS PINNED. The file states the shape itself: "the positive rows are the discriminator — a `neg` would corrupt them too, an `abs` leaves them alone", so the abs-vs-neg conclusion rests on BOTH halves. v0.81 pinned the negative half by bits; the positive half had only `len(_POS) >= 4` against SEVEN present, so the floor permitted deleting three in silence. Now pinned by bits, in a SEPARATE tuple from `_FAILING_SET_1439` — that name means exactly "the six values v0.78 recorded as failing" and adding rows would falsify it. THE ZERO IS EARNED, NOT VACUOUS: FOURTEEN individual firing mutations, one per row, plus TWO NEGATIVE CONTROLS that must stay silent and do — REORDERING rows does not fire (the pins assert content, not order) and ADDING a row does not fire (a future lane may extend). WHAT WAS NOT RUN, PLAINLY: the differential's BODY. It needs `./target/debug/synth`, absent after the v0.81 disk purge, and it has no `--self-test`. This lane changes MODULE-LEVEL fixture guards, which run at import and which the 14 mutations exercised directly; CI runs the full differential through `oracle_run.py`. A local oracle run is not a CI run and this claims none. NOT PROGRESS ON #1439 AND SAYS SO: the emitter is still unnamed. This hardened the oracle AROUND the defect. #1439 is INTERNAL (no `**[name]` body prefix), so conduct rule 4 does not bind — but the framing would be the same if it did. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: partial` + `landed:` naming the delivering PR, `issue-scope` OMITTED. Refs #1439 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 COMPLIANCE2 lane (#1453): the trigger was fixed and the job still produced nothing — the refuting command could not see the run THE FIRST HALF IS A VERIFICATION AND IT CAME BACK NEGATIVE. v0.81.0 carries THIRTEEN assets and ZERO matching `compliance`, derived with `gh release view v0.81.0 --json assets`. THE REFUTING COMMAND'S SECOND HALF IS BLIND BY CONSTRUCTION, which is worth more than the number it returns. It asks for the runs of `compliance.yml`'s workflow id; the answer is STILL 19 (1 `workflow_dispatch`, 18 `release`, newest v0.43.0) — which reads as "the wiring did not work". IT DID. A `workflow_call` invocation does NOT create a run of the CALLED workflow; it appears as a JOB INSIDE THE CALLER'S RUN. Found there: run 37654229482 ("Release", failure) contains `Compliance report / Generate compliance report` with 7 steps — step 2 `Resolve tag` SUCCESS, step 3 a single `actions/checkout@v7` SUCCESS, step 4 `Generate compliance report` FAILURE, step 5 `Upload report to release` SKIPPED. The trigger is fixed and is not re-litigated here. THE CAUSE, DERIVED ON THIS TREE RATHER THAN CARRIED. `rivet.yaml` declares SEVEN externals — gale, jess, kiln, loom, meld, scry, sigil — each with `git:` and `ref: main` and deliberately NO `path:` (#1012: a declared local path wins, and a dead one poisons resolution for everyone). Their clones live under `.rivet/repos/<prefix>`, and `.rivet/` is GITIGNORED at `.gitignore:62` with ZERO tracked files, so a single `actions/checkout` CANNOT supply them. The job's own log is no longer retrievable (the API returns 0 bytes — an API failure, not an empty population), so the `could not load externals` quote is v0.81's recorded reading; the step list above is what this release verified independently. AND THE REMEDY IS PROVEN END-TO-END ON THE SAME TREE, WITH THE SAME RIVET. With the seven clones PRESENT, `rivet validate` returns PASS with `Cross-repo backlinks: 1032 (external artifacts linking to local)` — the #1012 non-vacuity signature satisfied, resolution RAN. The local binary is `rivet 0.37.0 (6f9ef82c master 2026-09-22)` and the CI action pins `rivet-version: v0.37.0`: the same rivet, not a near-enough one. WHAT SHIPPED, AND THE PATTERN IS NOT NEW. A `Sync rivet externals` step between the checkout and the report, lifted from `ci.yml`'s federated-graph job (#1143): AUTHENTICATE FOR QUOTA, NOT FOR ACCESS — all seven siblings are PUBLIC, but GitHub rate-limits ANONYMOUS git traffic hardest from datacenter address space, and a throttled response makes git fall back to interactive auth, surfacing as `fatal: could not read Username` — which reads like a permissions failure and is not one. The `url.insteadOf` rewrite is scoped to the step and removed by a `trap`. THE LIST IS DERIVED AT RUNTIME FROM `rivet.yaml`, not mirrored into the workflow, so adding an external never needs a second edit. PROVEN by EXTRACTING THE EMBEDDED SCRIPT FROM THE WORKFLOW FILE and running it, so the test cannot drift from what ships: the real tree reports `synced 7 of 7 externals`; `externals: {}` REFUSES, because a zero population would otherwise succeed while syncing nothing; an unclonable external REFUSES. Both controls fired. THE SECOND HALF IS A DECISION PUT AND NOT TAKEN. Re-derived BY PAGINATION (two pages, 149 releases): 19 carry a compliance report, 130 DO NOT, 45 CONSECUTIVE from the newest, most recent report at v0.43.0. v0.81 recorded 129 of 148 and 44 consecutive; each is one higher because v0.81.0 itself shipped without one. The 19 matches the 19 workflow runs exactly, which corroborates the mechanism. Regenerating them is 130 outward-facing writes to already-published release pages via `workflow_dispatch`, one tag at a time — THE MAINTAINER'S CALL, and nothing was actioned. The tarball was NOT hand-attached: making the oracle reachable is not delivery. THE RESIDUAL, NAMED: no per-PR static gate pins the STEP ORDER, so a future edit could move the sync after the report and nothing would red until a release. It was deliberately NOT bolted onto `release_trigger_check.py`, whose own docstring is explicit that it polices trigger reachability and that a different population belongs in a different gate. The in-step non-vacuity refusal is the gate that exists, and it fires on zero or partial syncs. ALSO OBSERVED AND NOT ACTIONED, per the recorded VARVE non-action: `Rivet Federated Graph (advisory)` is red at step 6, `varve install — resolve + fetch + verify the pinned layer`, with `Sync externals` and `Validate` SKIPPED. So that job's red is the varve layer, NOT an externals failure, and it fails CLOSED exactly as designed. Reported and moved past. Gates: 31 of 31 Claim Check scripts pass, release_trigger_check rc=0, compliance.yml parses with 5 steps in the order Resolve tag -> checkout -> Sync externals -> Generate -> Upload. NON-CLAIMING BY CONSTRUCTION: `status: proposed` + `disposition: partial` + `landed:` naming the delivering PR, `issue-scope` OMITTED. #1453 stays open until a release attaches a report by an automated path, and this release is the first test of the remedy. Refs #1453 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 DEPS lane (#965): five held dependabot PRs in one, because four of them are the SAME upstream train MAINTAINER-REQUESTED, added to v0.82's scope after the plan was cut. WHY ONE PR IS CORRECT AND NOT MERELY CONVENIENT. Four of the five — `wasmparser`, `wasm-encoder`, `wit-parser`, `wit-component` — all move to 0.261.0, one upstream wasm-tools release train versioned in lockstep. Bumping them one at a time asks cargo to resolve a graph with half the family new and half old. The fifth, the `pulseengine/rivet` compliance ACTION 0.39.0 -> 0.40.0, is a different surface with its own evaluation. THE HOLD'S OWN EXIT CONDITION IS WHAT THIS FOLLOWS, not an exception to it. RQ-64-DEPS recorded it: "merge a held bump BY HAND once the FULL suite is green", base freshness part of "green", and a bump nobody evaluates needing a disposition because "still open" is not one. Raised on a FRESH base off origin/main — never by merging main INTO a dependabot branch, which RQ-64-DEPS names as the move that destroys those branches' freshenability. MEASURED, AND IT CORRECTED A FIRST READING. 0.261.0 was ALREADY in the lock transitively for `wasmparser`, `wasm-encoder` and `wat`, while synth's own declared floors sat at 0.256/0.258/0.259/0.259 — so these bumps raise the DECLARATION to meet a graph that already builds, and they UNIFY it: whole-lock duplicate copies 13 -> 10 wasmparser 5 concurrent copies -> 3 wasm-encoder 3 -> 2 wit-parser / wit-component 0.259.0 -> 0.261.0 wasm-metadata (transitive) 0.259.0 -> 0.261.0 My first pass read the lock with `head -1` and reported `wasmparser 0.252.0` as "the" version. That is a TRANSITIVE copy, not the resolved one, and the truncated view would have made the whole premise wrong. THE ACTION BUMP WAS EVALUATED AT ITS INTERFACE, not by its version number, because a renamed input breaks `compliance.yml` silently at the `with:` level. Fetched `action.yml` at v0.40.0: FOURTEEN declared inputs, and all SIX this caller passes (`theme`, `rivet-version`, `include-data-formats`, `report-label`, `archive`, `archive-name`) are among them, with the `archive-path` OUTPUT the Upload step reads still declared. Per RQ-64-DEPS's own #1107 disposition the action version is NOT the tool version — the rivet BINARY is pinned separately at v0.37.0 both in the `with:` and in ci.yml — and `compliance.yml` is not one of the nine required contexts. ONE INTERACTION NAMED RATHER THAN DISCOVERED LATER: RQ-82-COMPLIANCE2 adds an externals-sync step to the same workflow and has not merged. v0.40.0 declares an `offline` input this caller did not previously have available, so a later lane may find the sync unnecessary. The two changes are independent; both are tested only at a release tag. WHAT IS NOT CLAIMED: that synth's source compiles against the newer API. The data volume is at 99% with ~5 GiB available against a ~12 GiB workspace build, so no local compile was possible, and green `cargo fmt` / `claim_check` / `status_evidence` / `cargo metadata --locked` say NOTHING about `cargo build`. THE FULL SUITE IS THE ORACLE, which is exactly what the hold's exit condition requires. AND THE FIVE DEPENDABOT PRs STAY OPEN UNTIL THE SUITE IS GREEN. Closing them first would leave the bumps nowhere if it is not — create before delete, the same rule the cron rotation follows. They are closed with a reason naming this PR once it lands. Local gates: cargo fmt rc=0, check_version_pins rc=0, claim_check 75/75, status_evidence rc=0 (0 FAILs), verdict_prose 0 disagree over 70, cargo metadata --locked rc=0. Refs #965 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 lane wave: stamp the delivering PR (#1492) into each lane's landed field `_acknowledge` derives `PR_NUMBER.findall(subject)[-1]` — the last PARENTHESISED number in the squash subject — and that number differs by CONTEXT: on the lane branch it is the ISSUE, after the squash it is the DELIVERING PR. A `landed:` naming only one of the two is red in the other context, which this release learned the hard way on #1487. This wave's subject names no single lane, so R4-lane does not fire on it (verified in a squash simulation off origin/main, rc=0, 0 FAIL lines, rather than assumed). The stamp is therefore for the RECORD rather than for the gate: each artifact now names both its issue and the PR that delivered the increment. Applied by a script that asserts `count == 1` per edit and reports PER ARTIFACT, because an aborting batch leaves a MIXTURE — dry-run on all eight first, gates re-checked, idempotence confirmed, then reverted before the real run. Refs #1458 #1439 #1456 #1136 #1441 #1460 #1453 #965 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L * v0.82 DEPS lane (#965) REFUTED: the suite named as the oracle said no, and the failure was UNIVERSAL THE LANE ASKED FOR THIS OUTCOME. It shipped with an explicit non-claim -- "whether synth's own source compiles against the newer API" was named unanswerable locally (99% disk, ~5 GiB against a ~12 GiB workspace build) with THE FULL SUITE NAMED AS THE ORACLE. The suite ran and refused. That is the hold's exit condition working, not a lane failing to meet it. WHAT THE SUITE SAID. Run 37790630310 on #1492 at bfed8c2: 50 of 54 completed jobs failed, and the failure is UNIVERSAL rather than leg-specific -- 46 `ubuntu-latest` (x86), 2 `ubuntu-24.04-arm`, 2 `macos-latest`, with the only 3 green jobs `self-hosted,linux,x64,light` ones that compile nothing. `synth-core` (lib) does not build: error[E0277]: the type `[u8]` cannot be indexed by `std::ops::Range<u64>` Four sites, all `crates/synth-core/src/arena_bind.rs`, all one shape -- slicing the original wasm buffer by a wasmparser-supplied section range: 493 &wasm[reader.range()] FunctionSection 501 &wasm[reader.range()] GlobalSection 520 &wasm[range.clone()] CodeSectionStart 554 &wasm[range] copy_raw, via payload.as_section() CAUSE: wasmparser 0.261.0 widened its section-range types from `Range<usize>` to `Range<u64>` -- the 64-bit-memory change. Not a synth defect; an API widening synth's four consumers predate. MY FIRST READING OF THIS RUN WAS WRONG AND GROUPING BY LABEL IS WHAT CORRECTED IT. I saw 4 failures on arm64/macOS legs and hypothesised a leg-specific fault, explicitly declining to assert a cause and naming the decisive test: whether an x86 leg also fails. It does -- all 46 of them. An API break fails every leg; a leg-specific fault spares x86. It spared nothing. FOUR IS A FLOOR, NOT A MEASUREMENT, and that is why this is a WITHDRAWAL rather than a fix-forward. `synth-core` is the base crate, so the compiler stopped there; the `wit-parser` / `wit-component` / `wasm-encoder` consumer surface downstream was never reached and is UNMEASURED. At 99% disk it cannot be measured locally either, so fixing in place is N blind CI round-trips of unknown N, at the release tail, with SEVEN unrelated lanes held hostage. The seven land; the bump does not. THE WITHDRAWAL IS PROVEN BY EQUALITY, NOT BY A VERSION GREP. `Cargo.toml` and `Cargo.lock` are both byte-identical to origin/main (`git diff --quiet origin/main -- <file>` rc=0 each). A `0.261` grep would have been the WRONG check and would have read as a half-revert, because 0.261.0 was already in the lock transitively for `wasmparser`, `wasm-encoder` and `wat` before this lane existed. Paired with a positive control: appending a comment to `Cargo.toml` made the check correctly read DIFFERS. RETAINED, because it is a different surface: the `pulseengine/rivet` compliance ACTION bump 0.39.0 -> v0.40.0 (#1472). Evaluated at its INTERFACE, not its version number -- fourteen declared inputs at v0.40.0, all six `compliance.yml` passes present, `archive-path` output still declared -- it touches no Rust source, and `compliance.yml` is not one of the nine required contexts. Nothing in the build failure implicates it. THE FOUR CARGO DEPENDABOT PRs STAY OPEN: #1344 wasmparser, #1346 wasm-encoder, #1468 wit-component, #1471 wit-parser. Dependabot does not re-raise a manually dismissed version, so dismissing them now would drop the bumps silently with the work still owed. #1472 is the only one of the five whose premise held, and it is delivered here. STANDING RULE CONFIRMED, NOT DISCOVERED: 0.x-minor is BREAKING and such bumps are held; 0.256 -> 0.261 is a 0.x minor move. The lane's lock-level premise was true and insufficient -- a transitive copy in the lock is LINKED, never compiled against, so it cannot witness source compatibility. v0.83 inherits the four sites, the cause, and the fix's shape: a CHECKED u64 -> usize narrowing that refuses loudly on overflow and on a range past the buffer end, never `as usize`, which would silently truncate a malformed 4 GiB-plus offset into a wrong-bytes read. Local gates on the reverted tree: cargo fmt rc=0, check_version_pins rc=0 (all at 0.81.0), claim_check 75/75, status_evidence rc=0 (13 artifacts, 1 authorised closure #1484), verdict_prose rc=0 (78 artifacts, 0 disagree), cargo metadata --locked rc=0. Refs #965, #1472 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>
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 named measurement was half a measurement
The carried ask for #1436 named three stack slots. Each gravity block reads two operands,
so those three were only the multiplicands:
0x2498[sp,#200]@0x2490[sp,#152]@0x24940x24c4[sp,#216]@0x24bc[sp,#232]@0x24c00x24f0[sp,#192]@0x24e8[sp,#208]@0x24ecDerived from the module's own disassembly, digests verified against the thread
(
c.wasm d854e5bb…,c.loom.wasm 791ab6b5…).Two independent reasons three words could not have answered the lane's question. A wrong
addend and a wrong multiplicand are indistinguishable in the stored result. And these are
reused general-purpose spill homes —
[sp,#152]is referenced 130 times in this object —so a slot name identifies no single value and each word must be sampled at its own load PC.
What this lane did not obtain
The runtime values were not measured:
qemu-system-armandqemu-armare both absent onthe release machine and the reporter's repository is not cloned here. A request naming the six
PCs was drafted and not sent — correspondence with an external reporter is surfaced to the
maintainer, not posted by the loop. The thread stands at ten comments and this release added
none.
Per conduct rule 4 this is not claimed as progress on the defect: hardening an oracle
around an open external report does not count. Refining what to measure does, and the
artifact says which this was.
R14 governs this artifact
The verdict is
PARTIAL— the lane narrowed and did not name the cause — andleading_verdictclassifies it from the prose rather than from a token picked to please thegate. So R14, landed by this release's CLOSEARM lane, demands the issue's fate be declared:
issue-scope: outlives, truthful because #1436 is still open. Nodisposition:(R11 forbidsone beside a claiming status).
Proven load-bearing rather than assumed, inside the squash simulation:
issue-scopestrippedFAIL R14 RQ-82-JESSDIVERGE4: verified-by opens PARTIAL while status implemented claims the outcome holds…In v0.81 this declaration depended on an operator remembering it. It is now mechanical.
Instrument errors recorded, not buried
A first grep reported four materializations of
9.81f;head -8had truncated it andthere are nine. A first store-offset attribution gave
{932, 940, 936}and briefly madethe carried claim look wrong — the scan window began before its own anchor and picked up the
preceding block's
addw. Forward-only scanning gives 940, 936, 944, confirming the carriedclaim. The brief was right and my first measurement was not.
Refs #1436
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L