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 agent
  • steer: append human guidance to a running session
  • pause: checkpoint and stop tool execution
  • resume: continue from the checkpoint
  • cancel: 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.

  • started
  • log
  • checkpoint
  • change-set
  • failed
  • completed

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:

  1. verify the signed lease and repository allowlist;
  2. fetch the base SHA and create a dedicated Git worktree;
  3. write the scoped prompt and repository guidance;
  4. launch Codex CLI non-interactively with the requested sandbox policy;
  5. translate JSONL/tool output into ordered runner events;
  6. checkpoint commits and run required commands;
  7. 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.

CohentPractical guides for using and understanding Cohent