Claude Code vs OpenAI Codex: harness internals as documented on 2026-11-10
Reliability of this briefing
- Verified means I read the cited page today. Source tags like [C1] or [O3] point to the list at the end.
- OpenAI blog posts returned HTTP 403 (unrolling the agent loop, harness engineering, App Server). Their content below comes from search excerpts and secondary summaries, tagged [O-sec].
- Codex docs have moved:
developers.openai.com/codex/*now 308-redirects tolearn.chatgpt.com/docs/*. - Not verified today:
- Codex rollout path (
~/.codex/sessions/.../rollout-*.jsonlis from memory only). - Codex default auto-compact limit and tool-output truncation defaults.
- Agents SDK default
max_turns. - Claude Code's exact auto-compact threshold per model, Bash output cap, and which small model runs background utilities.
apply_patchgrammar (secondary sources only).- Seccomp on Linux for Codex (not mentioned in the pages I read).
- Codex rollout path (
- Lines marked Inference are mine, not vendor statements.
1. Agent loop
Claude Code / Agent SDK [C1, C2]
- A turn is one model response plus execution of its tool calls. The loop ends when a response contains no tool calls.
- SDK message stream:
SystemMessage(init),AssistantMessageper content block,UserMessagefor tool results, optionalStreamEvent, thenResultMessage. - Result subtypes:
success,error_max_turns,error_max_budget_usd,error_during_execution,error_max_structured_output_retries. - Parallelism: read-only tools (Read, Glob, Grep, MCP tools with
readOnlyHint) run concurrently; Edit, Write and Bash run sequentially. - Limits:
max_turnsandmax_budget_usd, both unlimited by default. Budget is checked after each response, so it can overshoot by one response plus running subagents. - Steering: Esc cancels the running tool call. A message typed mid-turn is queued and read as soon as the current tool calls finish, within the same turn.
- Thinking: adaptive reasoning on current models (the model decides per step). Effort levels are low, medium, high, xhigh, max; fixed
MAX_THINKING_TOKENSbudgets apply only to 4.6-era models [C9].
Codex [O-sec, O8, O9]
- A turn is one user input followed by many Responses API inference and tool cycles, ending on an assistant message.
- Codex does not use
previous_response_id; requests are stateless and ZDR-compatible, with reasoning carried as encrypted content. - The App Server exposes Thread, Turn and Item over bidirectional JSON-RPC (JSONL on stdio; WebSocket is experimental). Items have a
started, delta,completedlifecycle. - Control methods:
turn/start,turn/steer,turn/interrupt. In the TUI, Enter injects into the current turn and Tab queues for the next. - Agents SDK loop: final output, handoff, or tool calls then loop again; exceeding
max_turnsraisesMaxTurnsExceeded.parallel_tool_callsandtool_execution.max_function_tool_concurrencycontrol concurrency [O12].
2. Context management
Claude Code [C1, C3, C4, C5, A3]
- Request order is built for prefix caching: system prompt and tool definitions, then project context (CLAUDE.md, auto memory, unscoped rules), then conversation.
- Mid-session changes (plan mode, skills, output style, file-changed notices) are appended as messages or
<system-reminder>blocks, never edited into the prefix. - CLAUDE.md hierarchy: managed policy, user
~/.claude/CLAUDE.md, project./CLAUDE.mdor.claude/CLAUDE.md, andCLAUDE.local.md. - Auto memory: Claude writes
MEMORY.mdplus topic files; the first 200 lines or 25 KB load each session. - Compaction: a separate summarisation request reuses the cached prefix. Afterwards:
- Re-injected from disk: root CLAUDE.md, auto memory, the plan, skill descriptions.
- Re-read: up to five recently modified files (files over 5,000 tokens come back as a path reference only).
- Invoked skill bodies: capped at 5,000 tokens each and 25,000 total.
- Lost: path-scoped rules and nested CLAUDE.md, until re-triggered.
- A thrashing guard stops auto-compaction after repeated immediate refills.
- Tool-result clearing exists and is counted as an "expected rebuild" of the cache.
- Cache TTL: 1 hour for the main conversation on subscriptions, 5 minutes for API keys and for subagents. Invalidators include model switch, effort change on most models, and tool-set change when tools are not deferred.
- API primitives [A5, A6, A7]:
clear_tool_uses_20250919: trigger 100k input tokens, keep 3 tool uses,clear_at_leastto amortise the cache break.clear_thinking_20251015.- Server-side compaction: on-demand (
compact-2026-09-04) or threshold. - Client-side
memory_20250818tool, which auto-injects an "assume interruption" protocol into the system prompt.
Codex [O1, O-sec, O6, O7]
- Initial prompt items, in order: developer message with sandbox and permission instructions, developer instructions, user instructions aggregated from AGENTS.md, skills block, environment context.
- AGENTS.md: global
~/.codex/AGENTS.override.mdorAGENTS.md, then project root down to cwd, one file per directory, concatenated. Capped byproject_doc_max_bytes(32 KiB) and built once per run. - Caching depends on exact prefix. Changes to sandbox, approval mode or cwd are appended as new messages; MCP
tools/list_changedmid-session is a known cache-buster. - Auto-compaction calls
/responses/compactwhenmodel_auto_compact_token_limitis exceeded. It returns atype=compactionitem with opaqueencrypted_content.compact_promptoverrides the prompt. - Memories are off by default (
features.memories). They are generated in the background from idle threads, stored under~/.codex/memories_v2/, use separate extract and consolidation models, and redact secrets. - Skills list budget: 2% of the context window. Hook output shown to the model is capped at about 2,500 tokens.
3. Subagents and multi-agent
Claude Code [C6, C7, C8, A1]
- Definition: Markdown with YAML frontmatter. Fields include
tools,disallowedTools,model,effort,permissionMode,skills,memory,isolation: worktree,background,maxTurns,autoCompactWindow. - Precedence: managed, then
--agents, then.claude/agents/, then~/.claude/agents/, then plugins. - Context: fresh window containing its own system prompt, the delegation message, CLAUDE.md and git status. It gets no parent history. Explore and Plan skip CLAUDE.md.
- Only the final report returns to the parent. Reports are scanned for instruction-like text.
- A fork inherits the parent prefix and therefore reads the parent's cache.
- Limits: nesting depth 3, concurrency 20. Subagents run in the background by default, and
SendMessageresumes one with its history. - Transcripts:
~/.claude/projects/{project}/{sessionId}/subagents/agent-{id}.jsonl. - Agent teams (experimental): lead plus teammates, a file-locked shared task list, JSON mailboxes in
~/.claude/teams/. No nested teams, no resume of in-process teammates. Recommended size is 3–5 teammates. - Vendor-reported costs: about 7x tokens for teams when teammates run in plan mode; agents about 4x chat and multi-agent about 15x chat.
- Vendor-reported failure modes: 50 subagents spawned for a simple query, duplicated work from vague delegation, the lead doing the work itself, tasks never marked complete, and same-file overwrites.
Codex [O5]
- Built-in roles:
default,worker,explorer. Custom agents are TOML files in.codex/agents/withname,description,developer_instructions, and optionalmodelandmodel_reasoning_effort. - Concurrency is set by
agents.max_concurrent_threads_per_session. - Subagents inherit the parent's sandbox and approval settings and cannot override them.
- The parent waits for all results and gets summaries back. Delegation happens mainly on explicit request, or when AGENTS.md or a skill asks for it.
- The docs' rationale is context pollution and context rot. They state token use is higher than single-agent runs but give no multiplier.
- Worktree isolation:
codex fork <id> --worktree.
4. Planning, tracking, verification
Claude Code [C1, C10, A2, A3]
- Plan mode is read-only exploration; the plan is written to disk and survives compaction.
opusplanuses Opus to plan and Sonnet to execute, at the cost of a cache reset on each toggle. - Task tools (
TaskCreate,TaskUpdate) and task hooks (TaskCreated,TaskCompleted,TeammateIdle,Stop) can block completion with exit code 2. - Checkpoints: one per user prompt, 100 kept. They cover file-tool edits only, not Bash-only changes or most subagent edits. Rewind can restore code, conversation or both, or "summarize from here".
- Long-horizon pattern from Anthropic:
- An initializer session writes
feature_list.json(200+ features, all failing, only thepassesfield editable),claude-progress.txtandinit.sh. - Each worker session reads progress and git log, runs a smoke test, implements one feature, verifies end to end, and commits.
- Named failures: one-shotting, premature "done", marking features passed without testing.
- An initializer session writes
Codex [O9, O10, O-sec]
/planmode with its ownplan_mode_reasoning_effort./goal <objective>(4,000 characters max) acts as both the prompt and the completion criterion, and can be paused, resumed or edited./revieworcodex reviewruns a reviewer, optionally on a separatereview_model.- OpenAI's harness-engineering post: AGENTS.md of about 100 lines used as a table of contents into
docs/as the system of record; architecture enforced by linters and structural tests; continuous clean-up. Reported output is about 1M lines and about 1,500 PRs, at 3.5 PRs per engineer per day.
5. Tools, MCP, skills, hooks
Claude Code [C2, C11, C12, C13]
- Built-ins: Read, Edit (exact string replacement; observed directly in this session's tool schema), Write, Glob, Grep, Bash, WebSearch, WebFetch, Agent, Skill, AskUserQuestion, Task tools, ToolSearch.
- MCP and non-core tools are deferred by default. Only names enter context and schemas load through ToolSearch, which also keeps the cached prefix stable.
- MCP: stdio and streamable HTTP (SSE deprecated), OAuth, names of the form
mcp__server__tool. Output warning at 10k tokens and cap at 25k (MAX_MCP_OUTPUT_TOKENS). - Skills:
SKILL.mdwith frontmatter. Descriptions are truncated at 1,536 characters in the listing; the body loads on invocation; supporting files load on reference. Supportscontext: forkand dynamic!commandinjection. - Hooks: 33 events. Handler types are command, http, mcp_tool, prompt and agent.
PreToolUsecan return allow, deny, ask or defer, plusupdatedInput.
Codex [O4, O6, O7, O11, O-sec]
- Editing uses
apply_patch, a freeform custom tool constrained by a Lark grammar (*** Begin Patchenvelope with Add, Update and Delete File directives), not JSON. - Shell runs through unified exec. Web search modes are
cached(default, an OpenAI-maintained index),live,indexedanddisabled. - MCP: stdio and streamable HTTP, bearer token from an env var or
codex mcp login. Per-toolapproval_mode,enabled_toolsanddisabled_tools. Timeouts are 10 s startup and 60 s per tool. - Skills use the same
SKILL.mdstandard, in.agents/skills, with an optionalagents/openai.yaml. - Hooks: 14 events, including
PreModelRequestandPostModelRequest. Hooks must be trusted before they run. Hosted tools such as web search are not interceptable, and the docs call hooks "a useful guardrail, not a complete enforcement boundary".
6. Permissions and safety
Claude Code [C14, C15, A4]
- Modes: default (manual), acceptEdits, plan, auto, dontAsk, bypassPermissions. Deny rules win in every mode.
- Protected paths (
.git,.claude, shell rc files,.mcp.json) and critical-pathrmare never pre-approved by allow rules. - Auto mode:
- Rules resolve first, then read-only actions and in-project edits are auto-approved, then everything else goes to a classifier (Sonnet-class).
- The classifier sees user messages, tool calls and CLAUDE.md only; tool results and assistant text are stripped.
- Two stages: a single-token filter, then chain-of-thought.
- A separate injection probe runs on tool outputs.
- Broad allow rules such as
Bash(*)andBash(python*)are dropped on entry. - Falls back to prompting after 3 consecutive or 20 total blocks.
- Reported 0.4% false-positive rate and 17% false-negative rate on overeager actions.
- Subagents are checked at delegation, per action, and on return.
- Sandbox (Bash only): Seatbelt on macOS; bubblewrap plus socat on Linux, with an optional seccomp filter for Unix sockets. All egress goes through a local proxy with a domain allowlist that starts empty.
- Read, Edit, WebFetch, hooks and MCP servers are not sandboxed. Reads of
~/.sshare allowed by default. dangerouslyDisableSandboxis an escape hatch that goes through the permission flow.
Codex [O2, O3, O4, O13]
- Two orthogonal axes: sandbox mode (
read-only,workspace-write,danger-full-access) and approval policy (on-request,never,granular;untrustedis retired). - In
workspace-write,.git,.agents,.codexand.awsstay read-only, and network is off by default. An optionalnetwork_proxyadds a domain allowlist. - Enforcement:
/usr/bin/sandbox-execon macOS; bubblewrap on Linux (system or bundled, with a legacy Landlock path); restricted token or elevated sandbox on Windows, failing closed. - Execpolicy rules allow, prompt or forbid command prefixes.
- Auto-review (
approvals_reviewer = "auto_review"): a reviewer agent sees a compact transcript and the exact action, can run read-only checks, and interrupts the turn after 3 consecutive denials or 10 in the last 50. - Cloud: secrets are injected by the proxy as placeholders for allowed destinations. MCP tools annotated destructive always prompt.
7. Persistence
Claude Code [C1, C6, C10]
- Plaintext JSONL per session under
~/.claude/projects/.--resumekeeps the same ID;--fork-sessionor/branchcreates a new one. - File snapshots are retained about 30 days. The SDK
sessionStoreadapter mirrors transcripts to your own backend. - Execution can be local, cloud VMs, or Remote Control.
Codex [O8, O9, O14]
- Thread logs are JSONL rollouts.
codex resume,codex fork, andthread/forkwithephemeral: trueare supported.thread/rollbackhas been replaced bythread/revert. - Double Esc edits a previous message and forks from it; there is no file-snapshot rewind.
- Cloud tasks run in VMs with 2–4 vCPU and 8–16 GiB; saved VM state is recoverable for 7 days.
8. Model usage
Claude Code [C6, C9, C14, C16]
- Subagent model resolution order: per-invocation parameter, frontmatter,
CLAUDE_CODE_SUBAGENT_MODEL, then the parent's model. - claude-code-guide runs on Haiku and statusline-setup on Sonnet. The auto-mode classifier is Sonnet-class.
- Docs recommend Sonnet for teammates and
model: haikufor simple subagents. A fallback chain holds up to three models. - Enterprise average is about $13 per developer per active day.
Codex [O5, O15]
- Current model line-up is Astra, GPT-6.1 Sol, GPT-6.1 Terra and Luna (the small, high-volume one); efforts run from Low to Ultra.
- Settings:
agents.default_subagent_model,default_subagent_reasoning_effort,review_model, and separate memory extract and consolidation models.
Design lessons to adopt / pitfalls to avoid
- Treat the prompt as an append-only log. Order it static to dynamic and deliver every mid-session change as an appended message. Both vendors do this for cache hits.
- Freeze the tool list per conversation. Defer large or MCP tool schemas behind a search tool, and do not honour
list_changedmid-turn. - Pin model and effort per session. Each switch re-reads the full history uncached. Inference: route cheap work to subagents, not to mid-thread model swaps.
- Make compaction a re-hydration step. Reload instructions, plan, memory index and a few recent files from disk, with per-item token caps and a thrash guard.
- Use tiered context relief. Clear old tool results first, in batches large enough to pay for the cache break, and summarise second.
- Return only a final report from subagents. Have large artefacts written to files and referenced, and scan reports for injected instructions.
- Cap depth and concurrency, and budget for multi-agent. Expect roughly 4–15x tokens. Give each worker an objective, an output format and boundaries, and never let two workers own the same file.
- Keep state on disk for long tasks. Use a JSON feature list with only pass/fail editable, a progress log, an init script, and git commits as checkpoints. Begin each session with a fixed re-orientation routine.
- Make "done" machine-checkable. Use tests as the oracle, a stop hook that can refuse completion, and a separate reviewer agent or model.
- Separate sandbox from approval. The OS boundary (Seatbelt, bubblewrap, proxy allowlist) decides what is possible; policy decides when to ask. Fail closed if the sandbox cannot start.
- If you use an LLM approver, hide tool results and the agent's prose from it. Drop broad interpreter allow rules, add denial circuit-breakers, and assume a non-trivial miss rate (17% reported).
- Sandbox more than the shell. In Claude Code, file tools, hooks and MCP servers run outside the sandbox. Inference: your harness should cover these or constrain them separately.
- Protect self-modifying paths (
.git, agent config, hooks, rc files, transcripts) from the agent, regardless of allow rules. - Keep instruction files short (about 100–200 lines) as a map into docs, and enforce invariants with linters and hooks, not prose.
- Expose a typed event protocol and enforce limits in the harness. Thread, turn and item lifecycles with server-initiated approval requests let every UI share one core. Enforce
max_turnsand budget in code, with typed terminal states.
Sources (docs fetched 2026-11-10; they carry no publication date)
Anthropic
- [C1] How Claude Code works: https://code.claude.com/docs/en/how-claude-code-works
- [C2] How the agent loop works (Agent SDK): https://code.claude.com/docs/en/agent-sdk/agent-loop
- [C3] How Claude remembers your project: https://code.claude.com/docs/en/memory
- [C4] Explore the context window: https://code.claude.com/docs/en/context-window
- [C5] How Claude Code uses prompt caching: https://code.claude.com/docs/en/prompt-caching
- [C6] Subagents: https://code.claude.com/docs/en/sub-agents
- [C7] Agent teams: https://code.claude.com/docs/en/agent-teams
- [C8], [C16] Manage costs effectively: https://code.claude.com/docs/en/costs
- [C9] Model configuration: https://code.claude.com/docs/en/model-config
- [C10] Checkpointing: https://code.claude.com/docs/en/checkpointing
- [C11] MCP: https://code.claude.com/docs/en/mcp
- [C12] Skills: https://code.claude.com/docs/en/skills
- [C13] Hooks: https://code.claude.com/docs/en/hooks
- [C14] Permission modes: https://code.claude.com/docs/en/permission-modes
- [C15] Sandboxing: https://code.claude.com/docs/en/sandboxing
- [A1] How we built our multi-agent research system (2025-06-13): https://www.anthropic.com/engineering/multi-agent-research-system
- [A2] Effective harnesses for long-running agents (2025-11-26): https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
- [A3] Effective context engineering for AI agents (2025-09-29): https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- [A4] How we built Claude Code auto mode (2026-03-25): https://www.anthropic.com/engineering/claude-code-auto-mode
- [A5] Context editing: https://platform.claude.com/docs/en/build-with-claude/context-editing
- [A6] Compaction overview: https://platform.claude.com/docs/en/build-with-claude/compaction
- [A7] Memory tool: https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool
OpenAI
- [O1] AGENTS.md: https://learn.chatgpt.com/docs/agent-configuration/agents-md
- [O2] Sandboxing: https://learn.chatgpt.com/docs/sandboxing.md
- [O3] Auto-review: https://learn.chatgpt.com/docs/sandboxing/auto-review.md
- [O4] Agent approvals & security: https://learn.chatgpt.com/docs/agent-approvals-security.md
- [O5] Subagents: https://learn.chatgpt.com/docs/agent-configuration/subagents
- [O6] Skills: https://learn.chatgpt.com/docs/build-skills ; Config reference: https://learn.chatgpt.com/docs/config-file/config-reference.md
- [O7] Hooks: https://learn.chatgpt.com/docs/hooks ; Memories: https://learn.chatgpt.com/docs/customization/memories.md
- [O8] App Server: https://learn.chatgpt.com/docs/app-server.md
- [O9] CLI commands: https://learn.chatgpt.com/docs/developer-commands.md?surface=cli
- [O10] Long-running work: https://learn.chatgpt.com/docs/long-running-work.md
- [O11] MCP: https://learn.chatgpt.com/docs/extend/mcp.md
- [O12] Agents SDK, running agents: https://openai.github.io/openai-agents-python/running_agents/
- [O13] openai/codex
codex-rs/core/README.md: https://github.com/openai/codex/blob/main/codex-rs/core/README.md - [O14] Cloud environments: https://learn.chatgpt.com/docs/environments/cloud-environments.md
- [O15] Models: https://learn.chatgpt.com/docs/models.md
- [O-sec] Read indirectly (403 on direct fetch):
- Unrolling the Codex agent loop (about Jan 2026, date from memory): https://openai.com/index/unrolling-the-codex-agent-loop/
- Harness engineering (early 2026; first commit "late August 2025" plus five months): https://openai.com/index/harness-engineering/
- Unlocking the Codex harness / App Server (Feb 2026; InfoQ coverage dated 2026-02-17): https://openai.com/index/unlocking-the-codex-harness/
apply_patchgrammar, secondary: https://gist.github.com/monperrus/2a9f682f3fca18de5693f0975bf5b396
Not consulted for lack of budget: "Building effective agents", "Writing tools for agents", the Claude Code best-practices page, and Anthropic's sandboxing engineering post. The Codex best-practices URL returned 404.