Runtime¶
On-robot process supervision and IPC. ~2,600 lines; clone koyu-runtime and hand the whole thing to your agent — this page carries only the why and the invariants.
Why it is shaped this way¶
Robots accrete peripherals: a new camera, a foot pedal, a frontend button, a
different actuator. The runtime is built so that adding a process is cheap
and safe: supervisord (18 years of process-management scar tissue, used
as-is) owns lifecycle; iceoryx2 shared-memory IPC gives zero-copy
transport with process isolation, so your agent can add or replace a service
without touching the others. And because every message crosses inspectable
shared memory, debugging is looking: the always-on flight recorder
(ipc_logger) journals every topic, and koyu get / tail / frame let an
agent see inside a live robot — is the sensor publishing, what did the camera
last see — without a debugger.
Four IPC planes, chosen by one rule (how many readers, and does anyone need history?): streams for samples (camera, joints) · blackboard for current truth (params, telemetry) · events as coalescing payload-less doorbells · request-response, deliberately almost unused.
The data recorder is the runtime's data product: clock-gated capture of declared topics, finalized as format-conformant bundles, committed by atomic rename into a spool/outbox. That outbox is the entire interface between the robot and everything downstream.
The invariants (do not break these; everything else is fair game)¶
- Every piece of state has one writer; every mutation flows through one choke point.
- Failures become states, never bespoke exception paths — and every failure serializes to a string an agent can read.
- RUNNING is earned by surviving, never granted by spawning.
- Sweeps happen always-and-only at generation boundaries; shared-struct changes are generation events (a reboot, by design).
- Never trust a bare PID — verify start time and the env cookie.
- Events are doorbells; data lives on a plane. Coalescing is a feature.
- Capture everything that cannot be reconstructed; record intent, not resolution. The spool is the record; the store is a cache.
- Python never stands in a loop with a deadline.
The full rationale lives in the repo's design doc — start there, it is the best single document in the codebase.