Codex Harness: How OpenAI Built an Embeddable Agent OS in 135 Rust Crates

This article dissects OpenAI's Codex Harness, a 146K-line Rust workspace of 135 crates that powers ChatGPT, CLI, and IDE extensions as an embeddable agent platform, detailing its agent loop, context engineering, JSON-RPC protocol, multi-OS sandboxing, and multi-agent architecture with measurable benchmark gains on ARC-AGI-3.

Software Engineering 3.0 Era
Software Engineering 3.0 Era
Software Engineering 3.0 Era
Codex Harness: How OpenAI Built an Embeddable Agent OS in 135 Rust Crates

Core Concepts: Agent, Harness, and Platform

The article begins by clarifying three overloaded terms. An Agent is a program that autonomously completes tasks: it understands tasks, maintains cross-time context, fetches external information, calls tools, exposes progress, recovers from failures, requests human approval, and returns useful results. A Harness is the entire execution system surrounding the model — context management (nervous system), tools (limbs), safety guardrails (sandbox), and communication protocols (mouthpiece). A Platform means the system can be embedded into any product, not just served as a standalone assistant. Codex's pivot: from "assistant you bring work to" to "engine you bring into your workflow."

Analogy: Traditional coding assistants are like whole-car sales — you drive their car, use their seats, their navigation. Codex Harness is like engine-and-chassis sales — it gives you the hardest part (agent loop), but steering wheel, dashboard, seats (UI), navigation data (context), and traffic rules (approval policies) are yours to decide. You can mount it in a truck, ambulance, or tractor.

App, CLI, IDE Are Just Three Skins

Official docs state: "Most people know Codex through the App, CLI, or IDE Extension. Those experiences are important, but they are only a few of the ways the same underlying system can be used." The same codex-core drives ChatGPT App, VS Code/Cursor/Windsurf extensions, command-line TUI, non-interactive codex exec, and — via codex app-server and official SDK — third-party products' own agents.

Product implications:

UI fully owned by the application. A support team doesn't work in a chat window; they work in their support console, letting the agent see customer account history, product logs, internal docs, and draft replies. A security analyst works in their alert queue, letting the agent investigate affected services and request approval before opening a ticket.

Context and tools decided by the application. The app exposes its own systems, documents, data, operations — including its own MCP servers.

Execution boundaries set by the host app. Where the agent runs, which files it accesses, which operations need approval, how results flow back — all configurable.

Official example: Relay , a fictional freight operations app. User selects an anomalous package, clicks "Compare recovery", app feeds context to agent, agent uses app's own MCP tools to fetch latest ops data and propose solutions, while any consequential write operation (e.g., rebooking freight) requires human approval.

Benchmark: On ARC-AGI-3, keeping reasoning + context compression lifted GPT-5.6 Sol score from 13.3% to 38.3% while cutting output tokens 6×. Harness design is not icing — it's a measurable lever on model task performance.

Task Journey: Building Intuition

Running codex "fix this bug" in terminal:

Launch: CLI starts local process, spawns in-process app-server, creates a thread (conversation).

Start turn: Message wrapped into a turn — user message starts, agent message ends; basic unit of conversation.

Sampling loop: codex-core reads current context (world state, model instructions, tool catalog), builds request, streams call to OpenAI Responses API.

Tool call: Model says "need to see code" → triggers exec_command tool → executes ls / rg / cat in sandbox → output fed back to model.

Approval: Model decides to run git push → hits execution policy → approval popup → user allows.

Apply patch: Model emits apply_patch call → modifies files → diff shown to user.

End turn: Agent summarizes completion → turn ends → full conversation persisted to JSONL rollout log and mirrored into SQLite.

Throughout, the model's "brain" only thinks; who thinks, with what tools, what they can touch, who they must ask — all decided by the harness.

Source Code: 135-Crate Rust Workspace

Repository scale:

3,287 Rust source files

~1.46 million lines of Rust code

135 Cargo workspace members

705 TypeScript/JavaScript files

30 GitHub Actions workflows

~20 third-party patches

The codex-rs/ directory contains the core. Its structure is an architecture document. codex-core is explicitly marked "resist growth" — capped at ~330K lines; new features must go into behaviorally pluggable extension crates, not the core. This is a key engineering philosophy.

Heart Dissection: codex-core Agent Loop

5.1 Thread → Session → Turn

ThreadManager

: creates/restores/forks/closes threads; holds global shared AuthManager, ModelsManager, EnvironmentManager, MCP/plugin/skills services. CodexThread: external thread handle — submit ops, start_or_steer_turn, event stream, state watch. Session: actual running unit inside thread; runs a submission_loop — entry point of the entire agent state machine. submission_loop is essentially an infinite loop over a message channel: reads Op messages from queue, dispatches. Op types reveal all supported actions:

UserTurn (new user message)
TurnInput (turn input)
Interrupt (interrupt)
ExecApproval / PatchApproval (approval responses)
Compact (compress)
Review (review)
InterAgentCommunication (sub-agent communication)
Shutdown (shutdown)

5.2 Core Sampling Loop: run_turn

Each turn's core is run_turn, a precise production line:

Pre-compress: if context too long, compress before sampling.

Parse input: resolve required MCP services, plugins, skills.

Capture StepContext : snapshot per request — current model, tool routing, MCP bindings, world state. Key to "state isolation between requests."

Build sampling request: via ContextManager::for_prompt generate model-visible input.

Stream sampling: SSE/WebSocket stream Responses API events.

Parallel tool execution: tool calls enter FuturesOrdered parallel queue ( drain_in_flight), multiple tools run simultaneously.

Decide: based on results, choose follow-up, steer, auto-compact, or end.

5.3 Pluggable Tasks

Session workflow abstracted as SessionTask trait, four implementations: RegularTask: regular tasks ReviewTask: review tasks CompactTask: compression tasks UserShellCommandTask: user's !shell commands

"What process runs inside one conversation turn" is itself pluggable — the bedrock that turns Codex from "chat tool" into "workflow engine."

5.4 Tool Surface: What the Model Sees

Tools built per turn ( tools/spec_plan.rs), controlled by feature flags, grouped:

Execution: exec_command, write_stdin, apply_patch Environment: current_time, sleep, get_context_remaining, new_context_window, request_permissions, request_user_input Retrieval: view_image, web_search, tool_search (lazy-loaded), MCP resource tools

Multi-agent: spawn_agent, send_input, wait_agent, close_agent Extensions: image generation, memory, goals, plugin install suggestions

Tools have exposure levels: Direct (visible), Deferred (lazy-loaded), Hidden — preventing hundreds of tools from flooding context at once; part of context engineering.

Context Engineering: The Underrated Core Competency

If agent loop is the engine, context management is the transmission — decides how much the model sees each time, in what order, at what granularity.

6.1 Incremental, Bounded, Cacheable

ContextManager

: maintains model-visible transcript, linear append, normalized updates. ContextualUserFragment (~40 types): bounded injection — repo's AGENTS.md has six hard rules constraining injections to be bounded , ≤10K tokens . WorldState: engine renders by diff — only changed parts re-injected, not full resend.

Why so strict? Prompt caching. Responses API caches by prefix; more stable context, fewer changes → higher cache hit rate → lower cost, lower latency. This upgrades "context engineering" from trick to architectural principle.

6.2 Three Compression Paths

Local summarization ( compact.rs): dedicated SUMMARIZATION_PROMPT generates summary locally.

Remote compression ( /responses/compact v1/v2): calls server-side compression endpoint, with 64K token retention budget, retry budget, model fallback.

Token budget new window ( compact_token_budget.rs): when budget exhausted, directly open new context window.

Detail: InitialContextInjection mechanism — during mid-turn compression, canonical context inserted above "last real user message" because models expect "summary at end"; pre-turn compression does not inject. This fine modeling of model behavioral habits is harness value.

6.3 Data Speaks

ARC-AGI-3: 13.3% → 38.3%, output tokens ÷6. Message: in agent systems, harness quality equals model quality, and in long-task scenarios may matter more.

Platform Bridge: app-server & JSON-RPC Protocol

If codex-core is engine, codex app-server is standardized interface — lets any application programmatically control the engine. The watershed from "tool" to "platform."

7.1 Transport Layer: Five Connection Modes

stdio://

(JSONL) — Default, inter-process communication ws:// — Experimental WebSocket with health-check endpoint unix:// — Unix control socket

in-process — TUI/exec direct in-process channel

remote-control — Remote device control

Backpressure: bounded queue, returns JSON-RPC -32001 "Server overloaded; retry later." when full — prevents slow consumers from dragging down agent.

7.2 Protocol Design: MCP-Inspired JSON-RPC 2.0

Three top-level primitives:

Thread: one conversation, multiple turns

Turn: complete round-trip from user message to agent message

Item: I/O unit inside turn — userMessage, agentMessage, reasoning, commandExecution, fileChange, mcpToolCall

Methods organized by /, resources extremely broad: thread/ (start/resume/fork/compact/queue), turn/ (start/steer/interrupt), item/, fs/, process/, command/, model/, config/, plugin/, mcpServer/, skills/, hooks/, app/, environment/

