> ## Documentation Index
> Fetch the complete documentation index at: https://continuum-three-olive.vercel.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Codex

> Live Codex sessions over the codex app-server harness, with sandbox-gated approvals, the full reasoning-effort ramp, and respawn-lineage transcript resolution.

Continuum drives Codex through the `codex app-server` harness. Every live Codex session runs through one path: a driver speaking the experimental `codex app-server` stdio JSON-RPC dialect feeds the shared ACP harness bridge, which writes into the session's chat store. There is no PTY and no JSONL chat replay for Codex.

## Requirements

The `codex` CLI must be installed and signed in (`codex login`). Continuum needs no separate token — the app-server authenticates from Codex's own cached login. If the binary is missing or unusable you get a `codex_not_found` error with an "Install or repair Codex, then sign in with `codex login`" call to action; **Settings → Providers → Codex** can run `npm install -g @openai/codex` in an embedded terminal for you.

## How a session runs

The daemon launches `codex` with the `app-server` argument and handshakes over stdio JSON-RPC:

<Steps>
  <Step title="initialize">
    No ACP-style authenticate round-trip — Codex uses its cached login. The handshake advertises `experimentalApi` so the v2 thread/turn dialect is available.
  </Step>

  <Step title="thread/start">
    Creates a Codex thread. Continuum passes the per-session sandbox cwd, an approval policy, a sandbox mode, the model, and (when set) the reasoning-effort config override. The returned thread id becomes the session's external id.
  </Step>

  <Step title="turn/start">
    Each prompt sends the thread id, the input, and the effort. The request resolves at turn *acceptance*; the turn's end arrives later as a `turn/completed` notification, so turn lifecycle is driven by the notification stream, not the request response.
  </Step>
</Steps>

Interrupts send `turn/interrupt`. Mid-turn approval requests arrive as server-to-client approval calls that Continuum surfaces as permission prompts.

## Sandbox and approvals

Codex permission posture is set at `thread/start`, not via a CLI flag, and it follows the composer's two-state Plan ↔ Code pill:

| Pole                         | `approvalPolicy` | `sandbox`            |
| ---------------------------- | ---------------- | -------------------- |
| **Code** (skip approvals)    | `never`          | `danger-full-access` |
| **Plan** / ask-before-acting | `on-request`     | `workspace-write`    |

Code sessions default to skip-approvals. Flipping the pill rebuilds the harness bridge with the new posture rather than restarting the CLI from scratch. When Codex is asking, its mid-turn approval requests render through the same permission-prompt card used across providers.

## Plan approval

Codex has a real read-only Plan pole, and Continuum owns the "Approve & run" transition for it.

Approving does the cheapest thing that works: if the agent is currently blocked on its own plan-exit request, Continuum answers that request with a code mode so it proceeds with edit access **without** tearing down the bridge — the turn keeps its momentum. Only when there's no live pending approval (a plan captured before the bridge came up, or Codex's synthetic plan seeded at spawn) does it fall back to a kill-and-respawn with edit access. Either way the session's permission pill resolves to Code afterwards, on Mac and on iPhone.

<Note>
  The `approve-plan` endpoint returns `410 legacy_session_retired` only for retired runtimes — legacy pane-backed sessions and the old chat-SDK path — not for Codex.
</Note>

## Models and reasoning effort

The bundled catalog ships GPT-5.6 Sol, GPT-5.6 Terra, GPT-5.6 Luna, GPT-5.5, GPT-5.4, GPT-5.3 Codex Spark, GPT-5.3 Codex, and GPT-5.2 Codex. Sol is the default a fresh session resolves to.

Codex has the widest effort ramp of any provider: `minimal`, `low`, `medium`, `high`, `xhigh`, and `max` are all accepted. There is no `--reasoning-effort` flag — Continuum sends the value as a `model_reasoning_effort` config override at `thread/start` and on each `turn/start`. The Claude-only Ultracode selection folds to `xhigh` for Codex at the spawn boundary, so an unsupported value never reaches the CLI.

Changing model or effort mid-session rebuilds the harness bridge; it is not a Claude-style respawn-and-resume.

## Multi-account

A second Codex subscription is added in **Settings → Providers → Add account…**. Each non-primary account gets a deterministic config root, and the spawn environment sets `CODEX_HOME` to that root so the CLI's auth, history, and settings resolve per account — config-directory isolation, not a `HOME` swap. Codex's own `codex login` writes `auth.json` under that root. A session pinned to a removed account fails closed rather than silently billing the primary subscription.

## Usage analytics and quota

Codex reports rate-limit state in two places, and Continuum reads both.

The **live gauge** prefers `chatgpt.com/backend-api/wham/usage`, the account-wide view Codex Desktop's "Usage remaining" menu shows, and falls back to the `rate_limits` payload embedded in local session files when that call fails (offline, expired token, endpoint change). The two can diverge sharply: the local files carry the per-CLI bucket, while the account-wide window also counts your ChatGPT chat usage. Each bucket exposes a 5-hour rolling window and a 7-day weekly window.

**Historical analytics** are separate from both. Continuum parses `~/.codex/sessions/**/*.jsonl` for token-count events, each carrying a *cumulative* usage snapshot. The parser subtracts the previous cumulative to produce per-turn deltas; a non-monotonic drop (a session reset mid-file) is treated as a fresh baseline rather than emitted as a negative delta. Deltas are priced with the embedded pricing snapshot.

## Transcript resolution and respawn lineage

Live Codex chat doesn't replay JSONL while streaming, but Continuum still maps each session to its on-disk Codex rollout for history and search hydration, file-citation scanning, and the cold-miss snapshot reparse.

The resolver tracks respawn lineage so a session never strands on the wrong rollout: it returns the cached rollout if still valid, otherwise scans `~/.codex/sessions/` for the newest rollout inside the session's activity window, and an explicit spawn or invalidation can seed or force a rescan.

The scan is **cwd-hardened**: a candidate rollout's own recorded working directory must match the session's, so a sibling Codex rollout — a Spawn-mode tile, or any `codex` you launched in a terminal — can't silently re-point a live session's transcript at a different conversation. Legacy rollouts with no metadata line stay accepted for back-compat; a file still mid-creation is never selected, and is re-probed once its metadata line lands.

## Chat rendering

Live Codex chat renders from the app-server event stream. The mapper normalizes the v2 thread/turn dialect into provider-neutral events:

* assistant message deltas and whole messages, with commentary vs. final-answer phase metadata;
* reasoning deltas, rendered as collapsible "Thinking" rows rather than chat bubbles;
* tool and command runs with status, output, and exit code;
* proposed file edits with per-file unified diffs;
* plan and step checklists;
* approval requests, surfaced as permission prompts.

A newer CLI frame Continuum doesn't model yet degrades to a diagnostic placeholder rather than tearing the turn.

<Warning>
  A historical Codex `.jsonl` opened read-only — via search history, for instance — renders empty by design. The old chat decoder for Codex rollouts was deleted in June 2026 and those files are no longer decoded for replay. Claude history is unaffected; it uses its own decoder.
</Warning>

## Broadcast

Codex can participate in the Chat surface's multi-provider [broadcast](/docs/features/broadcast) mode — one prompt to several providers, answers side by side.

<Note>
  The Chat tab is hidden by default across every client while the product is focused on Code, so broadcast is not reachable from the default UI. See [Chat](/docs/surfaces/chat).
</Note>
