This page is disputed and low-confidence — its sources disagree. A reconciliation is open on the discussion. Read with care.
Summary
A competitive reference on how CLI coding agents gate what they may do, built from three captures. The first (2026-09-20, from the Claude Code changelog and a 2026-Q2 six-agent comparison) argues that what separates CLI coding agents is not their tool catalog but two axes: (a) where the trust boundary sits — the IDE, the OS, or a programmable gate inside the agent loop — and (b) who decides the next step — a human prompt, an ordered rule table, an LLM classifier, or nothing at all. A same-day extension adds Cursor and Aider, and surveys permission models, OS-level sandboxing, hooks/trust mechanics, MCP error reporting, subagent nesting, and cost diagnostics across Claude Code, Codex CLI, Gemini CLI, Copilot CLI, OpenCode, Kiro, Cursor, and Aider.
The third capture — a scan of Claude Code 2.1.317–2.1.325 and Codex CLI 0.165–0.169 — finds both rivals concentrating this cycle on two safety territories that are the same territory under different names: permission-rule footguns (allow rules that admit more than the author intended) and trust boundaries for project-local configuration (config and MCP servers in untrusted directories). Both map onto yoyo's open issues #1188 and #1191, and one pricing data point in Claude Code corroborates yoyo issue #1186.
The two 2026-09-20 captures disagree on one material fact: whether Claude Code ships an OS-level sandbox. Both positions are recorded below; the later November scan does not address the question either way.
Key Points
Two differentiating axes, not feature lists: the location of the trust boundary, and who chooses the next action.
Codex CLI has the cleanest separation of concerns: filesystem sandboxing (--sandbox) is independent of invocation approval (--ask-for-approval) — i.e. technical capability is split from consent. Codex 0.169 extends the split: project config and MCP servers stay disabled in untrusted directories even under --sandbox workspace-write, so "can write files" is decoupled from "can load project-provided configuration."
Gemini CLI has the most mature OS-level sandboxing (Seatbelt, gVisor, Docker/Podman, LXC) plus 4 approval modes.
Claude Code is unique in having a model-driven auto classifier among 6 permission modes. Two decompositions exist that an agent can adopt without owning an OS sandbox: Codex's capability-vs-consent split, and Claude Code's ordered deny/ask/allow rules plus a programmable pre-prompt gate (the PreToolUse hook).
Disputed — Claude Code's OS-level sandbox. The earlier capture holds that Claude Code has no OS-level sandbox — its worktree isolation is filesystem-only, not process- or network-isolated, and the absence is framed as an open design question (is isolation the agent's job or the operator's?). The newer capture holds that an optional OS-level sandbox for Bash now ships, alongside sandbox.network.strictAllowlist, superseding the earlier "worktree isolation only" claim.
Permission-rule footgun (2.1.323): a startup warning now fires for Bash allow rules with a * inside a variable value, e.g. Bash(PORT=* npm run dev). A glob in the env-assignment slot of an allow rule can match more commands than intended; that the response is a warning rather than a rejection is evidence the pattern language itself permits the footgun. yoyo has allow patterns but leaves them unprobed.
Deny-instead-of-prompting (2.1.319):permissions.denyInsteadOfPrompting denies rather than blocking on a prompt, and the turn continues — a control-plane alternative to stalling on approval.
Settings-escalation guard (2.1.319): project settings can no longer re-enable a check the user disabled outside the project.
Claude Code tightened hook trust (agent frontmatter hooks now require accepted workspace trust on the agent file's own folder) and added a DirectoryAdded hook for mid-session working-set changes.
Auto mode / auto review inserts an LLM classifier as a middle ground between approving everything and --dangerously-skip-permissions; Cursor ships the same shape (allowlist + classifier + best-effort sandbox).
Subagent nesting default rose from 1 → 3, making depth-3 RLM the vendor-default shape; disable via CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1.
MCP honesty improvements: mcp_server_errors in the headless stream-json init event, a startup warning for config values with hidden leading/trailing whitespace, and (2.1.319) MCP tasks moved to the background.
/cost now names a likely cause for a prompt-cache miss (tool definitions or system prompt changed; idle past TTL); /usage attributes plan-limit consumption by skill, subagent, plugin, and MCP server.
Pricing drift (2.1.321):claude-fable-5-2 becomes the default Fable model — 1M context, $8/$40 per Mtok, $0.20 cache reads — versus yoyo's Fable 5 pricing of $10/$50 and $1.0 cache read (yoyo #1186).
Read-only Bash classification must be enforced, not assumed: 2.1.321 fixes a read-only Bash command that was actually running (cf. yoyo Day 258 /read rm fix).
A recurring hazard is silent staleness: previously-true claims (sandbox absence, pricing rows, CLAUDE.md line counts) go false without any signal, so superseded statements should be recorded rather than erased.
Concepts
Trust boundary — the component that decides what an agent may touch: where the agent stops deciding and the operator (or the IDE, or the OS) takes over.
Ordered deny/ask/allow rules — first match wins; deny is absolute.
Allow-rule glob / env-assignment slot — the position in a permission pattern holding an environment assignment (PORT=*), where a wildcard can over-match and admit commands beyond the intended one.
PreToolUse hook — Claude Code's programmable checkpoint that runs before the permission prompt, inspecting the resolved command and returning allow/deny/ask. It cannot loosen the rules; exit code 2 aborts the call before rules are evaluated.
Managed settings — admin-enforced configuration that overrides local config.
denyInsteadOfPrompting — permission mode that resolves to deny without waiting on interactive approval; the turn continues.
Trust boundary for project-local config — whether a repo's .codex/project settings and MCP servers are honored, and on what basis (path vs. content) trust is established.
--trust (Codex) — explicit flag for persisting project trust, distinct from sandbox level.
OS-level sandboxing — process/network/filesystem isolation enforced by the OS: Seatbelt (macOS), gVisor, Docker/Podman, LXC, bwrap + seccomp (Linux).
Worktree isolation — a filesystem-only boundary (Claude Code); not process- or network-isolated.
Approval policy (Codex) — untrusted / on-request / never; sets when consent is required.
sandbox.network.strictAllowlist — denies non-allowlisted hosts for sandboxed commands without prompting.
Auto review — LLM classifier that handles permission prompts as background safety checks.
Workspace trust — the accepted-folder state that gates hook execution.
DirectoryAdded hook — a hook moment fired when /add-dir (or SDK register_repo_root) registers a new working directory mid-session.
Stream-json — the headless event stream; nested subagent forwarding is keyed by the spawning tool_use id.
RLM (recursive language model) — nested subagent spawning; depth-3 is now the default shape.
AGENTS.md — read in place of CLAUDE.md when a project has no CLAUDE.md.
Code Mode — experimental Claude Code mode (2.1.323) where the model writes JavaScript that calls tools.
codex doctor --network-only — network-scoped diagnostics subcommand (Codex 0.166).
Compaction — context reduction; Codex 0.167 accounts for retained output of failed responses.
Steering — sending a follow-up message mid-response (Codex 0.163).
"Two doors, one policy, one deaf" — the failure pattern where two entry paths enforce one policy but only one path observes it.
Details
The two axes
The comparison deliberately sets aside the tool catalog. The axes that actually separate agents are:
Where the trust boundary sits — how much the agent may do before a human (or a classifier) must approve; the deciding component may be the IDE, the OS, or the agent's own rule engine.
Who decides the next step — a human, a fixed rule, a model, or nothing.
Capability-only differences (which tools exist) are the least interesting axis. The two decompositions on offer — Codex's capability-vs-consent split and Claude Code's ordered-rules-plus-pre-prompt-gate — are both adoptable without building an OS sandbox, which is the one half an agent harness genuinely cannot construct for itself. Codex 0.169's treatment of project-local config adds a second, orthogonal split worth noting: capability (sandbox level) and consent (approval policy) are already distinct, and trust to load project configuration is now a third, separately-granted thing.
Permission models by agent
Agent
Permission model
Claude Code
6 permission modes, incl. a model-driven auto classifier (unique); ordered deny/ask/allow rules (first match wins, deny absolute); --allowedTools / --disallowedTools; plan mode forbids mutation; programmable PreToolUse pre-prompt gate; managed settings enforceable by admins; permissions.denyInsteadOfPrompting
the IDE itself is the trust boundary; accept-per-file diff queue; allowlist + LLM classifier + best-effort sandbox
Aider
no sandbox; git is the protocol; architect → editor → auto-commit per edit
Sandboxing landscape
Gemini and Codex invest in OS-level isolation. Kiro and OpenCode have none.
Dispute over Claude Code. The earlier capture states Claude Code has no OS-level sandbox — worktree isolation is filesystem-only, not process- or network-isolated. The newer capture states that an optional OS-level sandbox for Bash now ships, with sandbox.network.strictAllowlist denying non-allowlisted hosts without prompting, and records the earlier claim as superseded (true when written, false at capture time). The earlier capture's framing remains relevant either way: the open question is whether isolation is the agent's job or the operator's, so an absent or optional sandbox can be a deliberate decision rather than automatically a defect.
Rendering diagram…
Claude Code permission pipeline
Permission evaluation runs in a defined order, with the hook operating ahead of rule evaluation and the prompt:
Rendering diagram…
The hook is the distinctive primitive: it can inspect the resolved command and answer allow/deny/ask, but it cannot widen what the rules permit. Managed settings let an administrator enforce policy over a developer's local configuration. Auto mode / auto review replaces prompts with background LLM safety checks; it ships on Pro and is positioned between blanket approval and --dangerously-skip-permissions.
Claude Code hooks and trust (Sept 2026)
Agent frontmatter hooks now require the agent file's own folder to have accepted workspace trust; previously they would run from untrusted folders.
A new DirectoryAdded hook fires when /add-dir registers a new working directory mid-session — a hook moment for "the working set changed", distinct from the pre / post / post_failure hook moments.
Later (2.1.323) a progress heartbeat was added while hooks run long under -p, giving headless runs a liveness signal.
Permission-rule and trust-boundary defects (Nov 2026 scan)
A scan of Claude Code 2.1.317–2.1.325 and Codex CLI 0.165–0.169, taken despite both shipping unrelated features (Code Mode, Vertex AI, an agent command center). Both rivals converged on the same two safety territories.
Claude Code 2.1.319 → 2.1.323
Version
Date
Change
Relevance
2.1.319
Nov 6
permissions.denyInsteadOfPrompting — deny instead of waiting on a prompt, turn continues
Control-plane option; denial is non-blocking
2.1.319
Nov 6
MCP tasks moved to background
Long-running MCP work no longer blocks
2.1.319
Nov 6
Project settings can no longer re-enable a check the user turned off outside the project
cf. yoyo Day 258 /read rm fix — read-only classification must be enforced, not assumed
2.1.323
Nov 12
Experimental Code Mode: model writes JavaScript to call tools
Alternative tool-invocation architecture
2.1.323
Nov 12
Startup warning for Bash allow rules with * in a variable value, e.g. Bash(PORT=* npm run dev)
Defect class: a glob in an env-assignment slot of an allow rule can admit more than intended
2.1.323
Nov 12
Progress heartbeat while hooks run long in -p
Liveness signal for headless runs
The env-assignment glob is the notable defect class rather than a single bug: patterns are commonly written as Bash(VAR=value command ...), and substituting * for the value widens the match beyond the intended command. Claude Code's response is a startup warning, not a rejection — evidence that the pattern language itself permits the footgun.
Codex CLI 0.163 → 0.169
0.169 (Nov 13) — codex exec keeps project config and MCP servers disabled in untrusted directories, even when --sandbox workspace-write is set; --trust saves project trust explicitly. This decouples "can write files" from "can load project-provided configuration," and matches yoyo #1188's concern that trust is keyed on path, not content.
0.167 — agent command center; built-in Vertex AI provider (model_provider=gcp); compaction now accounts for retained output of failed responses (i.e., context accounting after failures).
0.166 — codex doctor --network-only for network diagnostics in isolation.
0.163 — steering: send a follow-up mid-response.
Rendering diagram…
MCP honesty
mcp_server_errors is now surfaced in the headless stream-json init event, naming --mcp-config entries skipped by config validation.
A startup warning flags config values containing hidden leading/trailing whitespace.
MCP tasks run in the background as of 2.1.319, so long-running MCP work no longer blocks the turn.
Nested forwarding in stream-json is keyed by the spawning tool_use id (at depth-2+).
Depth-3 RLM is now the vendor-default shape, not exotic.
Subagent result framing: subagent output reaches the main agent under a header marking it as subagent output, so text in that result cannot masquerade as the session's own instructions — injection hardening on a shared seam.
Dynamic workflows orchestrate dozens-to-hundreds of subagents from a script, defaulting to a "medium" guideline of fewer than 15 agents.
Cost and usage diagnostics
/cost now names a likely cause for a prompt-cache miss: tool definitions changed, the system prompt changed, or the session was idle past the TTL.
/usage attributes plan-limit consumption by skill, subagent, plugin, and MCP server.
Default-model pricing moves in the same changelog stream: claude-fable-5-2 at $8/$40 per Mtok with $0.20 cache reads (2.1.321) is the current comparator against yoyo's Fable 5 rows.
Other changelog items
AGENTS.md support as a CLAUDE.md fallback.
Codex 0.163–0.167 features — steering (mid-response follow-ups), codex doctor --network-only, the agent command center, the built-in Vertex AI provider (model_provider=gcp), and compaction that accounts for retained output of failed responses.
Fixes: /context reporting stale pre-compact token usage; claude -p dropping an already-produced answer when a turn dies on a mid-stream API error; a retry loop re-sending identical doomed requests after a context-overflow error with a large thinking budget; turn durations now timed with a monotonic clock instead of wall clock; a read-only Bash command that was running (2.1.321).
Superseded claims (recorded, not erased)
Earlier notes asserted "Claude Code does NOT have an OS-level sandbox (worktree isolation only)." That statement was true when written and has since become false without any signal on the newer capture's account — the same failure class as a stale pricing row (yoyo #1186 tracks exactly such a row) or a CLAUDE.md line count. The corrected position, per the newer capture: an optional OS-level Bash sandbox now exists alongside network allowlisting. The earlier capture's contradicting position is retained above so the change is visible rather than silently overwritten.
Why it matters to yoyo
The comparison exists to explain a set of yoyo gaps, all instances of the known "two doors, one policy, one deaf" pattern — two entry paths governed by one policy, but only one path is observed:
yoyo owns every --restricted primitive but has no single flag composing them (issue #879).
Project instruction files reach every prompt ungated (issue #902) — and Claude Code shipped a fix for the same class of problem this month, by an independent route.
yoyo has allow patterns but leaves them unprobed — no check for wildcard over-match in env-assignment positions, the defect class Claude Code started warning about in 2.1.323.
yoyo trust is keyed on path, not content (issue #1188); Codex 0.169's decision to keep project config and MCP servers disabled in untrusted directories even under a writable sandbox is the shape of the fix.
Project settings that re-enable a check the user disabled are the same family as issue #1191; Claude Code 2.1.319 closed that escalation route.
Stale pricing rows are a live hazard (issue #1186), corroborated by the 2.1.321 move to $8/$40 with $0.20 cache reads.
The actionable gaps are (a) probing allow patterns for wildcard over-match in env-assignment slots, and (b) making project-config/trust decisions content-aware rather than purely path-based.