7.3 Bidirectional Communication

Protocol not just client→server; two critical reverse channels:

Server notification stream (server→client): thread/started, turn/completed, item/agentMessage/delta, commandExecution/outputDelta, fileChange/patchUpdated … App can real-time stream-render agent's every move, and precisely opt out via optOutNotificationMethods.

Server-initiated requests (server→client): item/commandExecution/requestApproval (command exec approval), item/fileChange/requestApproval (file change approval), item/tool/requestUserInput (ask user), mcpServer/elicitation/request (MCP auth request)…

Second channel crucial — makes "human approval" a first-class protocol citizen, not an app-hacked side channel. Any app integrating Codex gets approval flow out of the box.

7.4 Type Safety & Lifecycle

Protocol types macro-generate TypeScript bindings and JSON Schema ( codex app-server generate-ts / generate-json-schema), guaranteeing multi-language SDKs never drift from protocol.

Lifecycle: 30 min inactivity after last subscriber unsubscribes → thread unloaded, triggers SessionEnd hooks — idle resources reclaimed promptly.

Experimental APIs gated by #[experimental] macro, ensuring controlled protocol evolution.

Security Boundaries: One Policy, Three Native Sandboxes

Agent must execute commands, read/write files, access network. But a "can-work" agent is also a "can-break-things" agent. Codex sandbox uses unified abstraction + native implementation .

8.1 Unified Policy Model

User faces one concept: SandboxMode (read-only / workspace-write / danger-full-access), rendered as unified PermissionProfile (filesystem policy + network policy). Profile translated by codex-sandboxing into three completely different OS-native mechanisms:

macOS: Filesystem — Seatbelt ( sandbox-exec, deny-default closed policy + protected metadata name exclusion). Network — Seatbelt network rules, proxy mode only allows loopback→proxy port.

Linux: Filesystem — bubblewrap namespaces + bind mounts ( --ro-bind / --tmpfs layered root), inner seccomp BPF network filter + no_new_privs. Network — --unshare-net + seccomp intercept connect/accept/socket.

Windows: Filesystem — restricted token ( CreateRestrictedToken + capability SID + deny-ACE ACL), optional elevated dedicated account. Network — WFP persistent filters (block ICMP/DNS/SMB).

Key design: Policy semantics (allow/deny/ask) written once, enforcement by each platform's native mechanism. "Define once, consistent everywhere" engineered.

8.2 Defense in Depth

Sandbox is only layer one. Clear defense in depth:

Process hardening ( codex-process-hardening): main process sets PT_DENY_ATTACH / PR_SET_DUMPABLE=0, RLIMIT_CORE=0, strips LD_* / DYLD_* env vars — anti-debug, anti-dump, anti-inject.

Privilege escalation control ( shell-escalation): patched zsh EXEC_WRAPPER protocol; sandbox execve intercepted and relayed to Codex for verdict: allow direct / allow escalate (sudo) / deny.

Execution policy engine ( codex-execpolicy): Starlark *.rules files ( prefix_rule, network_rule, host_executable), verdict Allow / Prompt / Forbidden, strictest wins; dangerous commands (e.g., rm -rf) have dedicated heuristics forcing approval.

Managed network proxy ( network-proxy): HTTP/SOCKS5 + MITM + cert management, network policy enforced at proxy layer, also does credential proxying and auditing.

This stack answers: when agent becomes powerful, why trust it? Answer: don't trust it, trust the boundaries.

Multi-Agent & Extension Ecosystem

9.1 Multi-Agent: Teaching Agents to Collaborate

Built-in multi-agent (v1 and v2). Core is AgentControl control plane:

Each root thread/session tree shares one AgentControl, holding AgentRegistry (limits sub-agent count, unique nicknames), V2Residency (agent path ↔ thread mapping), AgentExecutionLimiter (concurrency cap).

Sub-agents inherit environment + execution policy by role (default / explorer / worker) with bounded config overrides.

Communication via each sub-thread's mailbox ( input_queue.rs), MailboxDeliveryPhase::CurrentTurn/NextTurn decides whether late messages enter current or next turn.

Sub-agent completion injects SubagentNotification to parent thread.

Guardian approval: on-request approval can delegate to Guardian sub-session for auto-review, fail-closed (review fails → deny).

Effectively implements "management hierarchy" inside harness: main agent dispatches explorer to scout, worker to execute, then aggregates decisions.

9.2 MCP: Bidirectional Tool Ecosystem

MCP (Model Context Protocol) is de-facto agent tool standard; Codex implements both directions fully:

