# Codex: a turn engine with explicit execution boundaries

Snapshot: **2026-10-18**, local repository `https://github.com/openai/codex.git`, commit **`8c076942cb70fba8e5c4732c23f1faabc4aed484`**. This is a source-based account of that revision, not a claim about every Codex release or the proprietary desktop/cloud implementation. The checkout was clean when inspected. No builds, tests, model calls, or example commands were executed for this research.

Codex is useful to study when a small “call model, execute tools, repeat” loop has grown into a system that must survive interruption, permissions, changing tool catalogs, long histories, and multiple clients. Its distinctive lesson is how much state belongs around that loop: a coherent request snapshot, execution policy, event delivery, and persistence checkpoints.

## First distinguish the layers and clocks

The Rust **core** implements conversation and execution behavior. Frontends present that behavior; the **app-server** accepts thread/turn requests and distributes events. At this revision even the noninteractive `codex exec` path starts an `InProcessAppServerClient`. That is a concrete integration seam, not evidence that every frontend uses an identical transport. [C1]

Three units of work matter:

- A **thread** supplies the continuing conversation identity and resumable history.
- A **user turn** is the running task that handles input and emits lifecycle events. `RegularTask::run` can invoke `run_turn` again if input remains pending.
- A **sampling request** asks the model for one response stream. `run_turn` can make many such requests as tools return, steering arrives, hooks continue work, or context changes. [C2]

Consequently, counting API requests is not counting turns. A single visible “fix this bug” turn might contain reading, editing, testing, another edit, and a final answer.

![Codex architecture: a RegularTask captures each sampling step, routes tools, collects ordered results, and checkpoints thread state.](../guide/assets/codex-architecture.svg)

The diagram is a reading map, not a complete dependency graph. Runtime policy differs by tool: command and patch execution use approval/sandbox orchestration; remote MCP execution is not implied to share the local process sandbox.

## The turn lifecycle

`run_turn` prepares context before the first request: it handles pending asynchronous hook output, compaction, relevant MCP readiness, skills/plugins, context changes, and accepted input. Each sampling step captures a `StepContext`, so tools execute against the tools, model settings, and environment associated with that request. [C3]

The following pseudocode omits lifecycle bookkeeping but preserves the important loop boundaries:

```text
RegularTask:
  emit TurnStarted; run startup contributors
  repeat:
    run_turn:
      prepare/compact context; record accepted input
      repeat:
        admit pending input at an allowed boundary
        capture coherent step; construct model prompt
        stream one model response, with transport retries
        dispatch completed tool calls as they arrive
        collect tool results into history in call order
        process asynchronous hook output
        if continuation is needed: compact/roll context if required
        otherwise run Stop hooks
        if Stop hooks request more work: continue
        otherwise finish this run_turn
    stop on terminal error
  until no pending input remains
```

“No more tool calls” is insufficient as a stop rule. Pending input can require continuation; a response can explicitly request a follow-up; Stop hooks can contribute new work. Conversely, an error can terminate the task without replaying queued input. The model stream must reach its completed event; a stream ending early is an error. [C2][C4]

### An illustrative read → edit → test → finish trace

This example was **not executed**. Tool availability, approvals, names, and command choice depend on configuration.

| Stage | Model and harness behavior |
|---|---|
| Input | User asks to fix an off-by-one error in `src/range.py`. The harness records input and builds the first step. |
| Read | Model requests `exec_command` with `cat src/range.py`. The harness parses arguments, applies execution policy, runs the command, and records the call/result pair. |
| Edit | The next model response requests `apply_patch`. Its freeform patch syntax is grammar-described; the handler verifies the patch against the selected filesystem and sends the verified action through the patch runtime/orchestrator. |
| Test | A later response requests `exec_command` with `python -m unittest tests.test_range`. If the process outlives the initial wait, terminal controls can collect more output. |
| Repair or finish | A failing result becomes input to another model request. A passing result may lead to a final explanation. Stop hooks and pending input still participate in determining completion. |

The harness supplies execution and feedback; it does not mechanically insert a test after every patch. That sequence is the model's chosen workflow in this illustration. Patch verification and the freeform specification are explicit code paths. [C5]

## Tools: exposure, execution, and ordering

`ToolRouter` distinguishes tools registered internally from tools actually exposed in the current step. Exposure can be direct, deferred through search, or available to Code Mode. It normalizes function, custom/freeform, and search response items into invocations. Unknown tools can produce model-visible errors rather than crashing the whole turn; incompatible internal payloads can be fatal. [C6]

