Skip to content

Steer phase 2 — VERIFIED protocol surfaces (FLT-103)

Ground truth probed locally on 2026-07-17 against the installed CLIs. Anything here that disagrees with steer-lane-consult.md supersedes it — the consult was research; this is what the binaries on this fleet actually expose.

Codex — codex app-server (codex-cli 0.144.1)

  • codex app-server exists (marked experimental), plus daemon / proxy subcommands. generate-json-schema --out <dir> emits the full protocol schema — regenerate after any Codex upgrade instead of trusting docs.
  • Wire method names (exact, from codex_app_server_protocol.v2.schemas.json): thread/start, turn/start, turn/steer, turn/interrupt; notifications thread/started, turn/started, turn/completed.
  • TurnSteerParams: {threadId, expectedTurnId, input: UserInput[]}expectedTurnId is a REQUIRED precondition; the request fails if it isn't the active turn. Get the id from the turn/started notification.
  • TurnStartParams: {threadId, input: UserInput[], model?, cwd?, sandboxPolicy?, approvalPolicy?, effort?, ...} (all overrides optional).
  • TurnInterruptParams: {threadId, turnId}.
  • ThreadStartParams: all-optional {cwd?, model?, sandbox?, approvalPolicy?, baseInstructions?, ephemeral?, ...}.
  • UserInput (text form): {type: "text", text: "..."}.
  • Live probe findings (PROBEOK transcript, 2026-07-18): bare codex app-server speaks line-delimited JSON-RPC on stdio; thread/start result carries result.thread.id; turn/start result carries result.turn.id; agent reply text arrives as item/completed with item.type=="agentMessage" and full item.text; turn/completed can be delivered TWICE for the same turn (dedupe by turn id); the server loads the user's MCP servers per thread (startup notifications; slower spawn) and NEVER exits on its own — the host owns the kill. ephemeral: true keeps fleet jobs out of thread history.

Claude Code — stream-json (2.1.211)

  • claude -p --input-format stream-json --output-format stream-json--input-format works only with --print. --include-partial-messages available; --resume exists.
  • Input line shape: {"type":"user","message":{"role":"user","content":"..."}} — one JSON object per line on stdin, stdin held open.
  • Messages sent while a turn runs queue as the NEXT turn (no same-turn append).

Grok (grok agent, SuperGrok CLI)

  • grok agent stdio (ACP over stdio), headless (WebSocket relay), serve, leader.
  • ACP: one prompt turn at a time; session/cancel then next session/prompt.

agy 1.1.3

  • No steer surface (re-confirmed nothing new in --help). Stays phase-1 kill-and-resume.

Capability map (implementation targets)

Agent Mechanism Caps
codex app-server stdio JSON-RPC, turn/steer SameTurnSteer, Interrupt
claude stream-json stdin, queued user message QueueNextTurn, Resume (kill + --resume)
grok ACP stdio, session/cancel + session/prompt Interrupt
agy / ollama / others phase-1 kill-and-resume (fallback)

Delivery order: Claude adapter first (line-framed stdin, simplest), Codex app-server second, grok ACP third/optional. Kill-and-resume remains the universal fallback whenever a session is absent or a session steer fails.