As MCP client ( codex-mcp): supports stdio / streamable-HTTP+SSE transport, OAuth/PKCE auth, elicitation (request user auth/forms), tool sanitization/deduplication, mcp__ namespace isolation.

As MCP server ( codex mcp-server): exposes Codex's own tools ( codex, codex-reply) as MCP service for other agents or apps to call.

Combined with connectors (ChatGPT hosted app connectors: Google Drive, Gmail, etc.), Codex tool surface covers "own systems + third-party services + callable by other agents" three shapes.

9.3 Plugins, Hooks, Skills

Plugins + Marketplace ( codex-core-plugins): plugins declare MCP servers, apps ( .app.json), hooks, skills; support marketplace install/upgrade/remote install — capability distribution "app store" mode.

Hooks ( codex-hooks): lifecycle hook engine — PreToolUse, PostToolUse, Pre/PostCompact, SessionStart/End, UserPromptSubmit, Stop … App injects own logic at any critical agent action (audit, rewrite, block).

Skills ( codex-skills): SKILL.md format team knowledge injection, supports @skill mention, explicit/implicit invocation — teaches agent "your team's unique way of working."

Remote Execution Environment: Local UI, Remote Brain, Cross-OS Execution

Often overlooked but forward-looking: codex exec-server — execution environment server.

Role: on (usually remote ) machine, hosts process control and filesystem ops. app-server can connect multiple exec-servers (local default + environments.toml configured remotes), and app-server and exec-server can run on different OSes — e.g., Linux app-server drives a Windows machine to execute.

Remote wire format: protobuf relay frames inside Noise encrypted channel ( RelayMessageFrame, contains stream id, seq/ack, traceparent), each virtual session a stream id, demuxed each runs a ConnectionProcessor.

Implication: "Security context" enforced on executor side — code runs where security boundary lands, not on user's local machine. Decisive for enterprise deployment (SSH scenarios, cloud workloads).

Engineering Lessons: What 135 Crates Teach

1. Single Core, Multiple Frontends

codex-core

single business logic; CLI/TUI/exec/app-server/IDE all reuse it. Yields behavioral consistency : regardless of entry point, agent decision logic, context management, approval semantics identical. Product layer swaps "skin" not "brain."

2. Protocol-First Platformization

codex-app-server-protocol

independent crate; types macro-generate TS/JSON-Schema; SDK thin wrapper over protocol. Protocol as contract — turns "third-party embeds Codex" from "reverse-engineer internal API" to "integrate public contract."

3. Execution & Judgment Separation

PermissionProfile

(semantics) → three OS backends (implementation) → Starlark execpolicy (policy judgment), three layers fully decoupled. Policy experts write rules, OS experts write backends, no blocking each other.

4. Core Resists Bloat

codex-core

at 330K lines "refuses growth"; new capabilities all go into ext/ 13 built-in extension crates. Core stays stable, periphery grows wildly — standard mature platform shape.

5. Build System Rigor

Bazel 8 + bzlmod + hermetic toolchain (bundles LLVM, Windows SDK, even Wine for running Windows binaries in Linux CI) + RBE remote build. ~20 third-party patches (LLVM, v8, ring, zstd…) — for reproducible builds, spare no expense.

Conclusion: Harness Philosophy

Codex's engineering essence: package "an agent that can autonomously work" into a embeddable, observable, programmable, sandboxable, extensible platform runtime (similar to AgentOS shared yesterday), letting any application plug agents into its existing UI, data, tools, approval flows via codex app-server / SDK.

Division of labor in one sentence: Application owns "product context" — UI, business rules, data, tools, approval flows; Codex owns "running the agent loop well" — think, execute, compress, collaborate, persist, and always operate within boundaries.

Why officials stress "reusable part is agent loop": models become obsolete, harness doesn't — it's the replaceable, observable, programmable stable layer between application and model.

For developers, a new choice: when adding AI to product, no longer choose between "build an agent runtime" and "use someone else's chat window." Third path — embed the ready-made harness into your own product , then define with your UI, your data, your rules what this agent looks like in your business.

After all, the best agent isn't "a tool that looks like ChatGPT" — it's "a colleague that lives inside your workflow."

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

RustMulti-Agent SystemsAgent ArchitecturesandboxingJSON-RPCContext EngineeringAgent LoopCodex Harness
Software Engineering 3.0 Era
Written by

Software Engineering 3.0 Era

With large models (LLMs) reshaping countless industries, software engineering is leading the charge into the Software Engineering 3.0 era—model-driven development and operations. This account focuses on the new paradigms, theories, and methods of SE 3.0, and showcases its tools and practices.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.