Two Ecosystems: Claude Code and OpenAI Codex

Codex Subagents: Delegation, Verification and Integration

How Codex subagents are launched, configured and permitted, how to write a delegation contract, and why the orchestrating agent must verify and integrate…

Chapter 38Two Ecosystems: Claude Code and OpenAI Codex

When a task grows, you can open several parallel threads of work and ask each one to solve its own part. That speeds up independent investigation, but it does not make the results automatically compatible, verified or safe. The main agent remains responsible for framing the work, for permissions, for pulling the evidence together and for the integrated answer.

This unit is about the built-in subagents in Codex: what to hand them, what actually gets separated, and how to check the result. The general structure of agents, context and handing work over are covered in how AI coding agents work, context as a limited resource and handoffs between agents and sessions; here we focus on what is specific to Codex.

Who frames the task, who does it and who is accountable

The orchestrator is the main agent: it plans the work, assigns parts of the task, tracks their state and assembles the result. A subagent is a subordinate agent to which the orchestrator hands a bounded assignment. In Codex each such launch gets its own agent thread, and a supported client shows that thread's activity or its finished report. A separate thread does not automatically mean a separate copy of the repository, separate credentials or full isolation from the main conversation's history. The current public documentation describes threads and how results are passed back, but it does not specify how much of the parent thread's history each child sees Codex documentation on subagents.

The lifecycle can be pictured as a sequence:

framing → launch → work → follow-up or waiting → returned result → verification → integration.

Codex manages launching subagents, passing follow-up messages, waiting for results and closing threads. The main thread can carry on with other independent work while the children investigate their parts; later it receives the collected answers. In the command-line interface (CLI), the <code>/agent</code> command lets you inspect and switch between agent threads. In the desktop app, activity is shown in the relevant panel; in the integrated development environment (IDE) extension, it is shown when the background-agents interface is available. How you view, steer and stop threads depends on the interface; do not assume there is the same button everywhere, or that stopping the parent request cancels every child operation in the same way.

In supported scenarios, the main agent can be told to send a child a follow-up, stop it or close its thread. Which commands exist and what these actions actually do depends on the client; closing a thread should not be taken as proof that an external side effect has already been undone.

In a child's report it is important to distinguish four things:

  1. The assignment was sent. This confirms only that the request was delivered.
  2. The thread is active or has finished. This is an execution state, not a judgement of correctness.
  3. The child returned a result. This may be evidence, a partial answer, an error or merely an acknowledgement.
  4. The main agent verified the result against the target state. Only at this point is there a basis for including it in the answer or integrating the changes.

If a child writes "done", that does not yet mean it carried out the assignment. If a process exits with a success code, that does not prove the required artifact was created either. The orchestrator compares the actual result against the criteria, not just against a launch indicator.

Where Codex subagents run and which settings are documented

OpenAI's current documentation distinguishes local Codex clients, ChatGPT Work and the application programming interface (API). These are not one universal system with the same commands, environment and numeric limits. As of the check date, the documentation describes subagent workflows in Codex in the desktop app, the CLI and the IDE extension. ChatGPT Work offers them only to eligible accounts and runs subordinate agents in a hosted environment. Whether the feature is available depends on the specific product, its version and the workspace policy Codex documentation on subagents.

