Endstop

Rev 0.3.4 · in integration

Architecture

Contain the generated code. Mediate its physical effects.

The model's program executes on our board, on the same core as the loader and the envelope monitor, in the same address space. Nothing physical separates them. What separates them is a loader, an interpreter and an envelope monitor carrying fifteen machine-checked properties between them and a capability table of three entries fixed before the program runs. Hardware protection checks and seventeen jail-break probes have held on the physical board. This page is that arrangement, subsystem by subsystem.

§0

System definition

Endstop has two independent boundaries: one confines hostile generated code; the other mediates its physical proposals. The tables below specify each subsystem.

The two Endstop boundaries
BoundaryQuestion answeredMechanism
Execution containmentWhat may model-authored code reach while it runs?bounded VM, scratch-memory checks, fuel and an enumerated capability table
Physical mediationWhich proposed effects may reach the machine?fixed envelope monitor, independent feedback where integrated, and the stopping path

Consolidated implementation checklist and roadmap →

SubsystemSpecification
Host processorin-order RV32 soft core; no OS, no DMA, no network stack, no cache by default
Interpreter coredual-budget bytecode VM with memory-region isolation1
Capability tablethree typed effects: read state, propose setpoint, request signature
Envelope monitormulti-point limits, predicted stopping position, rate and acceleration ceilings, spectral resonance limiter, deadman
Feedback supervisorcaptured position/rate, following error and capture-sequence freshness
Effect constructiontrusted-side serialisation from an enumerated intent set with quantised parameters
Audit recordbounded capability journal sealed with Ed25519 on request
I/O surfaceserial in; PWM or step/direction out; relay drive in series with the safety chain; SPI secure element
Reaction timingmachine-specific capture-to-safe-state budget
Board integrationbring-up, timing closure, end-to-end measurement

We write the interpreter ourselves. The published verified VMs we evaluated proved a much larger machine than we run, arrived with a 2022 toolchain and a licence problem, and stopped at C rather than machine code. All seven properties of our own interpreter discharge, memory safety last, on 2 August 2026, to the depth a bounded model checker reaches. Physical-board loader/VM bring-up, UART diagnostics and workload-local counter timings have passed; what has been measured against the core's register-transfer description is in §2. The work in front of us is integration and measurement.

§1

The effect path

Within the specified program interface, every admitted effect follows one path: the instruction set exposes no file, socket, allocator or unmediated output verb.

  1. The agent (114), running off-board on untrusted host compute (110), sends a program over a serial interface (120) that carries programs in and verdicts out.
  2. The program executes in the interpreter (134) under a fuel bound. It terminates by construction; there is no analysis to defeat, only a counter that reaches zero.
  3. It may invoke exactly three capabilities through the capability table (136): read state, propose a setpoint, request a signature. There is no file, no socket, no allocator, no fourth verb.
  4. Each proposed effect is checked by the envelope monitor (138) against limits validated offline, covering multi-point position, predicted stopping position, rate and acceleration ceilings, a spectral resonance limiter and a deadman.
  5. Effects that pass are constructed by the trusted side and emitted (144) to the target driver stage (152). A failed check requests the configured safe reaction. The product design records every verdict and periodically seals the chain; the current emulator keeps a bounded journal sealed on request.

Two boundaries carry that path, and they do different jobs. The serial interface is the first: it keeps the loader, the interpreter and the monitor out of reach of whatever is running the model, so our code is not that machine's to patch. The second is the one the safety argument rests on. Step 2 executes the submitted program on the gate's own core, in the same address space as the loader and the monitor. Nothing physical stands between them. What separates them is the interpreter's semantics (fuel, the three-entry table, memory bounds) together with the RV32 physical-memory-protection configuration that holds the monitor's state out of the program's reach.

Memory safety in the interpreter is proven. The protection configuration has held in physical denial probes on the board. In the fabric-gate prototype, output permission already sits in fabric logic the processor cannot write itself into; the next isolation milestone moves the monitor's state there and puts the actuator path behind it.

