2026-03-15 21:21:09 +08:00
|
|
|
## Subagent dispatch requires multi-agent support
|
2026-03-06 11:56:15 -08:00
|
|
|
|
|
|
|
|
Add to your Codex config (`~/.codex/config.toml`):
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
[features]
|
2026-03-15 21:21:09 +08:00
|
|
|
multi_agent = true
|
2026-03-06 11:56:15 -08:00
|
|
|
```
|
|
|
|
|
|
2026-07-30 10:32:01 -07:00
|
|
|
This enables the multi-agent tools that skills like
|
|
|
|
|
`dispatching-parallel-agents` and `subagent-driven-development` use.
|
|
|
|
|
Which tools you get depends on the multi-agent version your model
|
|
|
|
|
preset selects (current presets run V2; older ones run V1). Trust your
|
|
|
|
|
actual tool list over any table — including this one — when they
|
|
|
|
|
disagree.
|
|
|
|
|
|
|
|
|
|
- **Spawning:** give children a clean context with
|
|
|
|
|
`spawn_agent {fork_turns: "none"}`; the default `"all"` copies your
|
|
|
|
|
entire transcript into the child. On Codex 0.145+, role files under
|
|
|
|
|
`~/.codex/agents/` attach to isolated forks via `agent_type`.
|
|
|
|
|
Full-history forks accept `model` and `reasoning_effort` overrides
|
|
|
|
|
(only `agent_type` is refused there) — isolated forks are the SDD
|
|
|
|
|
default for context hygiene, not because overrides require them.
|
|
|
|
|
- **Fix rounds:** resume the implementer with `followup_task` — it
|
|
|
|
|
delivers your message, triggers a turn, and transparently reloads a
|
|
|
|
|
child the harness evicted. Never dispatch a fresh implementer on the
|
|
|
|
|
theory that a spawned agent cannot be messaged again; on V2 it
|
|
|
|
|
always can.
|
|
|
|
|
- **Lifecycle:** V2 has no `close_agent`. Finished children are
|
|
|
|
|
evicted automatically when slots are needed; leaving them unclosed
|
|
|
|
|
costs nothing. Only V1 sessions have `close_agent` — there, close
|
|
|
|
|
reviewers when their review returns, and close each implementer
|
|
|
|
|
after its task's review passes.
|
|
|
|
|
- **Model names:** never copy a model name from a skill, table, or old
|
|
|
|
|
session into `spawn_agent` without checking it against your current
|
|
|
|
|
spawn allowlist — V2 accepts only V2-capable presets and hard-errors
|
|
|
|
|
on the rest.
|
2026-03-23 15:42:52 -07:00
|
|
|
|
2026-07-30 10:33:59 -07:00
|
|
|
## Waiting on children
|
|
|
|
|
|
|
|
|
|
`wait_agent` is an event subscription, not a poll: a long wait wakes
|
|
|
|
|
the moment a child produces mailbox activity, with the same latency as
|
|
|
|
|
a short one. Short-timeout polling buys nothing and costs a tool call —
|
|
|
|
|
and a context rebill — per poll. In measured sessions, roughly
|
|
|
|
|
two-thirds of all wait calls were short polls that timed out.
|
|
|
|
|
|
|
|
|
|
- While you still have local work, do not wait at all. A completed
|
|
|
|
|
child's final answer is pushed into your mailbox and arrives with
|
|
|
|
|
your next turn.
|
2026-07-30 15:57:32 -07:00
|
|
|
- When you are genuinely idle with children outstanding, wait in
|
|
|
|
|
bounded stretches: `wait_agent` with `timeout_ms` 300000-600000
|
|
|
|
|
(5-10 minutes). After each stretch — wake or timeout — post one
|
|
|
|
|
status line, run `list_agents`, and chase any child that finished
|
|
|
|
|
without reporting. Never stack polls shorter than five minutes; the
|
|
|
|
|
event subscription wakes a bounded stretch just as fast as a short
|
|
|
|
|
one.
|
2026-07-30 10:33:59 -07:00
|
|
|
- Completion mail cannot wake an idle controller (it is delivered
|
|
|
|
|
without triggering a turn); covering that idle window is
|
2026-07-30 15:57:32 -07:00
|
|
|
`wait_agent`'s only job. A stretch that times out with no activity
|
|
|
|
|
is your cue to reconcile, not to shorten the next stretch.
|
2026-07-30 10:33:59 -07:00
|
|
|
|
2026-07-30 10:35:28 -07:00
|
|
|
## Model routing on spawns
|
|
|
|
|
|
|
|
|
|
Every `spawn_agent` you issue — including when you are yourself a
|
|
|
|
|
spawned child running a fan-out — sets `model` AND `reasoning_effort`
|
|
|
|
|
explicitly, per the Model Selection rules of the skill you are
|
|
|
|
|
executing. Setting `model` alone is a trap: the child's effort
|
|
|
|
|
silently resets to that model's default, not to yours.
|
|
|
|
|
|
|
|
|
|
Ask your human partner to add a machine-level backstop to
|
|
|
|
|
`~/.codex/config.toml` so any spawn that slips through still routes to
|
|
|
|
|
a deliberate tier instead of silently inheriting the session's most
|
|
|
|
|
expensive model:
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
[agents]
|
|
|
|
|
default_subagent_model = "<a mid-tier model from your spawn allowlist>"
|
|
|
|
|
default_subagent_reasoning_effort = "medium"
|
|
|
|
|
```
|
|
|
|
|
|
2026-08-04 14:55:28 -07:00
|
|
|
## Compaction sheds these instructions
|
|
|
|
|
|
|
|
|
|
Context compaction replaces your transcript with a summary that keeps
|
|
|
|
|
your progress but not your working instructions — the first
|
|
|
|
|
post-compaction dispatch is where routing drift starts, and once one
|
|
|
|
|
bare spawn lands, the broken pattern becomes its own precedent. The
|
|
|
|
|
plugin ships a compaction re-injection hook (`hooks/hooks-codex.json`,
|
|
|
|
|
Codex 0.145+) that restores the bootstrap after every compaction; it
|
|
|
|
|
needs one-time trust approval, so if you never see a
|
|
|
|
|
`<CONTEXT_RESTORED>` block after a compaction, tell your human partner
|
|
|
|
|
the hook may be untrusted or unsupported on this version. Without it,
|
|
|
|
|
re-ground yourself: when a summary appears in your context, re-read
|
|
|
|
|
this file and the SKILL.md of the skill you are mid-way through
|
|
|
|
|
executing before your next dispatch, and trust the ledger over your
|
|
|
|
|
summarized memory of what happened.
|
|
|
|
|
|
2026-03-23 15:42:52 -07:00
|
|
|
## Environment Detection
|
|
|
|
|
|
|
|
|
|
Skills that create worktrees or finish branches should detect their
|
|
|
|
|
environment with read-only git commands before proceeding:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
|
|
|
|
|
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
|
|
|
|
|
BRANCH=$(git branch --show-current)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `GIT_DIR != GIT_COMMON` → already in a linked worktree (skip creation)
|
|
|
|
|
- `BRANCH` empty → detached HEAD (cannot branch/push/PR from sandbox)
|
|
|
|
|
|
|
|
|
|
See `using-git-worktrees` Step 0 and `finishing-a-development-branch`
|
|
|
|
|
Step 1 for how each skill uses these signals.
|
|
|
|
|
|
|
|
|
|
## Codex App Finishing
|
|
|
|
|
|
|
|
|
|
When the sandbox blocks branch/push operations (detached HEAD in an
|
|
|
|
|
externally managed worktree), the agent commits all work and informs
|
|
|
|
|
the user to use the App's native controls:
|
|
|
|
|
|
|
|
|
|
- **"Create branch"** — names the branch, then commit/push/PR via App UI
|
|
|
|
|
- **"Hand off to local"** — transfers work to the user's local checkout
|
|
|
|
|
|
|
|
|
|
The agent can still run tests, stage files, and output suggested branch
|
|
|
|
|
names, commit messages, and PR descriptions for the user to copy.
|