Surface What is documented What should not be carried over to another surface
Codex in the ChatGPT desktop app You can ask directly for an independent part of the work to be split across subagents; the app shows the threads and summaries. Project rules or a Skill can also ask for delegation. The look of the panel or the controls in this version of the app are not a contract for the CLI or the API.
Codex CLI You can ask directly for parallel work; the <code>/agent</code> command opens the threads, and the main thread collects the results. Project rules or a Skill can also ask for delegation. <code>/agent</code> is a command of this interactive client, not a general shell command for any agent.
Codex IDE extension When the background-agents interface is available, the panel shows active threads, lets you stop all active runs and open an individual thread. The documentation does not promise the same stop button for each individual child; the Work interface or the CLI may behave differently.
ChatGPT Work Available to eligible accounts; the work happens in a hosted environment. At most intelligence levels delegation has to be requested explicitly; Ultra can delegate proactively. Do not assume the local Codex sandbox, its approval modes or the local disk are available here. Integrations and site permissions remain separate.
Codex Cloud These are separate cloud tasks in an isolated environment, not another name for the same child thread in local Codex. Codex Cloud documentation The public page does not establish whether each cloud task uses internal subagents. Do not attribute the local control model to them.
Responses API The documented multi-agent mode has its own API fields, session, event streams and execution model. The page marks it as beta and gives a default value for <code>max_concurrent_subagents</code>. These fields, limits and behaviours are not settings of the local Codex CLI or IDE.
Agents API A different API contract: subordinate agents work in an environment configured by the application, for which the documentation sets separate limits. Its field names, default number of parallel agents and rules for shared files must not be equated with the Codex client or the Responses API.

In local Codex, the documented setting <code>agents.enabled</code> defaults to <code>true</code>. The <code>agents.max_concurrent_threads_per_session</code> parameter caps the number of subordinate agent threads open at the same time, not counting the main one. If it is not set, Codex chooses a value itself; the official documentation does not publish a universal number for all clients. Older configurations may use the alias <code>agents.max_threads</code>. The number six in the configuration sample is an example, not a guaranteed default.

The model and reasoning effort can also differ. The model is taken from an explicit launch parameter, then from <code>agents.default_subagent_model</code>, and if neither is set, from the parent thread's setting. Reasoning effort is taken from an explicit launch parameter, then from <code>agents.default_subagent_reasoning_effort</code>. If the child inherited the model and no other effort level is set for it, it inherits the parent's effort level; if an explicit launch or a default setting chose a different model and no effort level is given, that model's default effort applies. A custom agent file can override the model and effort resolved this way; other session settings not specified in it are inherited from the parent. The built-in types <code>default</code>, <code>worker</code> and <code>explorer</code> describe the purpose of a role, but the role's name does not determine the quality of the answer. Custom Codex agent configuration files live in <code>~/.codex/agents/</code> or in the project's <code>.codex/agents/</code> and can set instructions, the model and the sandbox mode. They use TOML (Tom's Obvious, Minimal Language, a plain-text configuration format); before changing anything, check parameter names against the subagents reference and the configuration reference.

For interrupted runs, the configuration has <code>agents.interrupt_message</code>: by default Codex adds an interruption message to the context. This does not cancel the work itself and does not replace checking whether a result came back.

The public documentation of Codex's built-in subagents does not define a supported contract for nested subagents, a maximum tree depth or a universal cap on the total number of children. That means "not documented as a capability", not "proven impossible". Do not build a workflow around an assumption of nesting. The Responses API guide separately describes a tree of child runs and sets no fixed depth; the Agents API has its own multi-agent contract, but its public guide does not define nesting semantics. These rules must not be carried over to local Codex.

When delegation is worth it

Good cases share two features: the subordinate part has a clear boundary, and its result can be checked on its own. Typical examples are reading an independent set of files, checking a specific assumption against official sources, matching acceptance criteria against the current code, or making a bounded change in files that belong to that task. The current documentation advises starting with independent work, especially investigation and analysis, and being more careful with parallel editing: conflicts and coordination can cost more than the time saved OpenAI on subagent workflows.

It is usually simpler for the main agent to do a short action of one or two steps itself, or work whose shared contract has not been worked out yet. The dependency rules from decomposition and shaping and dependency graphs apply here: a result you need is a blocker, whereas a preferred order on its own is not. If one task depends on a decision that has not been made yet, launching both at once is premature: the orchestrator first has to resolve the uncertainty or appoint a single owner of the contract. Likewise, do not have different agents change the same file without explicit ownership and a way to resolve conflicts.

Before launching, ask yourself:

  • Can you describe the finished result in one sentence and tell it apart from intermediate work?
  • Does the child have specific sources and the exact revision it should work from?
  • Is this part independent of decisions that have not been made yet?
  • Is it clear which files and external systems the child may change?
  • What evidence will let you check the answer without taking a "done" status on faith?
  • Does moving the work out save more of the main thread's context than it adds in integration cost?

