~/dev/myrepo praetor
$ praetor status

runtime         up  2h 14m 09s  ·  rev a3f1c89
sessions        3 active · 2 idle

  session-01    claude    fix-flaky-tests       stream  
  session-02    codex     audit-deps            execute 
  session-03    claude    draft-changelog       handle  
  session-04                                       idle
  session-05                                       idle

throughput      247 tok/s · 18,432 total
tasks           3 ready · 1 blocked · 7 done
next            test::integration    lint, fetch
trust           reviewer (host) · executor (sandbox)
session-02 → execute (3 tool calls pending)

A runtime that draws the line.

praetor hosts pluggable agents (Claude Code, Codex, your own) and dispatches their work through a dependency-aware task graph. The trust boundary is enforced by the runtime, not by polite request. Written in Rust.

Runtime

Pluggable, not bundled.

One runtime hosts many sessions, each with its own conversation, configuration, and JavaScript scripting environment. The runtime itself stays agnostic about which agent runs inside.

// register agents at boot runtime.register("claude", ClaudeCodeAgent::new())?; runtime.register("codex", CodexAgent::new())?; runtime.register("custom", MyAgent::new())?; // open a session bound to one let s = runtime.open_session("codex").await?; s.submit(task).await?;
Scheduling

Task graph, not tab manager.

The user-facing primitive is the task. Tasks declare dependencies; a workflow layer dispatches ready tasks to idle sessions.

// task graph fetch ──┐ ├──> test ──┐ lint ──┘ ├──> ship audit ──┘ // ready → idle session // blocked → waits on deps
Turns

Explicit phases, deterministic recovery.

Every turn walks a named phase machine. Failures land at known boundaries. Overflow triggers compact-and-retry. Cancellation interrupts at the next phase, never mid-stream in unknown state.

// turn phase machine accept → prepare preflight → stream → handle → execute recover? → persist → finalize // overflow ⇒ compact-and-retry
Configuration

Configuration is code.

Hooks, prompt builders, tool definitions, workflow logic. All written in code, with an effects bridge that lets configuration phases re-run safely without firing real side effects.

// .praetor/hooks.ts hooks.before("turn.stream", async (ctx) => { ctx.scratch.notes = await load(ctx.task.path); }); tools.define("git.diff", async ({ ref }) => { return effects.shell("git diff " + ref); });
Trust

Autonomy without ceding control.

A trusted reviewer owns commit and push authority. An untrusted executor edits and verifies inside a sandbox. The boundary is structural.

// authority by role reviewer executor ──────── ──────── edit files run checks read repo git commit git push modify hooks credentials