The registry provides hooks around execution. A pre-tool hook can block or rewrite a request. Post-tool hooks run after successful execution and may reject the result. They cannot reverse an external side effect that already happened. Client-provided dynamic tools form another extension boundary: the handler sends a request outward and waits for the client's result. [C7]

Concurrency is deliberately selective. `ToolCallRuntime` waits for readiness before taking an execution lock. Parallel-capable tools acquire a shared read lock; other tools acquire the exclusive write lock. Tasks can start while the model stream continues. MCP tools opt into parallel execution through an explicit flag or their `readOnlyHint`; this is metadata-based admission, not a proof of purity. [C8][C9]

Execution completion order and conversation order are different. Sampling collects futures in `FuturesOrdered`, so history receives results in call order even when later calls finish earlier. Readiness notification can happen earlier than that ordered collection. This design preserves a predictable transcript while permitting useful overlap, at the cost of waiting behind an earlier slow call before later results enter ordered history. [C10]

## Approval is different from a sandbox

An **approval policy** decides whether an action may proceed or must be reviewed. An **OS sandbox** constrains what the resulting process can actually access. The tool orchestrator evaluates approval requirements, constructs sandbox attempts, and handles certain sandbox-denial retries. It does not simply rerun every failed command with greater authority. Escalation depends on policy and approval conditions; a Guardian-reviewed authority scope may require a fresh review for escalation. [C11]

Platform enforcement differs. The core documentation describes macOS Seatbelt, Linux sandbox selection, and Windows support constraints. Unsupported policy combinations can fail closed. These are implementation-specific capabilities, so a comparison should preserve the distinction between requested policy and supported enforcement rather than publish one universal “sandbox: yes” cell. [C12]

For a harness builder, the essential separation is authorization before execution, bounded execution, then explicit interpretation of failure. Tool descriptions alone do not enforce any of those boundaries.

## Long conversations: compaction has several meanings

Codex does not have only one summarization switch. The context-window code considers both an automatic-compaction threshold and the full model context limit; a threshold measured after a reusable prefix does not remove the full-context cap. Model changes can also require compaction, including a move to a smaller window or a changed compaction compatibility hash. [C13]

There are three important paths:

1. **Client-managed summarization.** `compact.rs` makes a model request with a compacting prompt. “Local” here means client-managed orchestration, not offline summarization. On context overflow it can remove older items and retry. The replacement retains selected recent user text plus a summary and reconstructs canonical context; it does not preserve every old item verbatim. [C14]
2. **Provider-supported remote compaction.** `run_auto_compact` selects the remote path when the provider advertises `RemoteCompactionSupport::V2`; otherwise it can use the client-managed path. Provider support is explicit capability information. [C15]
3. **Token-budget context rollover.** The token-budget path installs a fresh context window without running model/server summarization. Calling every window transition “summarization” would misdescribe this behavior. [C16]

Background compaction is another dimension, not a fourth summary format. It requires its feature and remote-provider capability and is disabled for token-budget mode. A background attempt captures history/model/auth compatibility information. Ready results are candidates adopted at defined checkpoints; they are not allowed to mutate arbitrary current history whenever the request finishes. Shutdown cancels pending work and waits for accounting. [C17]

These mechanisms protect different invariants: request size, coherent initial instructions, compatible model state, and continuity across history replacement. They also create a learning tradeoff: the model continues from a deliberately lossy representation, so a robust harness must identify what information survives and what must be recoverable from tools or storage.

## Steering and multiple clients

**Steering** means adding direction to an active task. At the app-server boundary, `turn/start` calls `start_or_steer_turn`: the result may be a newly started turn or input admitted to the existing turn. The explicit `turn/steer` route requires a nonempty expected turn ID and can reject stale or incompatible state. Within the loop, pending input is admitted at controlled boundaries; the initial request is protected from being overtaken by later queued input. Some feature-controlled paths can preempt sampling/retry waits to process newly available input. [C18][C3]

That means “steering supported” should not be read as “every tool stops instantly.” Cancellation, pending-input admission, model-stream preemption, and a completed tool's external effects are different events.

**Multiple clients** are supported as an app-server primitive. `ThreadStateManager` maintains sets of subscribed connection IDs per thread and reverse connection/thread mappings. One disconnected client can be removed without deleting the other subscriptions. A thread listener serializes resume-response/history work with subscription so attaching a client does not introduce a gap between the history snapshot and subsequent notifications. [C19]