Each agent uses the model and tools separately, so parallel work consumes more tokens than a comparable single-agent run. On top of that come set-up time, reviewing several results, reruns and integration. Estimating the gain purely by the number of open threads is a poor measure; account for the attention of the human and of the orchestrator. Martin Fowler's practical analysis of the "orchestrator's tax" describes one incident and is the author's own experience, not a universal measurement Martin Fowler, "The Orchestrator's Tax".

The delegation contract

The word "expert" in a role name is not an adequate assignment. A useful contract gives the child a bounded scope of work and gives the orchestrator grounds to accept or reject the result. Include at least:

  1. Goal and decision. Why the answer is needed and which decision it should support.
  2. Boundaries. What is in scope, what is explicitly excluded, and which files or folders belong to other workers.
  3. Sources and revision. The exact documents, commit, branch, documentation version or data snapshot.
  4. Permitted actions. Read or edit, the named tools and systems, and any required approvals. Do not make the child guess at a permission it does not have.
  5. Expected evidence. A link, a path and line range, a search query, commands and their output, or another way to reproduce the finding.
  6. Stop conditions. How much uncertainty is enough to return a partial conclusion; where to stop and ask the main agent.
  7. Response format. Conclusion, evidence, exceptions, unknowns and next step, in a fixed structure.

How to limit the context you pass on and how to structure a handoff are covered in a separate context for a reviewer or subagent and in handoffs between agents and sessions. Here the contract matters for the next step: dividing ownership and defining merge points. For a read-only search you can require a table of "call → file and line → reason to consider it a consumer → check → uncertainty", forbid editing, and end the search after the specified folders and queries. For implementation, the contract fixes file owners and the meaning of the fields being exchanged. A generic instruction such as "check everything and fix it" defines neither a boundary nor a completion criterion.

Context, files, permissions and external state

Context. A subagent's thread is separate from the main thread as a place of execution and reporting. That is not a promise that the child knows every earlier decision the parent made. Pass it the facts, assumptions and constraints it needs explicitly, and name the source of truth by an exact path or version. A summary message keeps the raw log out of the main context, but the summary also has to be checked.

Files. The documentation on Git worktrees describes separate working copies of files for parallel Codex chats, but they share Git metadata — in particular commit history and branch records. This is no guarantee that every Codex subagent automatically gets its own worktree. If concurrent workers write to a shared working copy, give them non-overlapping files and agree on the contract. If a separate copy is needed, create and verify the worktree or another environment explicitly first Codex documentation on Git worktrees.

Processes and external data. A separate context does not separate a database, Jira, a cloud service account or a shared queue. Two threads may have different files but the same external credentials or the same shared test database. So when work has side effects, check not only the working copy but the environment itself, its permissions and the objects it can change.

Permissions. A local Codex subagent inherits the main thread's sandbox policy and approval mode; delegation by itself does not extend its capabilities. A custom configuration can specify a read-only sandbox, but active sandbox and approval-mode overrides in the parent thread also apply to the child and can take precedence over its profile; so a custom configuration is not an independent security boundary. In the CLI, an approval request sometimes arrives from an inactive thread; before answering, check which child sent it. In non-interactive mode, an action that needs a new approval may fail with an error that Codex returns to the main thread. ChatGPT Work uses a different model: there is no local Codex sandbox or local approval mode; the parent chat's tools and separate connector permissions apply. Source: official documentation on subagent permissions.

Having access to a repository is not permission to merge changes, deploy the product, spend money or expose secrets. The right to take such an action has to come from a separate, confirmed rule. The orchestrator can pass a child only the permissions it actually has, not an imagined authority its environment lacks.

Fan-out, and fan-in at the right point

Once the contract is clear, the orchestrator can hand independent parts out to several workers (fan-out). Collecting and combining the results is called fan-in. The fan-in point has an owner: usually the main agent, which checks each answer, compares them with each other and decides whether they allow moving on to integration. Automatically collecting the answers does not make that decision for it.

