SPB Git

Repository Public

01-claude-code-and-codex.md 22.0 KB

# 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 to learn.chatgpt.com/docs/*.
  • Not verified today:
    • Codex rollout path (~/.codex/sessions/.../rollout-*.jsonl is 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_patch grammar (secondary sources only).
    • Seccomp on Linux for Codex (not mentioned in the pages I read).
  • 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), AssistantMessage per content block, UserMessage for tool results, optional StreamEvent, then ResultMessage.
  • 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_turns and max_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_TOKENS budgets 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, completed lifecycle.
  • 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_turns raises MaxTurnsExceeded. parallel_tool_calls and tool_execution.max_function_tool_concurrency control 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.md or .claude/CLAUDE.md, and CLAUDE.local.md.
    • Files from the filesystem root down to the cwd are concatenated at launch.
    • Subdirectory files load on demand when Claude touches a file there.
    • @imports nest up to four hops; the target is under 200 lines per file.
    • AGENTS.md is read when no CLAUDE.md exists.
  • Auto memory: Claude writes MEMORY.md plus 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_least to amortise the cache break.
    • clear_thinking_20251015.
    • Server-side compaction: on-demand (compact-2026-09-04) or threshold.
    • Client-side memory_20250818 tool, 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.md or AGENTS.md, then project root down to cwd, one file per directory, concatenated. Capped by project_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_changed mid-session is a known cache-buster.
  • Auto-compaction calls /responses/compact when model_auto_compact_token_limit is exceeded. It returns a type=compaction item with opaque encrypted_content. compact_prompt overrides 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 SendMessage resumes 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/ with name, description, developer_instructions, and optional model and model_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. opusplan uses 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 the passes field editable), claude-progress.txt and init.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.

Codex [O9, O10, O-sec]

  • /plan mode with its own plan_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.
  • /review or codex review runs a reviewer, optionally on a separate review_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.md with frontmatter. Descriptions are truncated at 1,536 characters in the listing; the body loads on invocation; supporting files load on reference. Supports context: fork and dynamic !command injection.
  • Hooks: 33 events. Handler types are command, http, mcp_tool, prompt and agent. PreToolUse can return allow, deny, ask or defer, plus updatedInput.

Codex [O4, O6, O7, O11, O-sec]

  • Editing uses apply_patch, a freeform custom tool constrained by a Lark grammar (*** Begin Patch envelope 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, indexed and disabled.
  • MCP: stdio and streamable HTTP, bearer token from an env var or codex mcp login. Per-tool approval_mode, enabled_tools and disabled_tools. Timeouts are 10 s startup and 60 s per tool.
  • Skills use the same SKILL.md standard, in .agents/skills, with an optional agents/openai.yaml.
  • Hooks: 14 events, including PreModelRequest and PostModelRequest. 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-path rm are 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(*) and Bash(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 ~/.ssh are allowed by default.
  • dangerouslyDisableSandbox is 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; untrusted is retired).
  • In workspace-write, .git, .agents, .codex and .aws stay read-only, and network is off by default. An optional network_proxy adds a domain allowlist.
  • Enforcement: /usr/bin/sandbox-exec on 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/. --resume keeps the same ID; --fork-session or /branch creates a new one.
  • File snapshots are retained about 30 days. The SDK sessionStore adapter 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, and thread/fork with ephemeral: true are supported. thread/rollback has been replaced by thread/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: haiku for 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

  1. 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.
  2. Freeze the tool list per conversation. Defer large or MCP tool schemas behind a search tool, and do not honour list_changed mid-turn.
  3. 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.
  4. 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.
  5. Use tiered context relief. Clear old tool results first, in batches large enough to pay for the cache break, and summarise second.
  6. Return only a final report from subagents. Have large artefacts written to files and referenced, and scan reports for injected instructions.
  7. 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.
  8. 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.
  9. Make "done" machine-checkable. Use tests as the oracle, a stop hook that can refuse completion, and a separate reviewer agent or model.
  10. 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.
  11. 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).
  12. 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.
  13. Protect self-modifying paths (.git, agent config, hooks, rc files, transcripts) from the agent, regardless of allow rules.
  14. Keep instruction files short (about 100–200 lines) as a map into docs, and enforce invariants with linters and hooks, not prose.
  15. 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_turns and budget in code, with typed terminal states.

# Sources (docs fetched 2026-11-10; they carry no publication date)

Anthropic

OpenAI

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.

Files main
Menu

Theme