The other side is deliberately thin. The part running the model is an inference engine: tokens in, tokens out, no interpretation of what it emits and nothing wired to it. So a misaligned model, a jailbreak, a prompt injection and an attacker in full control of that accelerator all arrive here as the same object, which is a hostile program at the loader. We removed the host from this boundary, so there is no separate class of host-compromise attack to answer.

100 BOUNDED-AUTHORITY ACTUATION SYSTEM 110 GRAPHICS PROCESSING UNIT 112 LANGUAGE MODEL PLANNER 114 UNTRUSTED · OFF-BOARD 120 PROGRAM + PARAMETERS 130 AUTHORITY GATE SOFT PROCESSOR 132 BOUNDED INTERPRETER FUEL-BOUNDED 134 CAPABILITY TABLE 136 ENVELOPE MONITOR MULTI-POINT · PREDICTED STOP 138 SECURE ELEMENT 140 AUDIT SIGNER 142 TRUSTED COMPUTING BASE 144 EFFECT 150 DRIVER STAGE PWM · STEP/DIR 152 SERVO DRIVE 154 ACTUATOR 156 ACTUATOR PLANE EMERGENCY STOP 162 CONTACTOR 164 160 INDEPENDENT OF GATE — SERIES INTERRUPTION FIG. 1
Figure 1. The effect path, with reference numerals. Authority terminates at the gate (130); the host reaches the actuator plane (150) only through the gate; and the safety chain (160) bypasses the gate entirely, interrupting the servo drive (154) in series. A numeral key lists all twenty references.
The e-stop is not in this list

The emergency-stop chain (160) is designed to run physically around the gate and open the contactor (164) in series with the servo drive. The gate itself regenerates the drive-facing command after enforcement, so it has functional authority to produce a motion command. The independent stopping path is designed to remove drive authority without relying on the interpreter.

§2

Two timescales, because the physics demands it

The fast control loops belong to the servo drive, and we leave them there. Current loops typically run at 8–20 kHz and velocity loops at around 5 kHz, all of it beneath us. What crosses the network is setpoints, typically at 500 Hz or as PWM.

LAYER RATE RUNS IN Planner / agent 10 – 100 Hz off-board · untrusted Setpoint stream 500 Hz · 2 ms ← ENDSTOP INSERTS HERE Position loop 250 Hz – 2 kHz servo drive Velocity loop ~5 kHz servo drive Current loop 8 – 20 kHz servo drive never traversed Fast loops stay in the drive. Only setpoints cross the boundary the gate sits on.
Figure 2. Where the gate inserts. The loops that stabilise the machine run at kilohertz rates inside the drive and never traverse the gate, so it cannot destabilise them. Only the setpoint stream crosses the boundary.

So enforcement splits. The slow path validates the envelope offline, once, the way every certified safety configuration in industry is validated. The fast path is a constant-time comparison against that envelope on every cycle, using table lookups with no allocation and no search.

PathRateWorkBudget
Offline validationper configurationenvelope derivation, risk assessment, signed acceptancehours
Admissionper programcapability grant check; forward-only programs may be checked against a versioned tick-credit tableseconds
Enforcementevery cyclemulti-point limits, stop prediction, rate, resonance, deadmanfits the 500 Hz cycle in RTL simulation

ISO 13855 converts the complete reaction time into required guard distance at the applicable approach speed. The relevant quantity is not an isolated monitor target: it is capture, phase delay, computation, output, drive response and mechanical stopping time together. Endstop has measured the monitor against the target core's RTL and in 12, 24, 48 and 96 MHz board workloads; a pilot must derive its allowable budget from the machine-specific hazard analysis and replace every remaining component with hardware measurements.

Timing evidence: RTL simulation

Against the NEORV32 register-transfer description, the monitor's worst tick is 13,218 cycles (528.7 µs at 25 MHz), or 26.4% of the 2 ms control cycle. With a 144-instruction interpreted program added, the per-tick workload takes 92.8% of the cycle at the pilot's 25 MHz and fits it. Place-and-route for this part closes between 90.0 and 102.5 MHz across five seeds, and at 75.4 MHz with all eight memory-protection regions enabled; at those clocks the same workload takes under a third of the cycle.

