Overview
这篇文章想系统回答一个问题:Codex 到底是怎么工作的。
很多人第一次接触 Codex 时,都会有一种很强的”违和感”:
- 它不只是聊天,而是真的会读代码、改文件、跑命令;
- 它不是每次都等命令跑完才说话,而是会一边看输出一边继续推进任务;
- 它看上去像一个模型,但很多关键行为其实并不发生在模型内部;
- 它既能在本地执行,也能在云端环境里跑,而且这两种模式的安全边界还不完全一样。
如果只把 Codex 看成”一个会写代码的 LLM”,很多现象会解释不清。更准确的理解方式是:
Codex 是一个由模型负责决策、由 harness 负责编排、由 runtime 负责执行、并由 sandbox 与 approvals 负责边界控制的 agent system。
这篇文章会把这个系统拆开来看。重点不是介绍某个 API 参数,而是建立一个稳定的心智模型:当用户发出一个请求后,究竟发生了什么,哪些职责属于模型,哪些职责属于 harness,哪些职责属于 runtime,沙盒和审批又分别控制什么。
在进入细节之前,先给出一幅 Codex 的模块全景图,帮助你在阅读过程中始终有一个整体视角:
|
|
下文会逐一展开这些模块之间的协作关系。
Why Codex Feels Different
Codex 和普通对话模型最大的差别,不在于“更会写代码”,而在于它被放进了一个可执行的闭环里。
普通聊天模型的典型行为是:
- 读取上下文;
- 生成一段回复;
- 结束这一轮。
而 Codex 的典型行为更像:
- 读取上下文和工具定义;
- 决定下一步动作;
- 调用工具;
- 观察工具结果;
- 根据新观察继续推理;
- 重复这个循环,直到任务结束。
因此,Codex 的关键特征不是“回答得更聪明”,而是它能把用户目标拆成一系列可执行动作,并在执行结果的反馈下持续调整后续行为。
这也是为什么理解 Codex 时,只看模型往往不够。很多决定产品体验的关键能力,例如:
- 能不能真正跑 shell 命令;
- 命令失败后能不能恢复;
- 写文件时有没有边界;
- 什么时候需要用户审批;
- 长命令的输出怎么流式展示;
- 多个 agent 怎样协同;
这些都不只属于模型,而属于模型外面的整套执行系统。
Message Roles and Instruction Hierarchy
先看最上层的上下文结构。
过去很多人熟悉的 chat 格式里,角色通常只有:
systemuserassistant
但在现在的 Codex / OpenAI agent 语境里,developer 同样是核心角色。它往往承载的是宿主程序写给模型的工作规则,而不是普通对话内容。
可以粗略理解为:
system:平台级规则;developer:应用级规则,也就是 Codex 这个产品要求 agent 如何工作;user:当前任务;assistant:模型之前已经给出的自然语言回复或工具调用结果。
在 Codex 里,developer 往往会规定这类事情:
- 你是一个 coding agent;
- 先读代码再改代码;
- 优先使用哪些工具;
- 输出分成
commentary和final; - 不要做哪些危险 git 操作;
- 什么时候要更新用户进度;
- 什么情况下必须遵守沙盒和审批策略。
所以在架构上,developer 更像一层应用运行规则,而不是普通聊天历史。Codex 之所以表现得像“有工作流程”的 agent,很大程度上就是因为它始终处在一套强约束的指令体系之下。
Tools: Spec vs Implementation
再往下看工具。
模型并不会直接看到工具的源码实现。它首先看到的是一份 tool spec,也就是结构化接口描述。这个 spec 通常会告诉模型:
- 工具名是什么;
- 这个工具做什么;
- 参数有哪些;
- 参数的类型和约束是什么;
- 结果大概会返回什么结构。
在 Codex 的实际源码中,模型面对的工具类型(ToolPayload 枚举)主要有以下几种:
| 类型 | 用途 |
|---|---|
LocalShell |
执行 shell 命令(如 npm test、git status) |
Function |
标准函数调用(如 apply_patch 应用文件补丁) |
Mcp |
调用 MCP server 提供的外部工具 |
ToolSearch |
搜索当前可用的工具列表 |
Custom |
客户端动态注册的自定义工具 |
以 LocalShell 为例,模型看到的 spec 大致包含:
name = local_shell- 描述:在 PTY 中执行一条 shell 命令
- 参数可能包括:要执行的命令文本、工作目录、超时设置等
以 Function 类型的 apply_patch 为例:
name = apply_patch- 描述:应用一个文件补丁(diff)
- 参数:补丁内容(标准 unified diff 格式)
模型真正会做的,是基于这些 spec 决定:
- 现在需不需要调用工具;
- 如果需要,应该调用哪个工具;
- 参数该怎么填。
所以从抽象上说:
tool spec是暴露给模型看的接口定义;tool implementation是宿主程序里真正干活的代码。
在 Codex 源码中,这个对应关系由 ToolRegistry 管理:它维护一张 name → ToolHandler 的映射表。模型发出 tool call 后,ToolRouter 根据 tool name 从 registry 中查到对应的 handler,再由 handler 实际执行。这和传统软件里的”API 文档”和”后端实现”关系非常像——模型看到的不是实现细节,而是能力边界。
除了内建工具外,Codex 还支持通过 MCP(Model Context Protocol) 集成外部工具。McpHandler 和 McpResourceHandler 负责与外部 MCP server 通信,使 Codex 能够调用第三方提供的工具能力(例如数据库查询、API 调用等),从而扩展工具生态。
Harness: The Control Plane
接下来进入最容易混淆、但也最重要的一层:harness。
如果用一句话定义:
Harness是包在模型外面、把用户任务组织成持续 agent loop 的控制系统。
它关注的不是”某条命令怎么 spawn”,而是更上层的问题:
- 这一轮该不该调用工具;
- 工具调用前要不要审批;
- 失败后要不要重试;
- 当前任务是否已经完成;
- 输出该展示给用户什么;
- 多 agent 之间如何分工;
- 哪些规则需要始终保留在上下文里。
因此,harness 更像 control plane。它在意的是任务过程的组织、约束与调度。
在 Codex 语境里,harness 一般会包含这些职责:
-
Agent loop orchestration 把”读上下文 -> 选动作 -> 调工具 -> 看结果 -> 再决策”组织成一个可持续运行的闭环。源码中这体现在
codex.rs的主循环:Session持有全局状态,每次用户输入触发一个新的TurnContext,turn 内部不断循环直到任务完成或用户中断。 -
Instruction layering 把
system、developer、user等不同来源的指令组织成上下文,并维护优先级。ContextManager负责管理对话历史(Vec<ResponseItem>),在发送给模型前做标准化处理(剥离无效项、过滤模态)。 -
Tool routing 接住模型发出的 tool call,通过
ToolRouter把它路由给ToolRegistry中对应的ToolHandler。路由过程不仅匹配工具名,还要区分内建工具、MCP 工具和动态注册工具。 -
Tool orchestration (审批 → 沙盒 → 执行 → 重试)
ToolOrchestrator是工具执行的核心管线。每个 tool call 都要经过:- 检查
ExecApprovalRequirement(是否需要审批 / 是否禁止) - 选择沙盒策略(首次尝试用哪个沙盒)
- 在沙盒中执行
- 如果沙盒拒绝,决定是否升级沙盒(如降级到
SandboxType::None)并重试
- 检查
-
State and session management 维护会话状态、长进程 session、子 agent 状态、工具调用历史等。
Session是最顶层的生命周期容器,持有ContextManager、配置、事件通道、MCP 连接、钩子运行时等。 -
User interaction 决定什么时候发中间进度、什么时候等待审批、什么时候给最终结果。
-
Hook dispatch 通过
HookRuntime分发PreToolUse、PostToolUse、AfterAgent等钩子事件,允许用户自定义脚本在工具执行前后介入。
因此,harness 的关键词不是”执行”,而是编排。它是一个围绕模型的调度壳,确保模型的行为始终在可控、可观测、可恢复的框架内运行。
Runtime: The Execution Plane
与 harness 相对,runtime 更像 execution plane。
如果 harness 负责回答”该不该做、怎样组织做”,那么 runtime 负责回答:
既然决定要做了,那这件事怎样在真实环境里安全地执行起来?
runtime 更靠近操作系统,典型职责包括:
- 把工具请求转成真实的进程执行;
- 设置工作目录、环境变量、stdio 策略;
- 应用沙盒策略;
- 应用网络限制;
- 处理超时、取消、输出截断、流式输出;
- 收集 stdout / stderr 并回传给 harness。
所以更准确的关系不是”harness 和 runtime 并列夹在模型与 OS 中间”,而是:
- harness 是更外层的控制系统;
- runtime 往往是 harness 里的执行子系统。
在 Codex 的开源实现里,这个边界是能看到的:
execpolicy/负责策略定义与审批逻辑,偏向 harness 层的决策;core/src/tools/orchestrator.rs是ToolOrchestrator,编排”审批 → 选沙盒 → 执行 → 重试”的完整管线,是 harness 与 runtime 的交界;core/src/exec.rs把工具执行请求构造成真正的操作系统进程;core/src/spawn.rs负责最终的子进程启动(支持 PTY);sandboxing/目录(独立 crate)包含各平台的具体沙盒后端实现:seatbelt.rs(macOS)、landlock.rs(Linux)、windows.rs(Windows);core/src/sandboxing/包含沙盒适配器类型,定义了上层与各平台实现之间的接口。
从源码中可以清晰地看到,每个具体工具(如 ShellHandler、ApplyPatchHandler)都实现了 ToolRuntime trait,这个 trait 定义了工具与编排器之间的契约:
|
|
这意味着 runtime 不是一块模糊的”执行层”,而是每个工具都明确声明自己的审批需求、沙盒偏好和失败升级策略。
因此,一个更贴切的说法是:
Harness 是管”过程”的,runtime 是管”落地执行”的。而两者之间的契约由
ToolRuntimetrait 和ToolOrchestrator共同定义。
Sandboxing, Approvals, and Trust Boundaries
理解 Codex 时,最容易混淆的另一个点,是把 sandbox 和 approval 当成一回事。实际上它们是两层不同的控制。
可以这样记:
- sandbox:技术边界,决定“做不做得到”
- approval policy:交互边界,决定“越界前要不要先问人”
这两层结合起来,才构成 Codex 的真实信任边界。
Sandbox
沙盒的作用是限制 agent 能碰到什么。
本地 CLI / IDE 场景下,OpenAI 官方文档明确说明 Codex 使用的是 OS-level sandboxing:
- macOS:Seatbelt,底层通过
sandbox-exec系统调用实现文件系统和网络限制; - Linux:Landlock(Linux Landlock LSM),通过 Linux 内核的 Landlock 模块实现细粒度的文件系统访问控制;
- Windows:独立实现,通过受限 token 和权限控制实现沙盒。
在默认模式下,Codex 一般具有这样的边界:
- 只能在当前 workspace 内读写;
.git、.codex、.agents这类路径可以被进一步保护;- 网络默认关闭;
- 通过工具启动的命令同样继承沙盒,而不是只有“内建文件编辑”才受限制。
官方文档里常见的几种模式是:
read-onlyworkspace-writedanger-full-access
这些模式回答的都是同一个问题:agent 技术上能碰到哪些文件和哪些系统能力。
Approval Policy
审批层关心的不是”能不能做到”,而是”遇到越界或高风险动作时,要不要停下来问用户”。
例如:
- 访问网络;
- 写工作区之外的目录;
- 执行不在允许规则内的命令;
- 执行明显具有破坏性的操作。
源码中的审批机制通过 ExecApprovalRequirement 枚举来表达,主要有三种状态:
Skip:不需要审批,直接执行;Forbidden:禁止执行;NeedsApproval:需要审批后才能执行。
面向用户的可配置策略模式通常包括:
untrusted:所有操作都需要审批;on-request:仅在越界时请求审批;on-failure:失败时再请求升级;never:不请求审批(全部自动执行)。
此外,Codex 还支持 Guardian System(自动审批审查器)。Guardian 可以在没有用户介入的情况下,根据规则自动决定是否允许某个工具调用。这对于无人值守的长时间任务(如 CI/CD 集成、云端 agent)至关重要。Guardian 相当于一个自动化的”安全审查员”,在 harness 和用户之间增加了一层缓冲。
所以,一个动作可能在技术上可执行,但策略上仍要求先审批;反过来,一个动作即使用户愿意批准,如果底层沙盒根本不允许,也不能直接执行。Guardian 则在这两者之间提供了一个中间地带:不需要等用户在线,但仍然有规则约束。
Local vs Cloud
这里顺便补上本地与云端的区别,因为这和 sandbox 的实现方式直接相关。
在本地模式下:
- 模型推理仍在云上;
- 但命令执行和文件修改发生在你的机器上;
- 沙盒依赖你的操作系统机制来约束本地进程。
在云端模式下:
- agent 跑在 OpenAI 管理的隔离容器里;
- 官方文档采用两阶段模型:
setup阶段可装依赖,agent阶段默认离线; - secrets 只在 setup 阶段可用,进入 agent 阶段前会被移除。
这说明“本地 / 云端”的差异,不只是文件放在哪,而是整个执行边界和安全模型都不同。
End-to-End Lifecycle: From Query to Response
把前面的概念串起来,Codex 的一次完整生命周期可以画成这样:
|
|
这张图里有几个关键点值得再强调。
第一,模型并不直接操作操作系统。模型只能生成”下一步动作意图”(tool call),真正把它落成系统调用的是 harness 中的 ToolOrchestrator 和 runtime 中的 ToolRuntime::run()。
第二,工具调用不是一次性的插曲,而是 agent loop 的一部分。工具结果会作为 ResponseInputItem 重新进入 ContextManager,继续驱动模型的下一轮决策。
第三,每一步都有明确的边界控制。ToolOrchestrator 的管线设计确保了审批、沙盒、钩子这三个安全层在每次工具执行时都被正确穿过。
第四,上下文管理贯穿始终。从 for_prompt() 的标准化,到 compaction 的自动触发,再到 token 使用量的持续追踪,ContextManager 保证了模型始终能看到正确的、不超过窗口大小的上下文。
因此,Codex 不是”模型 + 插件”的松耦合结构,而是一个把观察、动作、验证、压缩和回复连接起来的闭环系统。
Long-running Commands and Streaming
Codex 的长命令体验之所以看起来“像有人在后台盯着终端看”,就是因为这里存在两条并行通道。
第一条通道是 原始进程输出流。
命令启动后,runtime 会持续读取 stdout / stderr,并把新增内容流式推给前端或宿主程序。这部分并不一定要求模型重新推理,所以你看到的很多实时日志,其实只是进程本身在打印。
第二条通道是 工具结果驱动的新推理。
典型流程通常像这样:
- 启动命令;
- 等一个
yield_time_ms; - 收集当前输出;
- 把这部分输出作为 tool result 返回;
- 如果进程还在运行,则保留
session_id; - 后续再用
write_stdin(session_id, chars="")轮询新输出。
因此更准确的理解方式是:
|
|
所以看起来像”边跑边汇报”,本质上是三件事叠加:
- runtime 负责维持进程和流式输出;
- tool result 负责把阶段性观察送回模型;
- 模型负责把这些观察翻译成更易读的自然语言或下一步行动。
Context Management and Auto-Compaction
前面的章节讲了工具执行和沙盒,但还有一个很容易被忽略、却直接影响 agent 能不能”长跑”的问题:上下文管理。
在 Codex 源码中,ContextManager(位于 core/src/context_manager/)是上下文管理的核心。它维护的是一个有序的对话历史列表(Vec<ResponseItem>),从最早到最新排列,并在每次调用模型前做标准化处理。
但问题是:对话历史会不断增长。每轮工具调用都会产生新的消息项(工具调用本身、工具结果、模型的中间推理),长任务下来,历史很容易超出模型的上下文窗口。
Codex 的解决方案是 自动上下文压缩(Auto-Compaction),实现在 core/src/compact.rs 中。当 ContextManager 检测到 token 使用量接近上限时(通过 TokenUsageInfo 追踪),会触发以下流程:
- 暂停当前的 agent loop;
- 启动一次专门的 summarization 任务,让模型把旧的对话历史压缩成一段摘要;
- 用摘要替换掉被压缩的历史;
- 重新注入初始上下文(system / developer 指令);
- 继续后续的 agent loop。
这保证了 Codex 可以在理论上无限执行下去,而不会因为上下文溢出而崩溃。代价是旧细节会丢失,但关键指令和最新状态会被保留。
ContextManager 的几个关键方法:
record_items()— 向历史中追加新的消息项;for_prompt()— 准备发送给模型的历史(标准化 + 模态过滤);set_token_usage_full()— 标记上下文已满,触发 compaction。
这个机制的存在说明,agent 系统的可持续性不是免费的。它需要 harness 层主动管理上下文生命周期,而模型本身并不知道自己正在被”压缩”。
Hooks: Extending the Agent Loop
Codex 的 harness 不仅是一个封闭的调度系统,它还提供了钩子(Hooks)机制,允许用户在 agent loop 的关键节点插入自定义逻辑。
钩子系统位于 codex-rs/hooks/ 中,支持三种类型的钩子:
| 钩子 | 触发时机 | 用途 |
|---|---|---|
PreToolUse |
工具执行之前 | 可以阻止命令执行、修改参数、记录审计日志 |
PostToolUse |
工具执行之后 | 可以修改返回结果、触发后续动作、记录结果 |
AfterAgent |
一个 agent turn 完成后 | 可以执行收尾操作、触发通知、更新外部状态 |
钩子的配置写在 config.toml 中,通过 HookRuntime 分发。一个典型的用例是:
- 在
PreToolUse中检查 shell 命令是否包含危险操作(如rm -rf /),并自动阻止; - 在
PostToolUse中把每次文件修改同步到备份系统; - 在
AfterAgent中发送任务完成通知。
钩子系统使得 Codex 的行为可以被用户定制,而不需要修改 Codex 本身的源码。这是 harness 作为”编排层”的另一个体现:它不仅编排内部组件,还允许外部逻辑介入编排过程。
Multi-agent as a Tree of Threads
再往上看 multi-agent。
Codex 的 multi-agent 更像一棵线程树,而不是多个 agent 共用一份上下文的共享池。
通常会有:
- 一个 root agent;
- 若干 child agent;
- 每个 child agent 都有自己的消息历史、任务输入、工具状态和执行循环。
因此默认情况下,子 agent 并不会天然共享父 agent 的完整上下文。常见的信息传递方式有三种:
-
spawn_agent(..., fork_context = true)显式复制父线程的对话上下文给子 agent; -
send_input给目标 agent 发送结构化输入(用户指令或任务描述); -
wait_agent/list_agents查看子 agent 的执行状态,等待其完成后汇总结果。
从架构上说,multi-agent 并没有改变 harness / runtime 的基本关系。它只是把“单个 agent loop”扩展成了“多个相互隔离、但可由上层协调的 agent loop”。
这意味着 multi-agent 的核心不是“共享脑子”,而是:
- 上下文默认隔离;
- 需要时再显式复制或显式传递;
- 上层 harness 负责协调并汇总结果。
The Architecture in One Picture
如果把 Codex 的主要模块放到一张图里,可以得到这样一个更稳定的架构视图:
|
|
这张图里有几个关键判断:
Model
模型负责推理,但不直接触碰操作系统。它的输出是”意图”(自然语言或 tool call),不是最终系统调用。
Harness
harness 是总调度台。它包含 Session(全局状态)、ContextManager(上下文与压缩)、Agent Loop(循环驱动)、ToolOrchestrator(审批与沙盒编排)、ToolRouter(工具路由)、HookRuntime(钩子分发)和 Guardian(自动审批)。它关心上下文怎么组织、工具怎么暴露、审批怎么插入、上下文何时压缩、任务何时结束。
Runtime
runtime 是执行引擎。每个 ToolRuntime 实现了与编排器之间的契约——声明自己的审批需求、沙盒偏好和失败升级策略,然后通过 exec.rs → spawn.rs → OS 的路径真正执行。它关心工具请求怎样变成真实命令、如何拿到输出、如何处理长进程和超时。
Sandbox
sandbox 是技术边界。它不是”建议模型克制一点”,而是底层真正限制命令能做什么。三个平台各有独立实现(Seatbelt / Landlock / Windows Sandbox),由 SandboxManager 统一调度。
Approval
approval 是人机协作边界。它决定哪些事情必须停下来问用户,而不是自动继续。Guardian 在此提供了自动审批能力,使得在无人值守场景下仍然有安全规则约束。
OS / Container
OS 或云容器才是真正执行系统调用的地方。文件到底被谁改了、进程到底在哪里被 spawn,发生在这一层。
因此,把这些模块串起来后,一个常见误解就可以被纠正:
Codex 不是模型直接“会用电脑”,而是模型在 harness 的调度下,通过 runtime 和 sandbox 受限地使用执行环境。
A Practical Mental Model
如果要把整篇文章压缩成一个简化心智模型,我觉得最有用的是下面这组对应关系:
- 模型:负责想下一步做什么(基于上下文推理,输出自然语言或 tool call);
- tool spec:告诉模型有哪些动作可以选(能力边界,不是实现细节);
- ToolRouter + ToolRegistry:根据模型发出的 tool call,找到对应的处理器;
- ToolOrchestrator:负责"审批 → 选沙盒 → 执行 → 重试"的编排管线,是 harness 和 runtime 的交界;
- ToolRuntime(每个工具各自实现):声明自己的审批需求和沙盒偏好,然后真正执行;
- ContextManager:管理对话历史,在 token 接近上限时触发压缩;
- HookRuntime:允许用户自定义脚本在 PreToolUse / PostToolUse / AfterAgent 三个节点介入;
- Guardian:在无人值守场景下自动决定是否批准某个工具调用;
- sandbox:负责限制它能碰什么(技术边界,平台级强制执行);
- approval:负责决定何时必须先问用户(交互边界);
- OS / cloud env:负责真正执行命令和文件操作。
换成一句更口语的话:
LLM 负责下工单,ToolRouter 负责找对人,ToolOrchestrator 负责把关放行,ToolRuntime 负责施工,ContextManager 负责整理记忆,HookRuntime 负责外挂钩子,Guardian 负责替用户守夜,sandbox 和 approvals 负责围栏,OS 或容器才是真正动手干活的地方。
其中最值得记住的一句话是:Codex 的能力来自整个系统,而不只是模型。 很多表面上看像"模型能力"的东西,其实属于模型外部的系统组件。
Final Notes
理解 Codex 的关键,不是记住几个术语,而是分清不同层的职责边界。
很多表面上看像”模型能力”的东西,其实属于模型外部系统:
- 可不可以本地改文件 — 由 sandbox 策略决定,不是模型决定;
- 长命令为什么能流式展示 — 由 runtime 的流式输出机制 + tool result 回传机制共同实现;
- 为什么有时候会被要求审批 — 由
ToolOrchestrator根据ExecApprovalRequirement决定; - 长任务为什么不会因为上下文溢出而崩掉 — 由
ContextManager的 auto-compaction 保证; - 为什么子 agent 不自动共享全部上下文 — multi-agent 默认隔离,需要显式
fork_context; - 为什么本地和云端的安全模型不同 — 本地依赖 OS-level sandbox,云端依赖容器隔离 + 两阶段模型;
- 外部工具怎么接入 — 通过 MCP(Model Context Protocol)集成,由
McpHandler桥接; - 用户怎么能不写源码就定制行为 — 通过 hooks 系统在关键节点注入自定义脚本。
把这些边界理清之后,Codex 就不会再像一个神秘的”会写代码的黑盒”。它更像一套分层明确的 agent architecture:
- 上层是指令和目标(system / developer / user);
- 中层是 harness 编排(Session, Agent Loop, ToolOrchestrator, ContextManager, Hooks)和模型决策;
- 下层是 runtime 执行(各 ToolRuntime 实现, exec.rs, spawn.rs)与沙盒限制;
- 最底层才是真实的操作系统或云容器环境。
也正因为如此,Codex 的很多产品体验,其实不只是模型问题,而是 harness engineering 问题。模型决定上限,harness 和 runtime 决定它能不能稳定、可控、可恢复地把事情做完。
References
[1] OpenAI Developers, Sandboxing, accessed March 28, 2026.
[2] OpenAI Developers, Agent approvals & security, accessed March 28, 2026.
[3] OpenAI Developers, Agent internet access, accessed March 28, 2026.
[4] OpenAI, Introducing the Codex app, accessed March 28, 2026.
[5] OpenAI Cookbook, GPT-5-Codex Prompting Guide, accessed March 28, 2026.
[6] OpenAI Codex GitHub repository, openai/codex, accessed March 28, 2026.
[7] OpenAI Codex source, codex-rs/core/src/exec.rs, accessed March 28, 2026.
[8] OpenAI Codex source, codex-rs/sandboxing/ (Seatbelt, Landlock, Windows sandbox implementations), accessed March 28, 2026.
[9] OpenAI Codex source, codex-rs/core/src/spawn.rs, accessed March 28, 2026.
[10] OpenAI Codex source, codex-rs/core/src/compact.rs (auto-compaction), accessed March 28, 2026.
[11] OpenAI Codex source, codex-rs/hooks/ (hooks system), accessed March 28, 2026.
[12] OpenAI Codex source, codex-rs/execpolicy, accessed March 28, 2026.
[13] OpenAI Codex source, codex-rs/core/src/tools/orchestrator.rs (ToolOrchestrator), accessed March 28, 2026.
[14] OpenAI Codex source, codex-rs/app-server/ (JSON-RPC app-server for IDE integrations), accessed March 28, 2026.