These are useful foundations for shared sessions, but a connection is not necessarily a distinct human. In the inspected thread/turn processors, a complete multi-human product—identity attribution, role-based collaboration policy, presence, edit conflict resolution, or ownership transfer—was **not established**. `expectedTurnId` is a stale-input guard, not a collaborative document merge algorithm. Multi-agent child threads also have a separate ownership rule: direct app-server user input is disallowed for the relevant spawned-subagent surface. [C20]

## MCP, lazy discovery, and Code Mode

**MCP** supplies tool catalogs and remote tool execution. Codex translates MCP schemas into its own tool specifications, waits for server readiness, and captures the executed binding and output-policy snapshot so a refreshed catalog cannot silently reinterpret an already admitted call. Search text includes tool descriptions and useful schema/namespace metadata. [C9]

**Lazy discovery** reduces how much of that catalog must be exposed initially. `ToolSearchHandler` indexes deferred entries using BM25, a lexical ranking method. Search returns loadable tool specifications, with namespace coalescing. Its cache is tied to runtime identity and dynamic metadata; it can rebuild when the registry changes. The Code Mode search path filters candidates against that exact step's allowed nested-tool catalog before applying the result limit. [C21]

**Code Mode** lets a model express orchestration as JavaScript: call several tools, combine/filter their results, and emit selected output. It is distinct from running a shell script or using a persistent Node REPL. The inspected runtime creates a fresh V8 isolate/context for a cell, rejects static and dynamic imports, and exposes controlled globals such as `tools`, `ALL_TOOLS`, `text`, `store`, `load`, and yield/notification helpers. Cross-cell state is explicit through storage rather than arbitrary surviving JavaScript variables. Node filesystem/import APIs were not present in this inspected global surface. [C22]

For example, conceptually, a cell could `await Promise.all(...)` for two independent MCP lookups, then emit only a comparison. This reduces model round trips and intermediate text. It does **not** bypass normal tool handling: nested calls are translated back into typed tool payloads and routed through `ToolCallRuntime` with the originating `StepContext`. The delegate retains that snapshot across a yielded cell; recursive invocation of the execution tool is rejected. Long-running cells can yield, be waited on, or be terminated. [C23]

This architecture separates two costs: catalog selection determines what the model sees, while programmatic orchestration determines how many model turns are needed to combine tool work. Either can be useful independently; feature/configuration gates determine availability.

## Persistence, cancellation, and recovery

`ThreadStore` is an explicit storage-neutral boundary. An append is not automatically a universal durability guarantee. `Standard` persistence and `flush_thread` must make queued items durable/readable before returning. `TurnStart`, `SteeredUserInput`, and `SubagentSpawn` permit background persistence subject to later barriers; acknowledging a spawned child requires the documented standard barrier. `shutdown_thread` flushes; `discard_thread` may drop pending in-memory writes. [C24]

Resume also has an ordering contract: the store returns authoritative replay context after acquiring the writer, including writes committed before acquisition. Core reconstruction finds the latest usable compaction checkpoint and replays its surviving suffix, respecting rollback and restoring context/window metadata. A saved UI transcript and the next model prompt are therefore not interchangeable. This review does not establish implementation-level `fsync`, crash atomicity, or exactly-once external side effects. [C25]

Tool cancellation preserves already completed lifecycle outcomes. Runtime behavior can wait for handlers designated to finish on cancellation; otherwise it can abort the task and synthesize an aborted tool result. That is bookkeeping for interrupted work, not rollback of filesystem or remote effects. [C26]

Model transport recovery is separate. Response-stream errors use provider retry limits, retry delays, and supported fallback behavior. WebSocket-to-HTTPS fallback can reset the retry counter. An optional feature permits unbounded connection-failure retries for eligible paths, so “bounded retries” is not universally true across configurations. Context-window and usage-limit failures are handled differently from retryable transport failures. [C27]

## Providers, extensions, and agent teams

The provider interface covers metadata, authentication/recovery, model catalog/routing, and capabilities. The factory supports configured providers and a dedicated Bedrock path; capability declarations decide features such as remote compaction. This is an abstraction boundary with capability differences, not a promise that every provider implements every behavior. [C28]

Extensibility operates at several levels: Rust tool runtimes, dynamic client tools, MCP tools, skills/plugins contributing instructions or tools, and lifecycle/tool hooks. These extension points have different trust and execution boundaries. Adding a skill is not the same operation as registering a callable runtime. [C7][C29]

The multi-agent v2 tool surface includes spawn, send-message, follow-up, list, interrupt, and wait. Spawning can inherit history or start without it; spawn cleanup uses a guard to shut down/discard a provisional child on failure. The control graph enforces distinctions such as not interrupting the root/self through the child-control path. These are agent-thread orchestration primitives. They do not, by themselves, prove separate filesystem/worktree isolation for each child. [C30]