ISO 13855 prices the simulated monitor time at about 0.85 mm of separation, against a 58.9 mm servo deadband that dominates the stopping distance by roughly seventy to one, in the simulated configuration. End-to-end reaction time on a machine, from capture through drive response, is measured per machine in a pilot.

The interpreter no longer treats every instruction as the same amount of timing work. It keeps step fuel, which proves termination, separate from tick credits, which use a versioned target-specific cost table. The VM reserves an instruction's complete charge before executing it; an unaffordable capability call therefore cannot enter the callee. Forward-only programs can be rejected at load time when the fixed overhead plus every instruction charge exceeds the tick allowance.

The initial table comes from a retained no-cache NEORV32 RTL characterization. With a 25% engineering margin and rounding, charges range from 320 credits for a byte store to 480 credits for capability-call stubs, plus 416 credits of fixed invocation overhead. This is simulator characterization, not physical hardware or WCET. The capability rows are harness stubs, so operational timing admission remains disabled until deployed callees are bounded and an independent privileged deadline/watchdog prevents output commit on model error. The dated record is in the fuel-cost artifact; the full table is on the silicon page.

A second thing that was projected is now run. The design has been synthesised, placed and routed for the part the pilot targets: it takes 130 of 208 block RAMs and 6.1% of the logic; the multiplier maps onto dedicated hardware, and 25 MHz closes on every router seed we tried, the worst by 3.6×. Neither the fit nor the closure had been demonstrated by anyone before. The frequencies come from an open toolchain’s timing model, and the board has since run the soft core at up to 96 MHz; the silicon page carries every run and every part we tried.

The older figures of 216, 159 and 376 instructions per tick divided a period by a single dispatch measurement. They are retained as historical workload arithmetic, not current admission limits: instruction mix changes the cost, capability implementations were not included, and the monitor shares the core. MAX_STEP_FUEL remains 1,024, but it is only the platform-independent ceiling on dispatched instructions. A program receives an independently configured tick-credit allowance beneath that ceiling.

§3

The trusted side constructs the effect

The agent names an effect, and the trusted side constructs it. A gate that validates a byte string is validating a field it believes is the amount, the joint index, the destination. Encodings are adversarial: the same bytes mean different things under different parsers, and the attacker chooses the encoding.

The agent supplies an index into a pre-approved intent set and quantised parameters. The gate serialises the transaction or the setpoint itself.

Effects are named, not described

That is the design decision that came directly out of adversarial review, and it replaced an earlier design that inspected agent-supplied bytes.

Quantisation matters as much. We publish the residual: snapping parameters to a coarse grid and emitting on a fixed schedule reduces the bandwidth of any channel an agent might modulate, from arbitrary to countable.

Here is the count. The physical command is a 16-bit PWM at prescaler 8 — about 3,000 distinct steps across a servo's pulse range — emitted on a 50 Hz frame. An agent that owned every commanded position outright could modulate at most log2(3000) × 50 ≈ 580 bits per second, and less as the intent grid is made coarser than the hardware or the loop runs slower. On the bounty, getting any value out through it, at any rate, is a win.

§4

What is trusted, and what is merely present

A trusted computing base is only meaningful if you enumerate it. Ours is 1206 measured lines, and the parts outside it are listed with equal precision.

