This page documents the fundamental architectural patterns that span the entire Codex codebase. These concepts provide the foundation for how user interfaces communicate with the agent core, how configuration is resolved and enforced, how experimental features are gated, and how security boundaries are maintained.
For specific UI implementations that use these patterns, see User Interfaces. For the internal agent implementation, see Core Agent System.
Codex uses a queue-based asynchronous communication pattern to decouple user input from agent execution. All frontends (TUI, App Server, Exec mode) interact with the core agent through this protocol.
The Codex struct exposes two async channels:
Sources: codex-rs/core/src/codex.rs257-265 codex-rs/protocol/src/protocol.rs1-5
The Submission struct wraps an Op with a unique ID for correlation. Key operation variants include:
| Op Variant | Purpose | When Used |
|---|---|---|
UserInput | Submit user message (legacy) | CLI/TUI sessions without full turn context |
UserTurn | Submit user message with turn context | App Server, provides cwd, approval_policy, sandbox_policy, model per turn |
Interrupt | Cancel active task | User presses Ctrl+C or stops turn |
ExecApproval | Respond to approval request | User approves/denies command execution |
PatchApproval | Respond to patch request | User approves/denies file modifications |
ElicitationResponse | Respond to model elicitation | User answers model's follow-up questions |
RequestUserInputResponse | Respond to model input request | User provides requested information |
OverrideTurnContext | Update persistent session defaults | Change model, sandbox, or approval policy |
UpdateSessionSettings | Modify session-level settings | Change collaboration mode, personality, or reasoning effort |
DynamicToolCall | Invoke dynamic tool | External clients invoke custom tools |
Shutdown | Terminate session | Clean shutdown request |
Sources: codex-rs/protocol/src/protocol.rs73-339 codex-rs/core/src/codex.rs470-485
The agent emits Event instances containing an EventMsg variant. Events flow unidirectionally from core to frontend:
Event Categories and Flow
Sources: codex-rs/protocol/src/protocol.rs73-796 codex-rs/core/src/codex.rs257-280
Sources: codex-rs/core/src/codex.rs449-467 codex-rs/core/src/codex.rs470-494
The RolloutRecorder persists events to JSONL files for session replay. Events are filtered by EventPersistenceMode:
UserMessage, AgentMessage, TurnComplete, TokenCount, etc.)ExecCommandEnd, PatchApplyEnd, McpToolCallEnd)Rollout files are stored in ~/.codex/threads/{thread_id}/rollout.jsonl and enable session resumption and forking.
Sources: codex-rs/core/src/rollout/mod.rs39-212 codex-rs/core/src/rollout/policy.rs1-171
Configuration is resolved through a layered merge with requirements enforcement. This design supports multi-tenant deployments (via MDM/requirements) while allowing per-project customization.
Higher layers override lower layers. Requirements act as constraints that prevent overrides in certain directions (e.g., can't relax sandbox mode beyond what requirements allow).
Sources: codex-rs/core/src/config/mod.rs410-506 docs/config.md1-36
The async builder pattern loads and merges configuration layers:
Sources: codex-rs/core/src/config/mod.rs410-506
| Type | Purpose | File |
|---|---|---|
Config | Final resolved configuration with all overrides applied | codex-rs/core/src/config/mod.rs160-408 |
ConfigToml | Raw TOML structure before resolution | codex-rs/config/src/lib.rs1-600 |
ConfigProfile | Named preset (e.g., "fast", "slow", "custom") with common settings | codex-rs/core/src/config/profile.rs16-54 |
ConfigLayerStack | Provenance tracking for merged layers | codex-rs/core/src/config_loader/mod.rs1-500 |
ConfigBuilder | Async builder for loading config | codex-rs/core/src/config/mod.rs410-506 |
Permissions | Security policies (approval, sandbox, network) | codex-rs/core/src/config/mod.rs132-158 |
Sources: codex-rs/core/src/config/mod.rs1-1200 codex-rs/core/src/config/profile.rs1-68
The Constrained<T> wrapper enforces requirements constraints:
Example: approval_policy: Constrained<AskForApproval> can prevent users from setting Never if requirements mandate OnRequest. Attempting to violate a constraint returns ConstraintError.
Sources: codex-rs/config/src/lib.rs1-400 codex-rs/protocol/src/protocol.rs343-382
The JSON Schema is generated at build time and includes all valid keys, enums, and nested structures. This enables IDE autocomplete and validation.
Sources: codex-rs/core/config.schema.json1-1500 docs/config.md28-30
Codex uses a centralized feature flag system to gate experimental, under-development, and deprecated behavior. This avoids scattered boolean checks throughout the codebase.
Each Feature has a Stage that determines its visibility and default state:
| Stage | Default Enabled | Visible in /experimental | Purpose |
|---|---|---|---|
UnderDevelopment | false | No | Features not ready for external use |
Experimental | false | Yes | User-testable features with menu descriptions |
Stable | Typically true | No | Production-ready features |
Deprecated | Varies | No | Features being phased out |
Removed | false | No | Kept for backward compatibility only |
Sources: codex-rs/core/src/features.rs27-44 codex-rs/core/src/features.rs411-635
All features are defined in a single static array FEATURES:
Sources: codex-rs/core/src/features.rs402-635
Key features include:
| Feature | Stage | Purpose |
|---|---|---|
ShellTool | Stable | Default shell tool execution |
GhostCommit | Stable | Ghost commit creation for undo |
UnifiedExec | Experimental | PTY-backed unified exec tool |
RequestRule | Experimental | Model can request exec rules |
Collab | Experimental | Spawn sub-agent threads |
Apps | Experimental | ChatGPT App (Connector) integration |
CollaborationModes | Experimental | Plan/Default mode switching |
Steer | Experimental | Enter submits immediately (vs Tab to queue) |
WebSearchRequest | Experimental | Live web search tool |
WebSearchCached | Experimental | Cached web search tool |
UseLinuxSandboxBwrap | Experimental | Bubblewrap sandbox on Linux |
WindowsSandbox | Experimental | Windows restricted token sandbox |
Sqlite | Experimental | Persist rollouts to local SQLite |
MemoryTool | UnderDevelopment | Startup memory extraction |
JsRepl | UnderDevelopment | JavaScript REPL tools |
Sources: codex-rs/core/src/features.rs72-146
The Features struct holds the effective set of enabled features:
Call sites check features via:
Sources: codex-rs/core/src/features.rs173-342
The system maintains backward compatibility for renamed features:
| Legacy Key | Current Feature | Migration Path |
|---|---|---|
connectors | Feature::Apps | Use features.apps |
include_apply_patch_tool | Feature::ApplyPatchFreeform | Use features.apply_patch_freeform |
experimental_use_unified_exec_tool | Feature::UnifiedExec | Use features.unified_exec |
tools.web_search | Feature::WebSearchRequest | Use web_search = "live" (top-level) |
Sources: codex-rs/core/src/features/legacy.rs1-121
Codex enforces security boundaries through two primary policy types: approval policies (when to prompt the user) and sandbox policies (what filesystem/network access is allowed).
The AskForApproval enum determines when the user must approve actions:
Enum Variants:
| Variant | Behavior | Use Case |
|---|---|---|
UnlessTrusted | Prompt unless command is known-safe read-only | Maximum safety (default for many orgs) |
OnRequest | Model decides when to request approval via require_approval parameter | Default - balanced approach |
Never | Always auto-approve, no prompts | Headless automation (codex exec) |
OnFailure | Deprecated - auto-approve with sandbox retry | Legacy, prefer OnRequest or Never |
Sources: codex-rs/protocol/src/protocol.rs343-382 codex-rs/core/src/tools/spec.rs1-1000
The SandboxPolicy enum controls filesystem and network access:
Sandbox Variants:
| Variant | Read Access | Write Access | Network | Platform Support |
|---|---|---|---|---|
ReadOnly | Configurable (full or restricted roots) | None | Blocked | macOS (Seatbelt), Linux (Landlock + seccomp), Windows (restricted token) |
WorkspaceWrite | Configurable (typically full) | cwd, /tmp, $TMPDIR (excludes .git, .codex) | Optional | All platforms |
ExternalSandbox | Full (assumes external sandbox) | Full | Optional | Used when running inside Docker/VM |
DangerFullAccess | Full | Full | Full | Unsafe, requires explicit user opt-in |
Sources: codex-rs/protocol/src/protocol.rs408-796 codex-rs/core/src/tools/sandboxing.rs1-500
The WritableRoot struct allows selective write access while protecting sensitive subdirectories:
Why? Prevents the agent from modifying .git/hooks (privilege escalation), .codex/config.toml (security bypass), or .agents/skills (code injection).
Sources: codex-rs/protocol/src/protocol.rs571-796
Both policies use the Constrained<T> wrapper to enforce requirements:
Example enforcement:
approval_policy = "on-request" (minimum)approval_policy = "never"ConstraintError, user config is rejectedSources: codex-rs/core/src/config/mod.rs127-143
| Platform | Implementation | Files |
|---|---|---|
| macOS | Seatbelt profiles (sandbox-exec) | codex-rs/core/src/seatbelt_permissions.rs |
| Linux | Landlock + seccomp (or bubblewrap if use_linux_sandbox_bwrap enabled) | codex-rs/core/src/tools/sandboxing.rs |
| Windows | Restricted token + ACL checks | codex-rs/core/src/windows_sandbox.rs |
Sources: codex-rs/core/src/tools/sandboxing.rs1-500 codex-rs/core/src/seatbelt_permissions.rs1-300 codex-rs/core/src/windows_sandbox.rs1-400
The ToolOrchestrator centralizes approval and sandbox logic:
Tool Execution Pipeline
Sources: codex-rs/core/src/tools/sandboxing.rs1-500 codex-rs/core/src/tools/registry.rs1-300 codex-rs/core/src/exec_policy.rs1-300
The four core concepts—Submission/Event Protocol, Configuration System, Feature Management, and Security Policies—provide the architectural foundation for Codex:
These patterns are used consistently across all frontends (TUI, App Server, Exec) and enable the same core business logic to serve diverse use cases safely.
Sources: codex-rs/core/src/codex.rs1-1500 codex-rs/protocol/src/protocol.rs1-1500 codex-rs/core/src/features.rs1-742 codex-rs/core/src/config/mod.rs1-1200
Refresh this wiki