## What to test, and what the code already observes

The execution runtime records dispatch wait, handler duration, and total time, with care around nested Code Mode accounting. Registration telemetry distinguishes exposed and hidden/deferred tools. This makes an execution queue delay distinguishable from a slow handler. [C31]

Inspected tests cover cancellation before admission, preserving a completed lifecycle during cancellation, metadata-sensitive search-cache rebuilding, and coalescing mixed search results. They are useful executable descriptions of contracts; they were read, **not run**, for this chapter. [C32]

Three design lessons follow:

1. **Capture request state deliberately.** A tool must execute under the same relevant settings and catalog used to generate its request. Snapshots and bindings add machinery but prevent time-of-check/time-of-use confusion when input or catalogs change.
2. **Separate parallel work from ordered history.** Shared/exclusive execution admission plus ordered result insertion provides concurrency without an unpredictable replay transcript. The price is potential waiting behind earlier calls.
3. **Name your barriers.** Authorization, sandbox enforcement, turn completion, model completion, compaction adoption, and durable persistence are separate boundaries. Explicit contracts make recovery possible; collapsing them into a single “done” flag hides failure modes.

## Evidence matrix

All links below are immutable links to the inspected commit. IDs are stable within this research snapshot and can be reused by the comparison matrix.

| ID | Source-backed claim | Primary code entry point |
|---|---|---|
| C1 | Core/frontend seam; exec starts an in-process app-server client | [core README][C1a]; [exec startup][C1] |
| C2 | A task can repeat `run_turn`; each run can repeat sampling | [`RegularTask::run`][C2] |
| C3 | Inputs and coherent step state are prepared/admitted at loop boundaries | [`run_turn`][C3] |
| C4 | Follow-up, pending input, and Stop hooks influence completion | [`run_turn` continuation logic][C4] |
| C5 | Patch has a freeform grammar and verified execution path | [`create_apply_patch_freeform_tool`][C5a]; [`handle_call`][C5] |
| C6 | Router separates exposure and payload forms | [`ToolRouter`][C6] |
| C7 | Registry hooks surround execution; dynamic tools await client output | [`dispatch_any_with_state`][C7]; [dynamic handler][C7a] |
| C8 | Parallel tools use shared admission; others exclusive | [`handle_tool_call_with_source`][C8] |
| C9 | MCP parallel metadata, binding snapshot, and readiness | [`McpHandler`][C9] |
| C10 | Concurrent results are drained in insertion order | [`drain_in_flight`][C10] |
| C11 | Approval/sandbox attempt and escalation are policy-sensitive | [`ToolOrchestrator::run`][C11] |
| C12 | Platform sandbox support differs | [core sandbox documentation][C12] |
| C13 | Automatic thresholds and full context limits remain distinct | [context-window status][C13]; [model-switch compaction][C13a] |
| C14 | Client compaction summarizes and reconstructs retained context | [`run_compact_task_inner_impl`][C14]; [replacement history][C14a] |
| C15 | Provider capability selects remote compaction | [`run_auto_compact`][C15] |
| C16 | Token-budget rollover does not invoke summarization | [token-budget compaction][C16] |
| C17 | Background compaction is feature/capability gated and adopted later | [async compaction lifecycle][C17] |
| C18 | Start may steer; explicit steering checks expected turn ID | [`start_or_steer_turn` caller][C18]; [steer checks][C18a] |
| C19 | Multiple client subscriptions and ordered attach/history mechanism | [listener command][C19a]; [`ThreadStateManager`][C19] |
| C20 | Spawned child input has a separate ownership constraint | [direct-input guard][C20] |
| C21 | Deferred lexical search, cache, and Code Mode policy filtering | [`ToolSearchHandler`][C21] |
| C22 | Fresh V8 cell, controlled globals, rejected imports | [runtime][C22]; [globals][C22a]; [module loader][C22b] |
| C23 | Nested Code Mode calls reenter normal routing with origin context | [nested dispatch][C23]; [cell delegate][C23a] |
| C24 | Persistence contexts distinguish enqueue from durability barriers | [`PersistContext` and `ThreadStore`][C24] |
| C25 | Resume and compaction-aware reconstruction have explicit contracts | [`resume_thread` contract][C25]; [reconstruction][C25a] |
| C26 | Cancellation can preserve completed/finish-on-cancel outcomes | [tool cancellation branch][C26] |
| C27 | Stream retry limits, optional unbounded path, and fallback differ | [`handle_response_stream_error`][C27] |
| C28 | Provider interface and capability boundaries | [`ModelProvider`][C28]; [capabilities][C28a] |
| C29 | Skills/plugins and lifecycle contributors extend turn preparation | [`build_skills_and_plugins`][C29]; [task lifecycle][C29a] |
| C30 | Child thread tools, inheritance, and spawn cleanup | [tool surface][C30]; [spawn][C30a]; [spawn guard][C30b]; [interrupt][C30c] |
| C31 | Runtime timing and tool-exposure registration metrics exist | [timing guard][C31]; [registration metrics][C31a] |
| C32 | Contract tests exist for cancellation and search caching | [cancellation tests][C32]; [search tests][C32a] |

