← Back to Blog

Rotifer v0.6.5: Cross-Binding Proof — IR Portability Gets Real

A RotiferBinding trait, a mock Web3 environment, and 9 cross-binding tests prove that genes can travel between fundamentally different execution environments.

Rotifer claims that genes are portable — compile once to IR, run in any binding environment. Until v0.6.5, that was a specification promise with zero proof. This release changes that.

The Problem: One Binding, Zero Validation

The IR specification declared:

IR 1.0 release condition: at least two binding environments pass cross-binding interoperability tests.

We had exactly one binding (Local/Cloud) and zero cross-binding tests. The most important section of the IR spec — §10, Cross-Binding Interoperability — had never been exercised against real code.

The Solution: Abstract, Mock, Validate

Rather than spending months building a full Web3 Binding (Solidity contracts, Arbitrum deployment, token economics), we took a minimal approach: build a mock that’s different enough to trigger every negotiation path.

RotiferBinding Trait

A new RotiferBinding trait abstracts what it means to be an execution environment:

pub trait RotiferBinding: Send + Sync {
fn binding_id(&self) -> &str;
fn metering_unit(&self) -> MeteringUnit;
fn capabilities(&self) -> &BindingCapabilities;
fn execute_ir(&self, ir_bytes: &[u8], context: &Context,
input: Value, phenotype: &Phenotype) -> Result<GeneResult>;
fn negotiate(&self, requirements: &IrRequirements) -> NegotiationResult;
}

Every binding declares its identity, metering unit (Fuel vs Gas vs WallClock), available host functions, and resource ceilings. The existing wasmtime sandbox was refactored into LocalBinding without changing any behavior — all 224 existing tests pass unchanged.

Web3MockBinding

A second binding simulates on-chain constraints:

DimensionLocalBindingWeb3MockBinding
MeteringFuel (1M cap)Gas = Fuel × price (500K cap)
Memory64 MB16 MB
Timeout30s5s
FilesystemAllowedForbidden
Extension functionsNonegetBlockNumber, getChainId

Same wasmtime engine, radically different constraints. These differences are sufficient to exercise every path in the Capability Negotiation protocol.

Capability Negotiation: Three Outcomes

When a gene’s IR is transferred to a new binding, the protocol negotiates compatibility:

The negotiation checks required host functions, optional host functions, memory requirements, and resource budgets. Six typed IncompatibilityReason variants provide precise diagnostics — not string errors.

9 Cross-Binding Tests

We planned 6 tests and shipped 9:

  1. Basic interop — echo gene compiled in Local, transferred and executed in Web3Mock
  2. Resource overrun — gene requiring 32 MB rejected by Web3Mock (16 MB cap)
  3. Optional function degradation — gene using getBlockNumber gets PartiallyCompatible in Local
  4. Required function rejection — gene requiring chainCall gets Incompatible in Local
  5. Gas metering validation — same IR, same computation, different metering units reported
  6. No-IR fallback — Wrapped gene (no irHash) returns ERROR_NO_IR_AVAILABLE 7-9. Bidirectional transfer — Web3Mock → Local transfers (reverse direction validation)

254 total Rust tests pass (224 original + 30 binding tests).

What We Found: 7 Spec Recommendations

The validation produced a formal IR Cross-Binding Validation Report with 7 recommendations for IR 0.2.0:

PriorityRecommendation
HighFormalize Capability Negotiation as an explicit sub-protocol (§10.5)
HighClarify compile-time interception vs runtime degradation for extension functions
MediumSeparate “core interop protocol” (steps 3-5) from “full propagation flow” (steps 1-7)
MediumDefine cross-binding resource metering semantics
MediumAuto-extract IrRequirements from WASM custom sections
LowClarify extension function naming convention
LowAdd version check placeholder in negotiation

IR 1.0 Progress

With v0.6.5, the IR version can advance from 0.1.0 → 0.2.0. The core interop path is validated. But IR 1.0 still requires a real (non-mock) Web3 Binding and external developer RFC feedback.

What’s Next

v0.6.5 is infrastructure — no new CLI commands, no UI changes, no user-facing features. But it unblocks everything that comes after:


Upgrade: npm i -g @rotifer/playground@latest

Docs: rotifer.dev/docs

Source: gitlab.com/rotifer-protocol/rotifer-playground