Before a parallel launch, fix the shared contract if the results will exchange data or code. For components it is important to name the owner of the schema or behaviour, rather than letting both workers independently infer it from neighbouring code. Also clarify:

  • which tasks really are independent of one another;
  • which folders or files each child may change;
  • which expectations are shared and which are local;
  • what must arrive from all children before the integrator starts assembling changes;
  • which integration evidence will check how they behave together.

Parallel searches are often simpler than parallel writes. If two independent investigations use the same documentation version, the orchestrator can work on another task meanwhile. If two agents change neighbouring modules behind a shared interface, write the interface down first and assign ownership. Even separate Git worktrees do not resolve a semantic contradiction: they only keep file copies and branches apart. Once the changes come back, the integrator checks them together on one defined revision.

Do not simply add conclusions together without checking the seams between them. Two reports can each be accurate on their own yet use different definitions of an "active user", different time zones, different units of measurement or different interpretations of a missing value. If the contradiction concerns a shared contract, integration waits for that contract's owner; you cannot "average" two incompatible assumptions.

Several reviewers do not guarantee independence. Two agents with the same model, the same task and the same sources can repeat the same mistake or miss the same assumption. A different vendor or model is not proof of truth either. For an important claim, set different checkable criteria: have one reviewer verify it against the primary source and another look for a counterexample or a gap in scope; the coordinator must examine the specific evidence and the disagreements, not count votes.

Hypothetical worked example: a search missed an API consumer

Situation. A team is changing the <code>season_id</code> field in a sports service's response. Before implementing, it needs to find every place in the repository that reads the old field, so that no client is left with a silent bug. The search is delegated to a subagent, because the client, adapter and test folders can be checked separately from the main discussion.

Assignment. The orchestrator specifies the exact commit, the files describing the response, all client folders and the tests. The child is allowed to read only. The request asks it to find both direct mentions of <code>season_id</code> and places where the response path is built through the adapter registry; for each finding it must return the file, line, call context, search query and an explanation of why this is a consumer. The conclusion must name unknown dynamic paths separately. The expected answer is a table, not file changes.

Returned result. The child finds two direct typed clients, several tests and some examples. The report says "all consumers found". However, its list of search queries contains only the field name, and the child did not check the dynamic adapter registry.

The orchestrator's check. The coordinator checks whether every folder in the assignment was covered, and searches itself for the endpoint address key and the places where adapters are registered. It finds a third consumer: a transformation of the response by field name, with no direct mention of <code>season_id</code> in the client code. The completeness claim is not accepted yet. The coordinator asks for a narrow follow-up search in the adapters, adds a row with the evidence, and marks the static search as incomplete wherever field names are built at runtime.

Accepted result. The table now separates confirmed consumers, tests and examples, and separately lists the dynamic places for which static scanning gives no complete guarantee. It supports the compatibility decision, but it does not prove that behaviour testing can be skipped.

Why this way. The subordinate agent produced useful findings, but the conclusion "all" rested on an unverified assumption about the completeness of the search. The coordinator checked exactly that load-bearing claim instead of redoing all of the child's work.

When it does not fit. If there is only one file and an obvious direct call, a parallel search will not save coordination costs. If the format is generated by code or comes from an external service, a single repository search is not enough — you need the specification, an execution log or a contract test.

This is a teaching model, not a real search run carried out for this course.

Hypothetical worked example: two implementations disagreed on the contract

Situation. A team is adding a payment summary to a match page. One child changes the server-side API endpoint; the other changes the page's user interface. Each part looks independent, but both rely on the shared meaning of the amount field.

Contract before launch. The coordinator fixes that the endpoint returns <code>amount_minor</code> — an integer in the currency's smallest units — <code>currency</code>, a three-letter code, and <code>captured_at</code>, the transaction time in an agreed time format. One designated person or one task owns the contract. The server-side agent and the interface agent are assigned different files; both receive the same criteria and test examples. Integration and cross-component checks remain with the coordinator.

