# Codex 源码解读

> 逐层拆读 OpenAI 开源的终端编码 Agent Codex CLI 的 Rust 源码（rust-v0.158.0）——从 app-server 架构、agent 内核、工具与沙箱，到扩展机制与终端界面，一边讲怎么用，一边讲怎么实现。

- 作者：David（道雾轩）
- 最后更新：2026-09-29
- 原文：https://daiw.net/manual/codex-source
- 转载与引用：请注明出处并附原文链接（https://daiw.net/about/copyright）

# Codex 源码解读

[Codex CLI](https://github.com/openai/codex)（命令行叫 `codex`）是 OpenAI 开源的**终端编码 Agent**：在你本机的终端里阅读代码、修改文件、执行命令、调用 MCP 工具，也能用 `codex exec` 嵌进脚本和 CI。它的主体是 `codex-rs/` 下的一个 **Rust** Cargo workspace，显式列出的成员有 153 个、约 190 万行代码（去掉测试约 82 万行，口径见下文“源码基准”）。

这个专栏把它**逐层拆开读**。

## 这个专栏怎么读

每一章尽量走**两条线**：

- **怎么用**——这个功能在 `codex` 里长什么样。详细用法站里已经有一本 [《Codex 中文手册》](https://daiw.net/manual/codex)，这里只点到为止，并链接到手册的对应页面；
- **怎么实现**——翻到对应 crate 的源码，看它在底层到底怎么做。

侧重**结构与数据流**：讲清“一件事经过哪些 crate、哪些类型、数据怎么流、边界契约是什么”，而不是逐行贴代码——关键处才引一小段源码点睛。每段摘录都原样取自源码，并在下方注明 `路径:行号`。

## 和《从 LLM 到 Coding Agent》配对

站里的 [《从 LLM 到 Coding Agent》](https://daiw.net/manual/llm-to-agent) 讲“一个 Coding Agent 在裸 LLM API 之上该做哪些事”，配了一个从零手搓的教学实现。这本则是同一件事的**生产实现**：agent 循环、工具、上下文、权限、扩展……教学实现让你看清骨架，生产实现让你看清骨架周围要长出多少东西。不少章节末尾有“和《从 LLM 到 Coding Agent》对照”一节，两边对照着读，收获最大。

同一组里还有 [《Grok Build 源码解读》](https://daiw.net/manual/grok-build)、[《OpenCode 源码解读》](https://daiw.net/manual/opencode) 等几本同类专栏，最后一部分会把它们放在一起比较。

<Callout type="info">
  **读者预设**：默认你懂一点 Rust（读得下 `async`、trait、`Arc`、workspace 分层），知道 tokio 是什么。不熟的语言点会在关键处就地补一句，但不系统教 Rust。读过《Codex 中文手册》会更顺，但不是硬前提。
</Callout>

## 源码基准

本专栏所有引用以下述快照为准：

| 项 | 值 |
| --- | --- |
| 仓库 | [github.com/openai/codex](https://github.com/openai/codex) |
| 版本 | Codex CLI 0.158.0（tag `rust-v0.158.0`，2026-09-28 发布） |
| commit | `064c6b8c737f5b41d171fdda80bd9ef10ad06eb3`（提交日期 2026-09-27） |
| 许可 | Apache-2.0 |
| workspace | `codex-rs/Cargo.toml` 的 `members` 显式列出 153 个；另有 5 个 crate（`windows-sandbox-rs`、`chatgpt`、`message-history` 与两个测试支撑 crate）作为路径依赖被 Cargo 自动纳入。crate 名是目录名加 `codex-` 前缀（如 `core` 即 `codex-core`） |
| 代码量 | 153 个显式成员共 4,770 个 `.rs` 文件、约 190 万物理行；去掉测试（`tests.rs`、`*_tests.rs`、`tests/` 目录与 `#[cfg(test)]` 块）约 82 万行。自动纳入的 5 个另有约 3.1 万行非测试代码，其中 `windows-sandbox-rs` 约 1.9 万行 |
| 最大的几个 crate | `tui` 约 20.6 万行、`core` 约 11.4 万行、`app-server` 约 4.4 万行（均为去掉测试后） |

所有路径都相对仓库根，例如 `codex-rs/core/src/session/turn.rs`；文中指向 GitHub 的源码链接都固定在 `rust-v0.158.0` 标签上。《Codex 中文手册》也以同一版本为基准。

## 路线图

- **第 0 部分 · 导论与全景**——Codex CLI 开源的是哪一部分、怎么从源码构建、153 个 workspace 成员怎么分层、读源码前要知道的工程约定，以及贯穿全书的主线：一条消息从按下回车到看到回复的全过程。
- **第 1 部分 · app-server 与线程**——终端界面、`codex exec`、IDE 与桌面客户端共用的 app-server、它的 v2 协议、守护进程与各种传输，线程的生命周期与会话持久化。
- **第 2 部分 · Agent 内核**——Session 与每轮配置、`run_turn` 主循环、模型客户端、只追加的上下文历史、压缩、指令组装、模型目录与提供方、任务类型与 Plan 模式。
- **第 3 部分 · 工具系统**——工具的暴露、注册、路由与并行，命令执行与 unified exec、命令解析与安全判断、`apply_patch`、MCP 工具调用、其它内置工具与 Code mode。
- **第 4 部分 · 安全：权限、审批与沙箱**——权限模型、审批流程，macOS、Linux、Windows 三套沙箱，网络代理、执行策略与自动审查。
- **第 5 部分 · 扩展机制**——配置系统、Skills、Hooks、插件、MCP 客户端、多 agent、扩展 API、记忆，以及从别的 agent 迁移过来。
- **第 6 部分 · 终端 UI**——TUI 架构、输入框、历史记录单元与流式渲染、全屏对话记录与其它界面。
- **第 7 部分 · 运行形态与工程**——exec-server、登录认证、实时语音、遥测、Codex Cloud 与代码审查，以及测试、构建与发布。
- **第 8 部分 · 收尾**——对照《从 LLM 到 Coding Agent》复盘，与 Grok Build、OpenCode 横向比较，读完之后怎么继续。

准备好了，就从 [Codex CLI 是什么](https://daiw.net/manual/codex-source/what-is-codex) 开始。

## 本专栏篇目

- [Codex 源码解读](https://daiw.net/manual/codex-source.md): 逐层拆读 OpenAI 开源的终端编码 Agent Codex CLI 的 Rust 源码（rust-v0.158.0）——从 app-server 架构、agent 内核、工具与沙箱，到扩展机制与终端界面，一边讲怎么用，一边讲怎么实现。

### 第 0 部分 · 导论与全景

- [Codex CLI 是什么 · 开源的是哪一部分](https://daiw.net/manual/codex-source/what-is-codex.md): Codex CLI 是 OpenAI 在你本机运行的编码 agent，仓库 openai/codex 以 Apache-2.0 开源。开源的是本地这一侧：Rust 写的 CLI、TUI、app-server、agent 内核、工具与三套沙箱，外加 npm 启动器和 TypeScript、Python 两个 SDK；模型、ChatGPT 后端、IDE 扩展与桌面应用都不在仓库里。npm 包里的 codex.js 只是一个挑平台二进制、转发信号的启动器。
- [从源码构建与运行 · Cargo、Bazel 与 npm 包装](https://daiw.net/manual/codex-source/build-and-run.md): Codex 同时维护两套构建：Cargo 是 crate 与依赖的事实来源，日常开发与正式发布都靠它；Bazel 从 Cargo.lock 导入依赖，负责封闭构建、跨平台产物与 CI，官方文档仍称其为实验性。发出去的只有一个 codex 二进制，arg0 按程序名和第一个参数把它分派成 Linux 沙箱助手、apply_patch 等多个入口；npm 包再用 optionalDependencies 别名只装上本平台的那一份。
- [workspace 全景 · 153 个成员怎么分层](https://daiw.net/manual/codex-source/workspace-map.md): codex-rs 的 members 列了 153 个 crate，按职责可以归成十二组：入口与终端界面、app-server 与传输、内核、工具与执行、沙箱与安全、扩展机制等。依赖方向很清楚：前端只认 app-server，app-server 驱动 codex-core，codex-core 再把工具、沙箱、MCP、模型调用、持久化分给几十个卫星 crate；TUI 甚至不直接依赖 codex-core。
- [读源码之前 · 仓库的工程约定](https://daiw.net/manual/codex-source/reading-the-source.md): 根目录 AGENTS.md 是写给所有贡献者（包括 Codex 自己）的开发规范：crate 命名、少往 codex-core 里加代码、模块 500 行目标、trait 用 RPITIT、模型可见上下文的六条硬规矩、测试与快照、app-server v2 的命名规范。读懂这些约定，很多“代码为什么长这样”就有了答案；本篇最后给出推荐的阅读顺序，以及在近百万行代码里找东西的办法。
- [一条消息的生命周期 · 从按下回车到看到回复](https://daiw.net/manual/codex-source/message-lifecycle.md): 在 TUI 里按下回车，输入先变成一个 AppCommand，再变成发给 app-server 的 turn/start 请求；app-server 把它交给 codex-core 的提交队列，内核起一个 RegularTask 反复调用 run_turn：流式请求模型、边收边派发工具、需要时经 app-server 向界面要审批；内核的事件经每线程一个的监听任务翻译成 v2 通知，回到 TUI 变成流式渲染的历史记录单元。turn/start 立即返回，回复全靠通知。

### 第 1 部分 · app-server 与线程

- [app-server · 所有前端共用的服务端](https://daiw.net/manual/codex-source/app-server-architecture.md): TUI、codex exec、IDE 扩展与桌面端都不直接调用 codex-core，而是经 JSON-RPC 访问同一个 app-server：要么在进程内嵌一份，要么通过 stdio、Unix socket 或 WebSocket 连一份。本篇拆开 MessageProcessor 的分派与按资源串行、线程事件翻译成通知的监听任务，以及审批这类服务端请求怎样一来一回。
- [v2 协议 · thread、turn 与 item](https://daiw.net/manual/codex-source/app-server-protocol.md): app-server 的线上格式全部定义在 codex-app-server-protocol 一个 crate 里：几个声明宏把 170 个客户端请求、11 个服务端请求与 85 种通知连同参数、响应、实验开关和串行范围一次声明清楚；数据模型是 thread 包含 turn、turn 包含 item。TypeScript 与 JSON Schema 在测试里生成、压缩后嵌进二进制，v1 只剩握手类型和几个弃用方法。
- [守护进程与传输 · 一个服务端，多种连法](https://daiw.net/manual/codex-source/daemon-and-transport.md): 同一个 app-server 可以经 stdio、Unix socket、TCP WebSocket 接客户端，还能主动连到 ChatGPT 的中转服务接受远程控制，四种入口最后都变成同一种 TransportEvent。codex-app-server-daemon 把它托管成后台进程：pid 记录、生命周期锁、独立安装包、自动更新与重启后恢复线程；在 Unix 上，控制 socket 放在沙箱会屏蔽的固定目录里。
- [ThreadManager 与 CodexThread · 线程的生与死](https://daiw.net/manual/codex-source/thread-manager.md): 线程在 app-server 里是一段可订阅的对话，在 codex-core 里是 ThreadManager 注册表中的一个 CodexThread：一端是提交队列，一端是事件队列。新建、恢复、分叉都汇入同一个 spawn_thread，差别只在初始历史；卸载、归档、删除则先关掉运行时，再交给 thread-store 处理持久化数据。
- [会话持久化 · rollout、thread-store 与 SQLite](https://daiw.net/manual/codex-source/rollout-and-storage.md): 每个线程落盘为 sessions 目录下一个只追加的 JSONL 文件（rollout），它是唯一的真相；SQLite 里的线程列表与分页历史都是可以重建的投影。本篇看文件布局与行格式、后台写入任务与跨进程写锁、legacy 与 paginated 两种历史格式各记什么，以及冷数据压缩和输入历史 history.jsonl。
- [codex exec 与 SDK · 没有界面的用法](https://daiw.net/manual/codex-source/exec-and-sdk.md): codex exec 是一个把 app-server 嵌在自己进程里的无界面客户端：发 thread/start 与 turn/start，把 v2 通知翻译成给人看的输出或一套更简单的 JSONL 事件，遇到审批请求一律拒绝，本轮结束就退出。TypeScript SDK 每一轮都拉起一次 codex exec 读它的 JSONL；Python SDK 则直接经 stdio 连 codex app-server，讲完整的 v2 协议。

### 第 2 部分 · Agent 内核

- [Session 与 TurnContext · 会话状态与每轮配置](https://daiw.net/manual/codex-source/session-and-turn-context.md): Codex 内核把状态分成三层：线程级的 Session、一轮一个的 TurnContext、每次模型请求一个的 StepContext。一轮开始时，设置先在锁内提交成线程默认值，再冻结成本轮只读的 TurnContext；每发一次请求，还要再冻结一次模型、工具与环境。
- [run_turn 主循环 · 一轮对话是怎么转起来的](https://daiw.net/manual/codex-source/turn-loop.md): 一轮对话是一个 RegularTask 反复调用 run_turn。run_turn 先做开轮准备，再进入循环：取出用户插话、捕获本次请求的 step、流式采样并边流边派发工具，最后按“还要不要继续”“上下文满没满”“Stop hook 放不放行”决定再来一次、压缩后再来，还是收尾；可重试的流错误在采样函数内部就地退避重试。
- [模型客户端 · Responses API 的流式调用](https://daiw.net/manual/codex-source/model-client.md): 会话级的 ModelClient 管认证、提供方与传输回落，每轮一个的 ModelClientSession 管 WebSocket 连接与粘性路由令牌。请求由 build_responses_request 拼成无状态的 Responses 请求；能用 WebSocket 时只发增量输入，否则走 HTTP 的 SSE；codex-api 把 SSE 或 WebSocket 事件、错误码与限额头统一翻译成 ResponseEvent。
- [上下文与历史 · 只追加、不改写](https://daiw.net/manual/codex-source/context-history.md): 发给模型的历史由 ContextManager 保管，只追加、不改写。环境、权限、协作模式、AGENTS.md 这些会变的上下文被建模成“世界状态”的各个分区：第一轮注入完整快照，之后只追加变化的部分，连换模型、改 AGENTS.md 也是追加一条新消息。真正改写历史的只有压缩与回滚，而且会同时清掉基准、下一轮重新注入完整上下文。
- [上下文压缩 · 窗口快满时怎么办](https://daiw.net/manual/codex-source/compaction.md): 压缩在四个时机触发：开轮前（换了模型或已超限）、一轮中途（模型还要继续但窗口快满）、轮末（可选）与手动的 /compact。OpenAI 等支持的提供方走远程压缩：在历史末尾追加一个触发条目，由服务端返回一个不透明的压缩条目；其余提供方走本地压缩，让模型按提示词写交接摘要。压缩后历史被整体替换，只保留最近的用户消息，这是“只追加”原则唯一的常规例外。
- [指令从哪来 · AGENTS.md、系统提示词与协作模式](https://daiw.net/manual/codex-source/instructions.md): 请求里的“系统提示词”只有基础指令一段，线程创建时定下，此后不变；开发者指令、权限说明、协作模式放在 developer 消息里，AGENTS.md 与环境信息放在 user 消息里，组织托管的开发者指令单独成条。AGENTS.md 由全局、线程与项目三部分拼成，全局部分每次请求前都重读，项目部分按执行环境与信任级别缓存。
- [模型目录与提供方 · 一个 CLI 接多家后端](https://daiw.net/manual/codex-source/models-and-providers.md): 模型能做什么由模型目录决定：每个模型一条 ModelInfo，上下文窗口、推理强度、工具形态、基础指令模板都写在里面，目录来自随附文件、磁盘缓存与服务端的 models 接口。请求发到哪、怎么认证由提供方决定：配置层的 ModelProviderInfo 描述端点与凭据，运行时的 ModelProvider 负责认证、能力上限与目录管理，所有后端都只说 Responses API 这一种协议。
- [任务类型与 Plan 模式 · 一轮里跑的不只是对话](https://daiw.net/manual/codex-source/tasks-and-plan-mode.md): 会话同一时刻只跑一个任务，任务都实现 SessionTask：普通对话、压缩、审查与用户 shell 命令四种实现，共用同一套启动、结束与中断流程，中断时先给任务 100 毫秒自行收尾再强制终止。Plan 模式不是一种任务，而是协作模式的一个取值：它换了一套开发者指令，从回复里解析计划块，禁用 update_plan，让 request_user_input 可用；“不做改动”只写在提示词里，沙箱与审批并不因此收紧。

### 第 3 部分 · 工具系统

- [工具系统总览 · 暴露、注册、路由与并行](https://daiw.net/manual/codex-source/tool-architecture.md): Codex 在每次采样前重新规划一遍工具：spec_plan 依据特性开关、模型目录、提供方能力与执行环境挑出工具登记进 ToolRegistry，再决定每个工具是直接给模型、留给 tool_search 还是只给 Code mode。模型发出的调用在流还没结束时就被派发，一把读写锁区分可并行与需独占的工具，再经 hook、处理器与编排器落地。
- [执行命令 · shell 与 unified exec](https://daiw.net/manual/codex-source/unified-exec.md): 0.158.0 里模型执行命令只剩 unified exec 一条路：exec_command 起进程、write_stdin 续写或轮询。命令经处理器解析成 shell 参数，由编排器决定审批与沙箱，再以 PTY 或管道启动；活着的进程留在进程表里跨轮复用，输出先在 1 MiB 的头尾缓冲里收集，再按 token 预算截断给模型，同时以增量事件流给界面。
- [读懂一条命令 · 解析、安全判断与 shell 快照](https://daiw.net/manual/codex-source/shell-command-analysis.md): 模型交来的只是一段 shell 字符串，Codex 要从三个角度读它：给人看的语义摘要（读文件、搜索、列目录）、给审批用的安全判断、给执行提速的 shell 快照。解析靠 tree-sitter 分严格与宽松两档，前者用来逐条匹配规则，后者只用来找危险命令；0.158.0 的内置危险判断只盯带强制选项的 rm 与几类 Windows 命令，其余交给审批策略和沙箱。
- [apply_patch · Codex 的文件编辑格式](https://daiw.net/manual/codex-source/apply-patch.md): Codex 没有直接写工作区文件、替换字符串的工具，改文件统一走 apply_patch：一种以 *** Begin Patch 开头、按文件分段、不带行号的精简 diff。解析器永远以宽松模式运行，seek_sequence 分四级放宽匹配，写进 shell 命令的补丁也会被截下来按补丁处理；补丁先校验、再审批，最后在执行环境的文件系统里逐个 hunk 落盘，不保证原子性。
- [MCP 工具调用 · 连接管理与工具目录](https://daiw.net/manual/codex-source/mcp-tool-calls.md): MCP 在 Codex 里分三层：线程级的 McpRuntime 负责连接与重连，McpConnectionSet 管一批 RMCP 客户端，每次采样前冻结出一个 McpBinding 作为这一步的工具目录。工具进目录时被过滤、改名成 mcp__服务器 命名空间下的函数，并按模型能力决定直接暴露还是留给 tool_search；调用时先按注解与 approval_mode 决定要不要审批，审批本身以 elicitation 表单呈现，服务器发起的 elicitation 则按审批策略自动处理或转给用户。
- [其它内置工具 · 计划、提问、权限与搜索](https://daiw.net/manual/codex-source/builtin-tools.md): 除了执行命令、改文件和 MCP，Codex 还有十来个内置工具：update_plan、request_user_input、request_permissions、时钟与上下文预算工具、插件安装建议、view_image、网页搜索、图片生成与 tool_search。它们大多由特性开关或模型目录按需打开，参数与返回格式都写在各自的 spec 文件里；按执行位置可分为纯内核、要等前端回应、服务端托管与扩展贡献四类。
- [Code mode · 让模型写 JavaScript 编排工具](https://daiw.net/manual/codex-source/code-mode.md): Code mode 给模型一个 exec 工具：模型写一段 JavaScript，在独立宿主进程里的 V8 isolate 中执行，脚本通过全局 tools 对象调用 Codex 的其它工具，中间结果留在脚本里，只把最后的文本、图片交还模型。它在 0.158.0 仍是开发中特性，由 code_mode / code_mode_only 开关或模型目录打开；宿主 codex-code-mode-host 默认经 stdin/stdout 与 Codex 通信，也能以 gRPC 服务的形式远程部署。

### 第 4 部分 · 安全：权限、审批与沙箱

- [权限模型 · 沙箱策略与审批策略](https://daiw.net/manual/codex-source/permissions-model.md): Codex 的安全边界由两个独立的量决定：PermissionProfile 规定命令在技术上能碰什么，AskForApproval 规定越界之前要不要问人。本篇讲清两者的取值、旧的 sandbox_mode 与新的权限配置档如何编译成同一个 PermissionProfile、“最具体者胜”的路径裁决、.git 等元数据保护，以及管理员下发的 deny_read。
- [审批流程 · 什么时候停下来问你](https://daiw.net/manual/codex-source/approvals-flow.md): 一次命令或补丁要不要问人，要过三道关：执行策略先判定“跳过、需要批准、禁止”，ToolOrchestrator 据此审批、选沙箱，并在沙箱拒绝后视策略请求提权重试，审批请求再按“钩子、自动审查、用户”的顺序分派。发给用户的请求经 app-server 变成 item/commandExecution/requestApproval，回复沿 Op::ExecApproval 唤醒挂起的 oneshot。默认的 on-request 下，命令失败不会自动弹“去掉沙箱重试”，提权由模型主动申请。
- [macOS 沙箱 · Seatbelt 策略生成](https://daiw.net/manual/codex-source/seatbelt.md): macOS 上 Codex 不装任何驱动，而是把每条命令交给系统自带的 /usr/bin/sandbox-exec，附上一段现拼的策略。策略由 codex-sandboxing 按 PermissionProfile 生成：以 (deny default) 为底，叠上读、写、网络三段，再追加守护进程套接字、XPC、读禁区、fcntl 等收尾拒绝；路径一律经 -D 参数传入。本篇拆开这段 SBPL 的生成顺序，以及被拦下之后怎么发现。
- [Linux 沙箱 · bubblewrap 与 Landlock](https://daiw.net/manual/codex-source/linux-sandbox.md): Linux 上的沙箱由 codex 可执行文件以 codex-linux-sandbox 的身份再跑一次来完成：外层把 PermissionProfile 翻译成 bubblewrap 的挂载与命名空间参数，bwrap 里再次进入同一个程序，确认没有残留特权、接好代理桥，装上 no_new_privs 与 seccomp，最后 exec 用户命令。本篇讲清这条两段式流水线、挂载顺序、seccomp 的三种模式、只许连代理时的网络桥，以及 bwrap 从哪里来；Landlock 如今只剩后备代码。
- [Windows 沙箱 · 沙箱用户、ACL 与防火墙](https://daiw.net/manual/codex-source/windows-sandbox.md): Windows 没有现成的“按策略跑命令”工具，Codex 用三种实现拼出沙箱：unelevated 以当前用户的写受限令牌运行，靠能力 SID 与 ACL 限制写入；elevated 先经 UAC 建两个本地沙箱用户、配好 ACL 与防火墙，再以沙箱用户身份启动 codex-command-runner，由它在私有桌面上派生受限令牌跑命令；mxc 则交给系统的进程安全环境。本篇讲清三者的分工与各自的边界。
- [网络代理 · 联网权限怎么落地](https://daiw.net/manual/codex-source/network-proxy.md): 沙箱只能把网络整个打开或整个关掉；codex-network-proxy 补上中间档：会话启动一个本地 HTTP 与 SOCKS5 代理，命令经环境变量被引向它，操作系统沙箱再保证命令只能连到代理端口。代理按“拒绝名单优先、本地地址默认挡、允许名单兜底”裁决，名单外的主机交给内核的审批服务内联询问；需要检查 HTTPS 内容时它自签 CA 做中间人，还能替命令注入真实凭据。
- [执行策略 · Starlark 规则与提权](https://daiw.net/manual/codex-source/execpolicy.md): 规则文件是一段受限的 Starlark 程序，只能调用 prefix_rule、network_rule、host_executable 三个内置函数；解析器边执行边收集规则，按命令首词建索引。匹配是逐词的前缀比较，多条命中取最严格的决定，没命中的交给内置启发式。结果变成审批判定：forbidden 直接拒绝，prompt 弹审批，每一段都被规则明确 allow 才跳过沙箱。在实验性的 zsh-fork 模式下，shell-escalation 还能在每一次 exec 时拦截子命令，按绝对路径重新判定并在沙箱外代为执行。
- [自动审查 · 让另一个模型替你审批](https://daiw.net/manual/codex-source/guardian.md): 把 approvals_reviewer 设为 auto_review 后，原本弹给你的审批请求先交给 guardian：内核把待审动作渲染成 JSON，连同压缩过的对话记录、权限上下文和一份风险策略，交给一个独立的审查线程。审查线程只有只读的命令工具，必须以严格 JSON 回答风险等级、用户授权程度、放行与否和理由；结论折算回审批决定，拒绝理由喂回主模型。连续拒绝会触发熔断中断本轮，开发中的 guardian v2 则尝试用后台打分跳过低风险动作的同步审查。

### 第 5 部分 · 扩展机制

- [配置系统 · 分层加载与托管要求](https://daiw.net/manual/codex-source/config-system.md): Codex 的配置由两摞“层”组成：config 层按优先级逐键合并出生效值，requirements 层合成管理员的约束，再把取值关进 Constrained 校验器。本篇沿 codex-config 的加载器走一遍来源与优先级、-c 覆盖、profile、项目信任、未知字段告警，以及改写 config.toml 的方式。
- [Skills · 发现、选择与注入](https://daiw.net/manual/codex-source/skills.md): 技能从哪些根目录被扫描出来、清单怎样在预算内挤进上下文、显式提及如何解析成要注入的 SKILL.md，以及“自动选用”在 v0.158.0 其实仍由模型自己决定——代码里的检索式选择器只在影子模式下跑实验指标。
- [Hooks · 在关键节点插入你的脚本](https://daiw.net/manual/codex-source/hooks.md): Codex 的 hooks 是一个名为 ClaudeHooksEngine 的引擎：12 个事件、按哈希记账的信任机制、会话 shell 里起进程、stdin 进 JSON、退出码与 stdout 出决定。本篇讲它从哪里收集钩子、怎样匹配和并发执行，以及拦截、改写、续写这些决定如何回到 agent 循环。
- [插件与 marketplace · 打包分发扩展](https://daiw.net/manual/codex-source/plugins.md): 插件把 skills、MCP 服务器、应用连接器和 hooks 装进一个目录，靠 marketplace 分发。本篇拆开 codex-core-plugins：清单的四个位置与两种格式、marketplace 的来源与策略、安装时复制进版本化缓存的流程，以及每个会话如何把启用的插件拆回各个扩展子系统。
- [MCP 客户端 · 传输与 OAuth 登录](https://daiw.net/manual/codex-source/mcp-client-oauth.md): 第 24 篇讲了 MCP 的连接管理与工具目录，这一篇往下一层看 codex-rmcp-client：配置怎样落成 stdio 或可流式 HTTP 两种传输、本地服务器进程怎么起、HTTP 会话过期怎么恢复，以及 codex mcp login 背后的 OAuth 流程、令牌存储和跨进程刷新。对外的 codex mcp-server 在 v0.158.0 里已不存在，代码中只剩 TUI 内部的一个任务工具服务。
- [多 agent · 子代理的派生与协作](https://daiw.net/manual/codex-source/multi-agent.md): Codex 的子代理就是同一个 ThreadManager 里的另一条线程。两代多 agent 工具（V1 按线程 id 寻址，V2 按任务路径寻址）共用一套 AgentControl：子代理从父轮次的实时设置派生，角色只能收窄、不能放宽权限；V1 限深度与打开数，V2 限驻留数并淘汰空闲子代理；V2 的消息与结果都经收件方的信箱投递。
- [扩展 API · goal 与内部扩展点](https://daiw.net/manual/codex-source/extension-api.md): Codex 把 skills、记忆、网页搜索、goal 等功能做成编译进来的“扩展”：codex-extension-api 定义十几种贡献者 trait 和按类型取值的分层存储，宿主把它们装进一个不可变的注册表，内核在一轮的固定时机逐个回调。goal 扩展是完整的例子：线程一空闲就自动开下一轮，直到目标完成、受阻、暂停或预算耗尽。
- [记忆 · 从历史会话里提炼经验](https://daiw.net/manual/codex-source/memories.md): 打开 memories 后，每开一轮新对话，Codex 都会在后台把闲置已久的旧会话分两阶段提炼成 ~/.codex/memories 下的记忆：Phase 1 用一次模型调用把单个会话抽成原始记忆存进 SQLite，Phase 2 由一个锁死权限的整合子代理把它们归并成 MEMORY.md 与 memory_summary.md。之后每个会话把摘要注入开发者指令，模型引用了哪条记忆就给它记一次使用，决定它下次还能不能留下。
- [从别的 agent 迁移 · 导入 Claude Code 与 Cursor 的配置](https://daiw.net/manual/codex-source/external-agent-migration.md): /import 背后是 codex-external-agent-migration：代码里把 Claude Code 叫 cla、Cursor 叫 cur，检测时先在内存里合并一遍、只列出真能带来新东西的项，导入时一律只补不覆盖，并把 CLAUDE.md、设置、MCP、hooks、子代理、命令、会话改写成 Codex 的格式；app-server 负责逐项报告进度，会话与远程插件在后台导入。

### 第 6 部分 · 终端 UI

- [TUI 架构 · 事件、线程路由与渲染](https://daiw.net/manual/codex-source/tui-architecture.md): codex-tui 是整个仓库最大的 crate，却不碰 agent 内核：会话里的每个动作都变成发给 app-server 的 JSON-RPC 请求，服务端的通知再按线程分流回界面。本篇从启动顺序讲起，拆开 App 的事件循环、按线程缓冲的事件通道，以及合并重绘请求、最高 120 帧每秒的帧调度。
- [输入框 · 补全、粘贴与快捷键](https://daiw.net/manual/codex-source/chat-composer.md): 底部输入框是 TUI 里最复杂的状态机：BottomPane 在输入框与弹窗栈之间分派按键，ChatComposer 管补全、粘贴、历史与提交，TextArea 是自己实现的编辑缓冲。本篇看斜杠命令的匹配规则、@ 文件搜索的双线程会话、大段粘贴与无括号粘贴的识别，以及三层优先级、支持双键组合的可配置快捷键。
- [历史记录单元 · 流式 Markdown 与终端排版](https://daiw.net/manual/codex-source/history-cells.md): 对话区里的每一块内容都是一个 HistoryCell，同一份数据按宽度排成主视图、对话记录、原始回滚等几种样子。本篇看单元怎样从“活动单元”走进历史，流式回复怎样按换行定稿、按提交节拍匀速落进回滚而不闪烁，以及 Markdown 表格、仓库自带的终端 Mermaid 渲染器、URL 感知的折行与 diff 着色。
- [全屏对话记录 · 搜索、选择与折叠](https://daiw.net/manual/codex-source/fullscreen-transcript.md): TUI 有两种放历史的方式：把定稿的行写进终端自己的回滚，或者占住备用屏幕、由 Codex 自己滚动。本篇看两种模式怎么在启动时定下来，回滚模式怎样用滚动区域插入历史、改宽度时重建，全屏模式的 TranscriptView 怎样用锚点定位、逐帧有界地搜索、在选择时冻结快照、按工具身份折叠活动，以及更早的历史怎样按页从 app-server 取回。
- [其它界面 · 登录引导、恢复选择、代理总览与用量面板](https://daiw.net/manual/codex-source/tui-surfaces.md): 聊天界面之外，TUI 还有一圈界面：登录引导与目录信任、恢复选择器、代理总览、用量面板、终端宠物、主题与状态栏。它们按挂载方式分成三类：App::run 之前自带事件循环的启动界面，ChatWidget 底部视图栈里的弹窗，以及 App 在备用屏幕上开的覆盖层。本篇逐个点到，重点讲清它们挂在哪、数据从哪来。

### 第 7 部分 · 运行形态与工程

- [exec-server · 在另一台机器上执行](https://daiw.net/manual/codex-source/exec-server.md): Codex 把“想”和“做”拆开：模型调用、上下文与审批留在 app-server 一侧，起进程、读写文件、发 HTTP 请求经 Environment 抽象落到本机或远端的 exec-server。本篇讲 Environment 三件套、exec-server 的 JSON-RPC 协议与断线续接、注册表加 Noise 加密中继的远程模式，以及路径与沙箱怎么跨操作系统。
- [登录与认证 · ChatGPT、API key 与网关](https://daiw.net/manual/codex-source/login-and-auth.md): 认证集中在 codex-login：八种凭据统一成 CodexAuth，由 AuthManager 按固定优先级加载、缓存、刷新。本篇讲浏览器登录的本地回调与 PKCE、设备码怎么复用同一套换码流程、多进程共用 auth.json 时怎样安全刷新令牌、凭据存在文件还是系统钥匙串，以及 Agent Identity、workload identity 与模型网关 OAuth 这几种面向企业的认证。
- [实时语音 · 语音对话的实现](https://daiw.net/manual/codex-source/realtime-voice.md): Codex 的语音模式不是“语音转文字再喂给 agent”，而是两个模型分工：实时语音模型在前台陪你说话，遇到要干的活就交接给后台的 Codex agent，agent 的结果再回到它嘴里说出来。本篇讲交接的数据通路与两种回传方式、三种传输，以及把音频关在 codex-voice-host 子进程里的 WebRTC 实现。
- [遥测与分析 · OpenTelemetry、埋点与反馈](https://daiw.net/manual/codex-source/telemetry.md): Codex 往外送数据的通道有四条：OpenTelemetry 的日志、追踪与指标，从 app-server 协议流量里归纳出的产品分析事件，只在用户执行 /feedback 并同意后才上传的诊断日志，以及只写本地的 rollout trace。本篇逐条讲它们采集什么、发到哪里、默认是否开启、用哪个配置关掉，以及代码里把“内容”和“计数”分开的几道闸。
- [Codex Cloud、代码审查与 worktree](https://daiw.net/manual/codex-source/cloud-and-review.md): 三个功能都以 git 为底座：codex cloud 把云端任务的 diff 用 git apply --3way 落到本地；/review 派出一个受限的一次性子代理，自己跑 git diff 找问题，结果以 JSON 回到主对话；worktree 用 git worktree 给并行的对话各开一份检出。本篇讲它们的数据流、边界约束，以及共用的 codex-git-utils。
- [工程实践 · 测试、构建与发布](https://daiw.net/manual/codex-source/engineering.md): 一次改动从本地到用户手里要过四道关：clippy、参数注释 lint、cargo-deny 与仓库自检脚本把住静态检查；core 集成测试用 wiremock 扮演模型，同一批测试还能换到 Docker 或 Wine 里的远程执行端上再跑一遍；PR 只跑 Bazel 与少量 Cargo 检查，全平台 nextest 留到合并之后；发版由 rust-v 开头的 tag 触发，签名、打包、npm 可信发布与 R2 镜像一路自动完成。

### 第 8 部分 · 收尾

- [复盘 · 对照《从 LLM 到 Coding Agent》](https://daiw.net/manual/codex-source/recap.md): 把《从 LLM 到 Coding Agent》的二十一个概念逐个对上 Codex 的生产实现与本专栏的篇目，列出 Codex 刻意没照教学建议做的几处，再提炼贯穿全书的几条规律：界面与内核之间隔着一层协议，历史只追加，有副作用的动作都走同一个编排器，沙箱与审批各管一件事。最后是教学实现里没有对应物的那一半。
- [横向对比 · Codex 与 Grok Build、OpenCode](https://daiw.net/manual/codex-source/codex-vs-others.md): 把 Codex 和站里另外两本源码解读的对象——Rust 写的 Grok Build、TypeScript 加 Effect 写的 OpenCode——并排比较。三家都让界面只当客户端，但协议各选各的：自定的 app-server v2、开放的 ACP、HTTP；安全上一家给每条命令套沙箱，一家把整个进程关进沙箱，一家不设沙箱；Codex 只说 Responses API，另两家追求提供方中立。关于 Grok Build 与 OpenCode 的说法都出自站内专栏并附链接。
- [读完之后](https://daiw.net/manual/codex-source/whats-next.md): 全书收尾，不讲新代码：按兴趣分出七条重读路线；在自己机器上构建、调试与读测试的入口；Codex 不接受外部代码贡献，想参与要走 issue，动手前该读 docs/contributing.md 与 AGENTS.md；以及几条可以带回你自己 agent 的设计。
