Harness: Codex (v3)
One of the three harness files a loop root reads beside the contract, published unchanged from the public export of the copy my own agents read.
- Source
- agent-docs/sources/loop/harness-codex.md
- Revision
- 0f4fd35
Read at launch with the contract and the charter.
Launch
cmd: codex -m gpt-6.1-sol -c model_reasoning_effort=high
You are the root. Read $PROTOCOL_SOURCE/sources/loop/contract.md, $PROTOCOL_SOURCE/sources/loop/harness-codex.md
and <abs charter path> in full. Write <abs closeout path> last, then reconcile and reply (contract section 12).
Standing: <abs path> sha256=<hex>
- The
agent-workflowsStop hook arms on “You are the root” plus one closeout path and releases a stop only for a counting closeout or a currentPAUSED:line. Nothing wakes a Codex root that ends its turn, soWAITING:releases nothing: hold the turn withwait_agentuntil the closeout is written. - Start at 6 to 8 live lanes and raise the count only while your own model time stays under about half of wall time.
Routes
| Role | agent_type |
Model / effort |
|---|---|---|
| implementation (default) | worker |
gpt-6.1-sol / medium |
| judgement, compose, board batches | senior |
gpt-6.1-sol / high |
| escalation (tripwire or owner-named) | senior-escalation |
gpt-6-astra / high |
| review and security review (read-only sandbox) | reviewer |
gpt-6.1-sol / high |
| read-only mapping, sweeps, single waits | scout |
gpt-6.1-sol / low |
- Spawn these by
agent_typeand pass no model or effort. A spawn without a matching installed agent is a harness fault: stop and say so. fork_turns: "none"with the complete brief for every lane. 19 child threads plus the root; keep about 7 free when lanes may delegate, and say in each brief whether it may.
Dispatch, repairs and questions
spawn_agent,wait_agent,list_agents,followup_task,send_messageandinterrupt_agentare direct calls, never inside an exec cell.- Prepare a lane’s worktree in one exec cell; the next call is the
spawn_agent. - Repair rounds and answers go to the same lane with
followup_task, carrying the new evidence. - Owner questions while the owner is present:
request_user_input_asyncfor a real decision only, plus aQUESTIONS.mdentry. Never prompt for something that needs no decision. - Never conclude dispatch is unavailable without a recorded
spawn_agenterror. A thread-pool limit means wait for a return, then retry.
Waits
- With lanes in flight and no local work, make one
wait_agentcall (up to 19 minutes). Returns arrive in context, not in the wait: process every return already in context before each wait. After compaction, reconcilelist_agentsagainstLANES.mdbefore the first wait. - A root with lanes in flight cannot also wait in an exec cell. Hand each process wait (main CI, a
release) to a
scoutwith the exact identity, terminal states and a deadline; its return quotes the raw readback. A deadline exit means “not observed”. - Lanes wait on their own processes with a self-polling exec cell (
yield_time_msup to 1140000) running one quiet command that exits on the terminal state. LOOP.md’s optionalci-statusreplacesghreads exactly as the contract’s lanes use it.- A process backgrounded with
&,nohupordisowndies with its exec call: start watchers as a foregroundexec_commandwithyield_time_ms1000 and record thesession_id. - A composed gate’s legs (contract section 6) start the same way, one
exec_commandper leg after thegit status --porcelaincheck. If one is refused, run the legs in turn and say so.
Closeout sweep
Send write_stdin "\u0003" to every watcher session still running and interrupt_agent every
live lane; list both under ## Notes.
Turn endings
A message with no tool call ends your turn and the loop stops until the operator returns. Never end
a turn with a summary that announces the next step, an offer to carry on, a list of decisions none
of which blocks the remaining work, or a decision that this is a good place to stop. Hold the turn
with wait_agent while lanes run. End a turn only when the closeout is written or when paused
(`PAUSED: <reason>` as the last line).