### Suggested source-reading path and limits

Start with `tasks/regular.rs`, then `session/turn.rs`. Follow one tool through `tools/router.rs`, `tools/registry.rs`, `tools/parallel.rs`, and its handler. Then read the orchestrator, compaction modules, and `thread-store/src/store.rs`. Finally trace app-server steering/subscriptions and Code Mode's nested dispatcher. This order keeps the basic feedback loop visible before introducing concurrency and recovery.

This is a focused source review, not a security audit or performance benchmark. Defaults, feature gates, provider capabilities, and frontend configuration affect which paths run. The chapter does not infer proprietary product behavior, remote MCP-server isolation, full multi-human collaboration, or crash-level durability from these interfaces. Revisiting a release should recheck each C-ID against the new pinned commit, especially loop entry points, persistence contracts, tool-exposure rules, and feature-gated compaction/Code Mode behavior.

[C1]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/exec/src/lib.rs#L1021-L1040
[C1a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/README.md#L1-L12
[C2]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tasks/regular.rs#L40-L126
[C3]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/turn.rs#L166-L570
[C4]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/turn.rs#L570-L800
[C5]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/apply_patch.rs#L307-L589
[C5a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/apply_patch_spec.rs#L9-L32
[C6]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/router.rs#L185-L311
[C7]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/registry.rs#L615-L910
[C7a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/dynamic.rs#L100-L282
[C8]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/parallel.rs#L126-L260
[C9]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/mcp.rs#L135-L325
[C10]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/turn.rs#L2568-L2695
[C11]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/orchestrator.rs#L125-L580
[C12]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/README.md#L13-L98
[C13]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/context_window.rs#L1-L130
[C13a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/turn.rs#L1416-L1506
[C14]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/compact.rs#L264-L610
[C14a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/compact.rs#L651-L794
[C15]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/turn.rs#L1507-L1613
[C16]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/compact_token_budget.rs#L1-L69
[C17]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/async_compaction.rs#L40-L214
[C18]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/app-server/src/request_processors/turn_processor.rs#L649-L737
[C18a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/app-server/src/request_processors/turn_processor.rs#L1045-L1150
[C19]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/app-server/src/thread_state.rs#L320-L687
[C19a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/app-server/src/thread_state.rs#L62-L103
[C20]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/app-server/src/request_processors/thread_input.rs#L1-L37
[C21]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/tool_search.rs#L66-L358
[C22]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/code-mode-runtime/src/runtime/mod.rs#L73-L260
[C22a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/code-mode-runtime/src/runtime/globals.rs#L15-L98
[C22b]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/code-mode-runtime/src/runtime/module_loader.rs#L142-L217
[C23]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/code_mode/mod.rs#L350-L474
[C23a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/code_mode/delegate.rs#L1-L250
[C24]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/thread-store/src/store.rs#L100-L250
[C25]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/thread-store/src/store.rs#L177-L205
[C25a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/rollout_reconstruction.rs#L65-L340
[C26]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/parallel.rs#L260-L335
[C27]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/responses_retry.rs#L57-L210
[C28]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/model-provider/src/provider.rs#L112-L420
[C28a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/model-provider/src/capabilities.rs#L1-L57
[C29]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/session/turn.rs#L1099-L1320
[C29a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tasks/lifecycle.rs#L1-L122
[C30]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/multi_agents_v2.rs#L1-L66
[C30a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs#L103-L260
[C30b]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/agent/control/spawn_guard.rs#L1-L105
[C30c]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/agent/control/interrupt.rs#L1-L52
[C31]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/parallel.rs#L399-L540
[C31a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/router.rs#L398-L440
[C32]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/parallel.rs#L604-L883
[C32a]: https://github.com/openai/codex/blob/8c076942cb70fba8e5c4732c23f1faabc4aed484/codex-rs/core/src/tools/handlers/tool_search.rs#L360-L620
