Runner protocol
The TypeScript contract lives in lib/runner.ts.
Start request
A start command contains:
- stable run and task IDs;
- repository and base branch;
- unique worktree name;
- room revision plus immutable intent and outcome snapshots;
- active project decisions;
- claimed write scope and prerequisite task IDs;
- versioned task prompt;
- provider, model, and agent instructions;
- permission profile.
The runner must reject a request it cannot isolate or authorize. It must never silently broaden permissions.
Commands
start: acquire an environment and launch the agentsteer: append human guidance to a running sessionpause: checkpoint and stop tool executionresume: continue from the checkpointcancel: terminate execution and preserve available evidence
Commands should include an idempotency key when transported over a network.
Events
Each event has a run ID, strictly increasing sequence, type, message, optional JSON payload, and occurrence time.
startedlogcheckpointchange-setfailedcompleted
The receiver deduplicates on (run_id, sequence). Large logs and artifacts
belong in object storage with signed references, not inside the room event.
Real Codex CLI adapter
A local adapter would:
- verify the signed lease and repository allowlist;
- fetch the base SHA and create a dedicated Git worktree;
- write the scoped prompt and repository guidance;
- launch Codex CLI non-interactively with the requested sandbox policy;
- translate JSONL/tool output into ordered runner events;
- checkpoint commits and run required commands;
- publish the head SHA, diff summary, check evidence, and cleanup policy.
Secrets are injected to the runner for an individual job and are never stored in room messages or the change-set payload.
Implementation status
This document describes the contract, not what runs today. Implemented: the
TypeScript types in lib/runner.ts and the dispatch call sites for start,
pause, resume, and cancel. Simulated: run progress and completion, driven by
a time-based reconciler that publishes a hardcoded fixture diff. Not implemented:
steer is never dispatched, the run_events table is never written, and no
runner event is produced or consumed by anything.