Harness

Codex, taken apart

OpenAI's coding harness, seen the same two ways as Claude Code.

Checked against the official docs and the open-source repo on 2026-09-23, with Codex CLI 0.155.1.

This page looks at Codex CLI version 0.155.1, as of 2026-09-23. The outside view comes from codex --help, codex exec --help and codex features list. The inside view comes from a different source than the Claude Code page. That page relied on the model describing its own session. Codex writes every session to disk, including the full base instructions, so this page is based on 99 of my saved sessions (702 turns), read for their structure rather than their conversations. The logs record what was sent and called, but not the tool definitions themselves.

Claims link to the doc page that confirms them. Findings that come only from the logs are marked as observed. For a feature-by-feature comparison, see Claude Code vs Codex.

From outside: the flags

These are documented in the command reference.

PartFlags
Who drivescodex exec (run once without the interactive interface), codex review, queue (add a message to a running session)
Tools--search (web search), codex mcp, codex plugin, --enable / --disable for any of 142 feature flags
Context-C (working directory), --add-dir, -i (attach images), -c key=value to override any setting, -p for a named profile
Checks-s sandbox (read-only, workspace-write, danger-full-access), -a approval policy (on-request, never), --approve-for-me, --ignore-rules, --output-schema, codex sandbox
Memoryresume, fork, archive, --ephemeral (don't save the session); a memories feature that is off here
Delegationthe multi_agent feature, codex agents, --worktree, codex cloud
Interfacean interactive terminal by default; --json event stream, a desktop app, --remote / remote-control, app-server

Two things stand out from the outside. First, the model can be swapped: --oss with --local-provider runs Codex on a local model through LM Studio or Ollama, so the harness doesn't depend on the company that built it. Second, a lot of the harness sits behind feature flags: 142 of them, most marked "under development" and several "removed". Anyone can list them, so the harness shows its own work in progress.

--help lists only two approval policies. The docs add a granular form that sets approval separately for sandbox escapes, rules, MCP prompts and skills. They also say the old untrusted policy has been retired, and that leaving it in a config file can stop Codex from starting.

Codex has nothing like Claude Code's --bare or --safe-mode that removes a whole layer at once. It strips down piece by piece instead: --ignore-user-config, --ignore-rules, --ephemeral, -s read-only, and individual --disable flags.

From inside: the session logs

Where the instructions come from

Each session's log shows its context arriving in separate parts:

Base instructions (about 21,000 characters)
Stored once per session. Sections cover when to ask permission, autonomy, personality and writing style, working with the user, getting work done, skills, connectors and plugins. The first line names the model generation it was written for.
Developer messages
A separate message for each concern: the list of skills, the permission rules, the current mode (Default or Plan), and the agent's role in a team of agents. Claude Code puts most of this in its system prompt.
World state
A separate record holding the AGENTS.md text for the working directory. Project instructions have their own place in the log, apart from the conversation. The docs explain how that text is assembled. Codex reads a global file from ~/.codex, then every AGENTS.md from the project root down to the current directory. An AGENTS.override.md takes the place of its sibling, and the total stops at 32 KiB.
Turn context
A record written every turn with the working directory, date, timezone, model, reasoning effort, approval policy, sandbox policy and personality. The settings are re-sent every turn, not just set once at the start.

One tool that runs code

In my sessions, the model gets a tool called exec that takes JavaScript. The other tools are functions the script calls: await tools.exec_command({cmd: "…"}). So one model call can run a command, look at its output, and decide what to do next, all within one script. Tallied across my sessions, calls from inside exec were:

Called inside execCalls
exec_command (shell)3,650
apply_patch (file edits as diffs)706
web__run290
view_image190
write_stdin (type into a running process)168
update_plan62
image_gen__imagegen11

A few tools are still called directly instead of from a script: wait (313), request_user_input and list_agents. Those pause the model or hand control to someone else, so they don't fit inside a script.

Claude Code handles a large toolset the opposite way: it gives the model many separate tools and loads their definitions on demand. Codex gives the model one tool and lets it write the code that decides which others to call.

Observed, and not documented. The config reference mentions features.code_mode only as "under development and off by default". codex features list shows that flag off and a related one, code_mode_host, stable and on. The logs show exec in use on every turn.

Permissions: a sandbox the model can see

Codex runs every command inside an operating-system sandbox by default. Claude Code has one too, but it's opt-in. In workspace-write mode, the one used in all 702 turns, files can be read anywhere, written only inside the workspace, and there's no network. Approval is for leaving the sandbox, not for each command.

The model is told all of this. The permission message explains how a command is split at |, &&, ; and subshells, with each piece checked separately. It also says that redirects, variables and wildcards disqualify a command from matching a rule. To get out of the sandbox, the model sets sandbox_permissions: "require_escalated", writes a one-line justification for the user, and can suggest a prefix_rule for the user to save for future sessions. The instructions list banned suggestions: never a prefix like ["python3"] that would allow any script, never one for rm, never one for a heredoc.

Those saved rules are plain text in a small rules language, which the docs mark as experimental. A rule can include match and not_match example commands that act as tests. The three in my ~/.codex/rules/default.rules are all curl prefixes the model proposed and I approved. So in Codex, the model and the user write the permission rules together. Claude Code has permission rules too, but the model never proposes them.

Approval doesn't have to come from a person. Auto-review sends requests to leave the sandbox to a separate reviewer agent. It sees only those requests. Anything that stays inside the sandbox runs without review. Claude Code's auto mode works the other way round: its classifier checks every call.

Asking less often

The base instructions push hard toward autonomy. The model is told not to ask again for anything the user already authorized, and not to ask at all for reversible or read-only work. Before an action that does need approval, such as publishing a site, it should finish everything else first, so that the approval is the last step and the user approves a finished result. The instructions add that the user "gets very frustrated" by unnecessary questions.

Compaction leaves a record

When a session's context fills up, Codex writes a compacted record containing a replacement_history, the shorter history the conversation continues from, and starts a new window ID linked to the previous one. 14 of my 99 sessions were compacted at least once. The log keeps both the original history and its replacement, so you can see what was dropped.

The config reference lets you set the threshold (model_auto_compact_token_limit) and replace the prompt that does the summarizing (compact_prompt). Claude Code documents instead what it restores after compacting.

Delegation that can be taken back

One developer message tells the model it is /root, the main agent in a team, and can start sub-agents. A later message in the same session cancels that: don't start any unless the user or an AGENTS.md file asks. That lines up with my own "ask before subagents" rule, but it arrives as a harness-level mode switch, not through my instruction file. This comes from the logs. The subagent docs cover the built-in agents (default, worker, explorer) and custom ones defined in TOML files.

Codex and Claude Code side by side

The comparison is now its own page: Claude Code vs Codex.

One set of instructions for both

My global instructions exist twice, as ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md, with the same content. My repo convention (content in AGENTS.md, with CLAUDE.md just importing it) exists so that one instruction file works in both harnesses. My instructions have become something I maintain separately from either harness.

The harnesses are moving in the same direction. Since v2.1.277, Claude Code reads AGENTS.md directly when a project has no CLAUDE.md. That makes my import line a fallback rather than a requirement. The global files are still separate, though: neither harness reads the other's home directory.

Keeping this current

This repo's check.py compares the installed CLI, its feature list, and every doc page linked here against saved snapshots, and reports what has changed.