ComponentStatusBasis
Interpreter coremachine-checkedours, 667 lines; seven properties discharged with a bounded model checker1
Fuel accountingmachine-checkedstep fuel bounds termination; timing credits are prepaid before execution; the provisional cost table is simulator-derived
Memory isolationmachine-checkedevery access lands in the designated region; discharged 2 August 2026
Capability tableengineeredstatic; callee behaviour not proven
Envelope monitormachine-checked539 lines outside the VM; eight properties discharged, one exhaustive over all 232 inputs and one over every prismatic-axis configuration
Audit recordpart machine-checkedThe emulated board collects capability events in a bounded journal and seals the current batch when the program requests a signature. The request-signature callee is written and its message-building and journal plumbing machine-checked, retained for the source-audit release; the Ed25519 leaf is audited, its field arithmetic Coq-verified. The product design — a durable control-rate hash chain with periodically signed heads and a secure monotonic counter — is not yet implemented or demonstrated on hardware.
PMP configurationvalidated · narrow hardware mechanismon the physical board, a user-mode sweep of every protected region boundary faulted with its documented cause, and no user-mode access reached monitor RAM, the fabric gate, UART or GPIO
Debug / JTAG isolationplannedthe synthesis test configuration disables JTAG tests; permanent production disablement or physical isolation is a board-integration milestone
Boot & signature checkplannedimmutable first stage, image authentication and an anti-rollback counter, specified before any persistent configuration; the board runs volatile images only
Soft processorassumedin-order RV32, no speculation, no cache by default
Synthesis toolchainassumedopen toolchain, reproducible builds intended
Physical accessout of scopeno tamper response in the pilot
OUT OF SCOPE physical attacker · power & EM side channels · model-to-silicon gap ASSUMED in-order RV32 soft core · open synthesis toolchain ENGINEERED · tested boot & anti-rollback · driver stage · deadman MACHINE-CHECKED Interpreter · fuel · memory isolation · envelope monitor · capability table interpreter published · monitor under NDA ↓ trust decreases outward
Figure 3. Scope of assurance. The innermost band carries the published machine-checked property set; that is narrower than full functional correctness. Each band outward is a weaker claim, and the outermost is explicitly excluded. A trusted computing base is only meaningful if the exclusions are named.
Threat model exclusions

The pilot excludes physical attackers, power and electromagnetic side channels, and the gap between a formal hardware model and delivered silicon. Those exclusions are disqualifying for payment-HSM and cross-domain defence use, where tamper response is a baseline requirement, so we do not sell into those markets.

They are defensible for a fenced robot cell, where physical access is already controlled, and that is the market we address first.

§5

Deliberately small, deliberately dull hardware

An in-order RISC-V soft core on an FPGA, running from on-chip memory. No operating system. No DMA engine. No network stack. No cache by default, so timing is predictable and the speculative-execution attack classes do not exist to begin with.

Everything the device can do is visible on the pin map, and that is what makes an independent audit tractable. The I/O surface is specified as the complete effect vocabulary: a serial link in, PWM or step/direction out, a relay drive that sits in series with the existing safety chain, and an SPI secure element holding keys.

Signing runs off the control path entirely. The product record is designed to append events to a hash chain at control rate and periodically sign a chain head; it does not sign every verdict, so signing speed sets how often a head is sealed, not the control rate, and the control loop never waits on it.2 The signer is written: a real Ed25519 that builds for the board in under 80 KB with no heap and uses 6.5 KB of stack, its message-building and journal plumbing machine-checked and retained for the source-audit release, its field arithmetic from a Coq-verified backend. The emulated implementation seals its bounded journal on request; continuous durable chaining under a periodic-seal policy is the next milestone.

References

  1. The interpreter is ours: 667 measured lines of no_std Rust over a deliberately reduced instruction subset, verified with a bounded model checker. An earlier design inherited a published verified VM; that decision was reversed because the proof covered a much larger machine than we execute. Termination comes from a fuel cap, which holds for any program including one that loops. The harness bounds are shallow — one to three instructions, where the machine admits 256 — and deliberately so: the properties are structural. The memory-safety harness quantifies over a fully symbolic instruction, and termination is bounded by the fuel cap whatever the program does. The bounds themselves are in src/proofs.rs, one per harness.
  2. Measured figures for portable verified Ed25519 implementations on 32-bit RISC-V are approximately 1.2 million cycles per signature, which at the pilot's 25 MHz is about 48 ms. Implementation choice materially affects this. On the board, the signer in its default configuration, without a precomputed base-point table, measured 12,262,800 cycles per signature, about 0.49 s at 25 MHz (dated record).