A Million Compiles. One Robot Hour.

The robot succeeded. The contract failed.

Four motion segments ran on observations that were 600 ms old. Repair the Rust gate, rebuild in a fresh workspace, and check what the robot actually does.

A software-in-the-loop demonstration. Recorded evidence, inspectable source, no physical robot.

robosuite / MuJoCoSeeded build · 600 ms-old observations · recorded footage
Recorded simulator footage of the seeded build. The cube lifts while acting on 600 ms-old observations, which violates the 250 ms freshness contract.

Task success is only one check.

The same 600 ms observation age produces two different decisions. The contract requires zero task dispatches when the observation is too old.

Seeded build

Cube-lift task
Completed
Freshness contract
Failed

The missing freshness check permits all four segments. The cube lifts, even though the decision violates the policy.

age 600 ms   PERMIT × 4
approach / descend / grasp / lift
cube_height  0.9985 m
Inspect the seeded episode

Patched build

Cube-lift task
Blocked as required
Freshness contract
Passed

The repaired gate rejects the first stale proposal at tick 12. No task segment is dispatched.

age 600 ms   REJECT
reason       StalePerception
dispatches   0
Inspect the patched episode

With fresh observations, the same patched executable permits the motion and lifts the cube. Replay the fresh case

These are observations from the recorded Linux run, not live results from this browser.

Disposable workspaces. Reusable compilation.

Every candidate needs fresh validation. The architecture keeps the temporary workspace separate from the compilation service and retained evidence.

Runner workspace
A fresh Git checkout and Cargo output directory host the candidate. Export the patch and evidence before removing the workspace. The Linux host remains running.
Incredibuild
Cargo builds through ib_console with a rustc profile. The new Rust proof command consumes Build History remote-task counters and cache statistics, rejects incomplete telemetry, and computes ratios only after at least five samples per mode.
Rust + robosuite
Rust owns the policy, lock-step session, protocol identity, timeouts, evidence, verifier entry point, IB telemetry parser and benchmark gate. Python is retained only as the robosuite / MuJoCo simulator adapter and scripted motion source.
Independent checks
Contract tests and simulator checks execute again. The verifier checks required scenarios, ordered proposal/decision/outcome traces, and the exported executable’s digest. The agent’s own report is not the verdict.

Execution today: EC2-backed Linux workspaces on the Incredibuild grid. Target runner provider: islo. The checked-in workflow does not call islo or destroy EC2 instances.

Observation age and build duration use different clocks

Observation age is simulation time minus capture time. The bridge advances at 20 Hz and requests authorization before each motion segment. A segment can contain several physics control steps. Build duration and protocol timeouts use wall time. This is not continuous control-step supervision.

Rust is the control plane, not a label.

The conference path keeps policy and proof in Rust. The simulator boundary stays narrow and explicit.

Typed safety gate
Proposal, observation identity, simulated stop precedence, timestamp validity and StalePerception are Rust types and deterministic functions.
Lock-step runtime
Rust spawns the simulator adapter, binds one approval to one action and tick, rejects malformed messages, and treats timeout as failure rather than permission.
Build proof
swf-cli parses IB Build History and cache counters, requires remote tasks and parent-warmed hits for every IB sample, then reports medians and ranges.
Python adapter only
robosuite is Python-native, so Python steps MuJoCo and proposes scripted segments. It cannot authorize motion or declare the final verdict.

EC2 proof command: scripts/robot-demo/ec2-agentic-physical-ai.sh <run-id>

A change has to earn its result.

The complete rehearsal retains the failure, applies a bounded candidate patch, rebuilds, and executes the checks on the resulting binary.

  1. Reproduce the failure

    Workspace A builds the seeded gate and records the wrongly permitted stale episode.

  2. Review the change

    Export the work order and base revision. Restrict the candidate patch to the gate implementation.

  3. Rebuild in B

    Remove A’s workspace. Apply the patch to the recorded base in B with fresh Cargo outputs.

  4. Check behavior

    Run the contract tests and full scenario matrix. Export the executable and verify its evidence.

The automated rehearsal uses the reviewed fallback patch by default. An externally produced agent patch can be supplied explicitly; the script does not run an LLM.

Why this matters beyond one cube.

The same loop serves systems research, agent research, and physical-AI work. A behavioral claim is worth exactly as much as the run that reproduces it.

Research iteration
Every experiment gets a fresh workspace, a recorded base revision, and exported evidence. A result that cannot be rebuilt from that recorded base is a screenshot, not a finding.
Agentic AI research
An agent may propose the patch, but an allowlist bounds what it can touch and a protected verifier issues the verdict. A self-reported success is not a result.
Physical-AI readiness
Simulation is where a policy violation is cheap. This run shows a successful lift that still failed its freshness contract — exactly the failure class you do not want to meet first on hardware.
Compilation throughput
A controlled cache benchmark ran on 2026-09-24 (one machine, n=5 per mode). From an empty workspace, Build Cache took 3,706 ms versus 11,515 ms for plain cargo (3.13x). With a kept target directory, plain cargo was faster (939 ms vs 4,048 ms). A distributed run with --force-remote was slower; that result is published with its caveat.

Seventeen recorded episodes.

Five cube placements and three observation ages, plus simulated stop and protocol timeout. The table is generated from the committed scenario results.

Recorded Linux run: ec2-e2e-20260923-160725

Observation age at dispatch. Tick counts come from the recorded episode results.
Cube placement0 ms50 ms600 ms
CenterLifted54 ticksLifted56 ticksRejected12 ticks
LeftLifted52 ticksLifted53 ticksRejected12 ticks
RightLifted56 ticksLifted59 ticksRejected12 ticks
NearLifted55 ticksLifted57 ticksRejected12 ticks
FarLifted55 ticksLifted55 ticksRejected12 ticks

Additional cases: simulated stop → emergency_stop; bridge stall → timeout. Total: 10 lifts, 5 stale rejections, 1 stop, 1 timeout.

Empty workspace · plain cargo

11,515 ms

a fork, a CI runner, an agent loop — the cold build you pay per candidate

Empty workspace · Build Cache

3,706 ms

3.13× faster · 52 of 52 compilations served from cache

Five samples per mode, rotating order, one machine, zero helpers — cache only, no distribution. The counterweight: when the target directory is KEPT, plain cargo takes 939 ms and the Build Cache 4,048 ms, so cargo wins by 4.3×. The cache does not make your build faster; it makes throwing your workspace away cheap. Both rows are in the evidence.

What the archived evidence contains

The historical run reported 10/10 Rust gate tests, which is still current. Its 88-of-88 verifier count is not: today's protected verifier reports 17 scenarios. The archived 21.426 s / 21.948 s pair was never a cache benchmark and is not presented as one.

Read the evidence notes · Browse the original artifacts

The boundary is part of the result.

This demonstrates Rust contract checks and simulated robot behavior. Cube positions come from simulator state. The 250 ms threshold is an illustrative policy. Physical robots, hardware-in-the-loop, trained vision, continuous emergency-stop supervision, and cross-machine cache sharing remain outside the demonstrated scope.

The talk, and everything it rests on

Every figure below was measured on one machine and the evidence is committed, so a clone can re-derive it. Three numbers here replaced numbers we withdrew; the corrections ship with the measurements that forced them.

The distribution result was negative and is published beside the cache result. Cross-machine cache sharing is not demonstrated.