Independent results. The server returns the amount <code>1234</code> meaning 12.34 currency units. The interface agent treats the same attribute as whole decimal units and displays 1,234.00. Both parts' local tests pass, because each part's own test data locked in its own interpretation of the field. This outcome is possible even when each agent carefully did exactly what its local brief asked.

Integration. The coordinator merges the changes and runs a contract integration check. It shows that the page interface scales the amount by the wrong factor. The orchestrator stops the two parts from being combined into a single change, shows them to the contract owner, fixes the display and checks the behaviour on the same data for both server and client code. After the fix, the checks are rerun on the merged revision, and the final set of changes is reviewed as a whole.

Why this way. Separate files reduced editing conflicts but did not ensure a shared meaning for the data. It was the contract and the integration test that caught the semantic mismatch, which the separate local examples could not see.

When it does not fit. If the contract has not been decided yet, do not let both agents treat their own interpretation as authoritative. Appoint a decision owner and open parallel implementation only after the meaning and the units are fixed. If both would have to edit the same component, it is better to leave it with one owner or split the work into sequential handoffs.

This is a teaching scenario; the results shown are not from tests that were actually run.

Hypothetical worked example: "tests passed" with no revision and no log

Situation. A subagent returns: "Done, all tests passed." The message contains no commit, no check name, no exit code and no log. The thread may have broken off while waiting; the child may have run the checks against an earlier state, or not run them at all.

The coordinator's response. The status is marked unverified, not successful. The coordinator asks for the exact revision, the working copy, the commands, the exit code and an excerpt of the relevant output. If no answer arrives, it checks the available commit itself and runs the required targeted check in the environment where the result is supposed to hold. It compares the verified commit with the revision it intends to integrate.

Result and the limits of the claim. If reproducible evidence arrives for the current revision, the coordinator can report exactly what passed and on which commit. If the revision or the result cannot be recovered, the work stays incomplete or unverifiable. If HEAD moves after a successful check, that check is no longer evidence for the new HEAD: it has to be repeated.

Why this way. A subagent's words record its claim, but they do not establish what was checked. A public report in the Codex repository about cases where a subordinate thread acknowledged an assignment but did not carry it out is a single user report. It shows a specific type of failure, not the frequency or typical reliability of all runs.

When it does not fit. Do not spend time rerunning every test if the criterion was a single documentation change. Recover exactly the check that supports the claim, and do not describe it as broader than it is.

This is a hypothetical case, not a claim that the tests in this example were run.

Local Codex, the Responses API and the Agents API

Concurrency limits differ and do not carry over between systems:

System Setting and default Environment
Local Codex <code>agents.max_concurrent_threads_per_session</code> (old alias <code>agents.max_threads</code>); a limit on open subagent threads, excluding the main one. The documentation does not fix a default value; the number six in the configuration sample is illustrative only. Behaviour depends on the client and the worktree.
Responses API <code>max_concurrent_subagents</code>; beta mode, default 3 active subagents, including descendants but excluding the main agent. There is no fixed upper bound on the limit, the tree depth or the total number of subagents. An API session and its event model.
Agents API <code>max_concurrent_subagents</code>; default 6 subagents, not counting the coordinator. The coordinator and subagents share the environment's file system; no new file system is created for a subagent.

Check the contract against the documentation for the version you need: API fields and limits may change. See the Responses API guide and the Agents API guide.

These differences should not be reduced to a table of "how many agents it is best to launch". In one API the contract sets the depth, environment, events, models and tools; in another, different defaults and file state apply. Check the documentation of the product and version where the code will actually run. The current Responses API documentation marks its multi-agent mode as beta; individual API fields and supported models may change.

Claude Code's documentation is useful for comparison only where it explicitly describes its own behaviour. It separately defines the child agent's context, tool parameters and nested launches up to a described depth. That is not proof that the same can be configured in Codex. For local Codex, the public guide does not define a supported nesting contract; the most accurate statement is that this behaviour is undocumented, not that it is impossible Claude Code: subagents.

