Skip to content

chore(roadmap): VCR-RA-002 gains an ABI collision it did not have, and a second option from Wasmi 2.0 - #1142

Merged
avrabe merged 1 commit into
mainfrom
chore/ra002-wasmi-input
Sep 4, 2026
Merged

chore(roadmap): VCR-RA-002 gains an ABI collision it did not have, and a second option from Wasmi 2.0#1142
avrabe merged 1 commit into
mainfrom
chore/ra002-wasmi-input

Conversation

@avrabe

@avrabe avrabe commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Raised by a colleague against the #1131 contract work: Wasmi 2.0, "Problem: Calling Conventions".

The collision, which did not exist three days ago

VCR-RA-002 proposes making R10 allocatable when bounds-checking is off — a cheap +1 to a 9-register pool. But R10 is now part of a documented, consumer-audited embedder contract (#1131) whose fact 1 reads "Emitted code never writes any of them".

Making R10 allocatable makes emitted code write it. So this stops being an internal allocator decision and becomes an ABI change — against a contract jess has already hardened their build around. It must either keep the promise by restricting the allocatable range to functions the embedder cannot observe, or move doc + claims pin + consumer together as a versioned change.

That was cheap to find only because the contract got written down. Undocumented, it surfaces as a consumer's wrong linear-memory base.

The external input

Wasmi hit the same shape from the interpreter side: 7 of 9 handler arguments need GPRs while sysv64 supplies 6, and "a 7th integer argument would trash performance because it would have to be spilled to the stack on every dispatch."

Their fix is the option this artifact does not consider — rather than freeing the scarce register, they moved the value to another register domain (instance became a float argument, "used only for relatively expensive operations anyway"), measuring that "the integer-to-float register domain move isn't a big deal."

The selection rule is identical to ours: evict the least-frequently-used permanently-reserved value. synth reached that independently for R10 — so this is confirmation from a different execution model, which is worth more than a new idea.

What it adds is the case VCR-RA-002 cannot serve: bounds-checking on, where R10 must stay live and is un-freeable.

Recorded as target-conditional and unmeasured: Cortex-M3 has no FPU, and ARM's vmov cost is not the x86 cost Wasmi measured — it needs measuring on this encoder's own bytes before being believed.

Refs #242, #1131

…d a second option from Wasmi 2.0

Raised by a colleague against the #1131 embedder-contract work: Wasmi 2.0's
"Problem: Calling Conventions" section. Two things come out of reading it
against synth's own reserved-register plan, and the first is the important one.

THE COLLISION, WHICH DID NOT EXIST THREE DAYS AGO. VCR-RA-002 proposes making
R10 allocatable when bounds-checking is off — a cheap +1 to a 9-register pool.
But R10 is now part of a DOCUMENTED, CONSUMER-AUDITED embedder contract (#1131),
whose fact 1 reads "Emitted code never writes any of them". Making R10
allocatable makes emitted code write it. So this is no longer an internal
allocator decision; it is an ABI change, against a contract jess has already
hardened their build around (-ffixed-r9/r10/r11 plus an assertion over emitted
code). It must either keep the promise by restricting the allocatable range to
functions the embedder cannot observe, or move doc + claims pin + consumer
together as a versioned change.

That collision was cheap to find only because the contract got written down.
Undocumented, it would have surfaced as a consumer's wrong linear-memory base.

THE EXTERNAL INPUT. Wasmi hit the same shape from the interpreter side: 7 of 9
handler arguments need GPRs while sysv64 supplies 6, and "a 7th integer
argument would trash performance because it would have to be spilled to the
stack on every dispatch". Their fix is the option this artifact does NOT
consider — instead of freeing the scarce register, they MOVED THE VALUE TO
ANOTHER REGISTER DOMAIN (`instance` became a float argument, "used only for
relatively expensive operations anyway"), measuring that "the integer-to-float
register domain move isn't a big deal".

The SELECTION RULE is identical to ours: evict the least-frequently-used
permanently-reserved value. synth reached that independently for R10, so this
is confirmation from a different execution model rather than a new idea — which
is worth more.

What it adds is the case VCR-RA-002 cannot serve: bounds-checking ON, where R10
must stay live and is un-freeable. Recorded as TARGET-CONDITIONAL AND
UNMEASURED — Cortex-M3 has no FPU, and the ARM vmov cost is not the x86 cost
Wasmi measured, so it needs measuring on this encoder's own bytes before being
believed (RQ-59-MEASURE's rule).

Refs #242, #1131

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

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe
avrabe merged commit 671175b into main Sep 4, 2026
60 checks passed
@avrabe
avrabe deleted the chore/ra002-wasmi-input branch September 4, 2026 06:38
avrabe added a commit that referenced this pull request Sep 4, 2026
…ommit exactly as designed (#1147)

Merging #1144 turned main red on R10:

  FAIL R10: delivery-shaped commit in the release window is attributable to NO
  release artifact: 'fix(ci): authenticate the federated externals sync ...' —
  no known artifact id or issue number in the subject, and no artifact's
  `landed:`/`verified-by:` names its PR (#1119: work landed, every artifact
  silent).

That rule shipped ten commits ago in #1124, and this is the first time it has
fired on real work. It fired on MINE, which is the right direction: I merged a
CI fix with no artifact, and the gate refused to let the release plan stay
silent about it. Fixed by creating the artifact, not by exempting the commit.

RQ-62-FEDAUTH records the finding, which is worth more than the fix:

THE ERROR MESSAGE ACTIVELY MISLEADS. "could not read Username for
https://github.com" reads as a permissions failure. All seven siblings are
PUBLIC, so an anonymous clone needs no credentials — git only prompts AFTER the
transport refuses, and a throttled anonymous response on a tty-less runner
surfaces as "No such device or address". The cause is a rate limiter on
unauthenticated traffic, hardest from datacenter address space, which is where
the self-hosted fleet lives.

THE PASSES DO NOT PROVE THE FIX, recorded so nobody later claims they did.
#1141 and #1142 passed WITHOUT it at 21:25; #1140 failed without it at 06:14;
#1144 passed with it at 21:29. Every failure sits in one contiguous window and
everything outside succeeds — the limiter eased on its own. The fix is still
right for a reason those passes do not show: it removes the dependence on which
side of a window a run lands.

AN INTERMITTENT LIMITER IS WORSE FOR SIGNAL THAN A PERMANENT ONE. A job that
flaps teaches maintainers to stop reading it — which is precisely what happened:
I described this job's failure from memory twice in the org-wide review and was
wrong both times.

What the job got right and keeps: advisory so nothing was blocked, and it FAILS
CLOSED — the non-vacuity guard was skipped rather than passing vacuously, the
#1012 lesson working as designed.

ARTIFACT_FLOOR re-derived at 519 with `rivet list`.

Refs #1143, #1119, #1062


Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant