Overview
The Agent Runner wraps workspace creation, prompt rendering, and app-server client integration. It creates/reuses workspaces, builds prompts from workflow templates, launches the coding agent subprocess, and forwards app-server events to the orchestrator.On any error during the agent run, the worker attempt fails and the orchestrator will retry according to the configured backoff policy.
Agent Runner Contract
The Agent Runner executes the following sequence:1. Workspace Creation
Create or reuse workspace for the issue
2. Prompt Building
Build prompt from workflow template
3. Session Startup
Start app-server session
4. Event Forwarding
Forward app-server events to orchestrator
Workspaces are intentionally preserved after successful runs to enable continuation across multiple agent sessions.
Workspace Creation and Lifecycle
Workspace Path Determination
Workspace Root
workspace.root (normalized path; the config layer expands path-like values and preserves bare relative names)Per-Issue Workspace Path
<workspace.root>/<sanitized_issue_identifier>Creation and Reuse Algorithm
This section does not assume any specific repository/VCS workflow. Workspace preparation beyond directory creation (e.g., dependency bootstrap, checkout/sync, code generation) is implementation-defined and typically handled via hooks.
Workspace Hooks
Supported hooks and their execution semantics:after_create
When: Only when a workspace directory is newly createdFailure: Aborts workspace creationTimeout: Uses
hooks.timeout_ms (default: 60000)before_run
When: Before each agent attempt after workspace preparation and before launching the coding agentFailure: Aborts the current attemptTimeout: Uses
hooks.timeout_ms (default: 60000)after_run
When: After each agent attempt (success, failure, timeout, or cancellation) once the workspace existsFailure: Logged but ignoredTimeout: Logged but ignored
before_remove
When: Before workspace deletion if the directory existsFailure: Logged but ignored; cleanup still proceedsTimeout: Logged but ignored
Workspace Safety Invariants
Invariant 1: Agent CWD
Run the coding agent only in the per-issue workspace path. Before launching the coding-agent subprocess, validate:
cwd == workspace_pathInvariant 2: Path Containment
Workspace path must stay inside workspace root:
- Normalize both paths to absolute
- Require
workspace_pathto haveworkspace_rootas a prefix directory - Reject any path outside the workspace root
Invariant 3: Sanitized Keys
Workspace key is sanitized:
- Only
[A-Za-z0-9._-]allowed in workspace directory names - Replace all other characters with
_
Prompt Construction
Inputs
Markdown body from
WORKFLOW.mdNormalized issue object with all fields
Optional retry/continuation metadata
Rendering Rules
- Render with strict variable checking (unknown variables fail rendering)
- Render with strict filter checking (unknown filters fail rendering)
- Convert issue object keys to strings for template compatibility
- Preserve nested arrays/maps (labels, blockers) so templates can iterate
Retry/Continuation Semantics
Failure Behavior
If prompt rendering fails:- Fail the run attempt immediately
- Let the orchestrator treat it like any other worker failure and decide retry behavior
Codex App-Server Integration
Launch Contract
codex.command (default: codex app-server)bash -lc <codex.command>Workspace path
Separate streams
Line-delimited protocol messages on stdout (JSON-RPC-like JSON per line)
Session Startup Handshake
The client must send these protocol messages in order:Session Identifiers
Thread ID
Read from
thread/start result: result.thread.idTurn ID
Read from each
turn/start result: result.turn.idSession ID
Emit as:
session_id = "<thread_id>-<turn_id>"Continuation
Reuse the same
thread_id for all continuation turns inside one worker runStreaming Turn Processing
The client reads line-delimited messages until the turn terminates.Line Handling Requirements
- Read protocol messages from stdout only
- Buffer partial stdout lines until newline arrives
- Attempt JSON parse on complete stdout lines
- Stderr is not part of the protocol stream:
- Ignore it or log it as diagnostics
- Do not attempt protocol JSON parsing on stderr
Emitted Runtime Events
The app-server client emits structured events to the orchestrator callback. Each event includes:Event type enum/string
UTC timestamp
Process ID if available
Optional token counts
session_started
startup_failed
turn_completed
turn_failed
turn_cancelled
turn_ended_with_error
turn_input_required
approval_auto_approved
unsupported_tool_call
notification
other_message
malformed
Approval, Tool Calls, and User Input Policy
Approval, sandbox, and user-input behavior is implementation-defined.Each implementation should document its chosen approval, sandbox, and operator-confirmation posture.
Timeouts and Error Mapping
Request/response timeout during startup and sync requests
Total turn stream timeout (1 hour)
Enforced by orchestrator based on event inactivity (5 minutes). If
<= 0, stall detection is disabled.