Failure, waiting, retries and autonomy

A subagent may run for a long time, return only part of the result, hit a tool error, finish without a final answer, or not finish within the waiting period. In such cases, keep the intermediate findings already verified and re-issue only the unfinished part of the assignment. Do not blindly launch a second agent on the same action: if the first one may already have changed an external system, a retry can add a duplicate comment, ticket or transaction. For side effects, check the current state before retrying; for a read-only search it is usually safer to repeat only the range that was missed.

After an interruption, do not equate "the thread is no longer active" with "the result was saved". Check that a final report came back or that the required artifact is available. If the client lets you send the child a short follow-up, ask only for the result that has not arrived, rather than reissuing a vague order for the whole task. The open Codex issue #24951 describes one extremely long wait; the reporter had no small deterministic reproduction, although they provided logs. It is a single report, not an estimate of typical latency.

Autonomy applies only within the boundaries that were handed over. A child may read or change specified files, but the orchestrator checks its final list of changes and its side effects. Moving from "find" to "change", from "create a pull request" to "merge it", or from "check the test environment" to "update production" changes the class of action and requires a corresponding separate right. A parallel team is not a way to bypass the main agent's approvals.

A practical coordination loop

For local Codex, use a sequence that keeps responsibility for integration with the main thread:

  1. Decide whether there are two or more truly independent parts; keep simple or not-yet-shaped work in the main thread.
  2. Separate facts and the contract from assumptions, and appoint an owner for each shared decision.
  3. Prepare a bounded assignment with the required source, revision, files, permissions, evidence, stop conditions and expected format.
  4. Launch only as many agents as there are independent workstreams, within the limits of the configured surface.
  5. Carry on with independent work if needed; check active threads rather than spamming repeated wait requests.
  6. Collect the answers and check sources, changes and revision; mark claims without evidence as unverified.
  7. Bring the results together in one defined working copy, resolve disagreements and verify the integrated behaviour.
  8. Report exactly what is finished, which check was run, on which revision, what remains unknown and who has the right to the next side effect.

If any part of this sequence did not happen, do not hide it under a general "the agents handled it". Returned text is material for coordination; the result is only what was accepted against specific criteria and verified on the required state.

Sources and further reading

Documentation that may change and the state of GitHub issues were checked on 26 September 2026.

  1. OpenAI, Subagents, current Codex and ChatGPT Work documentation. Surfaces, launching, passing results back, models, configuration, permissions and costs; accessed 2026-09-26.
  2. OpenAI, Configuration reference, current Codex configuration documentation. Fields in the <code>[agents]</code> section and custom agent configuration; accessed 2026-09-26.
  3. OpenAI, Configuration sample, example Codex configuration. Illustrative settings, including an example concurrency limit; accessed 2026-09-26.
  4. OpenAI, Worktrees, current documentation. Separate working copies of files, shared Git metadata and parallel chats; accessed 2026-09-26.
  5. OpenAI, Codex cloud, current documentation. Separate cloud tasks and their environment; accessed 2026-09-26.
  6. OpenAI, Multi-agent Responses API, current beta guide. A separate API contract for multi-agent runs and concurrency limits; accessed 2026-09-26.
  7. OpenAI, Multi-agent Agents API, current documentation. A different API contract, the default concurrency limit and the shared environment; accessed 2026-09-26.
  8. Anthropic, Create custom subagents — Claude Code Docs, current documentation. Used only to contrast Claude Code's documented behaviour; accessed 2026-09-26.
  9. OpenAI Codex, Issue #23296, an open user report about a thread that received an assignment but did not carry it out. Used as an example of a failure type, not as statistics; accessed 2026-09-26.
  10. OpenAI Codex, Issue #24951, an open user report about an extremely long wait; the reporter did not provide a minimal reproduction, although they included logs. Used with the caveat stated in the text; accessed 2026-09-26.
  11. Martin Fowler, "The Orchestrator's Tax", 16 July 2026. A practical analysis of the cost of the orchestrator's attention based on a single incident, not a universal metric; accessed 2026-09-26.