Skip to content

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)

  1. Every piece of state has one writer; every mutation flows through one choke point.
  2. Failures become states, never bespoke exception paths — and every failure serializes to a string an agent can read.
  3. RUNNING is earned by surviving, never granted by spawning.
  4. Sweeps happen always-and-only at generation boundaries; shared-struct changes are generation events (a reboot, by design).
  5. Never trust a bare PID — verify start time and the env cookie.
  6. Events are doorbells; data lives on a plane. Coalescing is a feature.
  7. Capture everything that cannot be reconstructed; record intent, not resolution. The spool is the record; the store is a cache.
  8. 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.