CODING AGENT HARNESS · SOURCE AUDITREPORT 11 / 18
11

OpenAI Codex

安全、可恢复、可观测和多 Agent 控制面最均衡的企业级基座之一。

Rust · Secure Multi-Agent RuntimeApache-2.0main
SOURCE
VERIFIED
Repository
openai/codex
Commit
3418498f01422f5f650ea645d4bd19e05c3a9616
Commit date
2026-07-28T01:17:52Z
Findings
27
Citations
63
Tracked files
5,774
EXECUTIVE READING

先给结论,再进入源码

核心机制

turn 内多 step;不可漂移 snapshot;流式工具 future

上下文

COW 历史;配对/多模态成本;本地压缩自救

安全边界

审批/permission profile 双轴;三平台原生 OS 沙箱

适用建设

企业内研发平台、安全执行、复杂长任务、多 Agent

值得借鉴

  • 权限与能力边界代码化
  • 恢复与审计事实源完整
  • 多 Agent 资源治理成熟

需要警惕

  • 体系庞大、二次开发成本高
  • Responses 协议中心化
  • 配置与 feature surface 复杂

直接带走

  • StepContext 快照
  • 审批与权限双轴
  • Rollout 事实源 + SQLite 镜像
00 · METHOD

研究口径:先锁提交,再沿运行链读代码

README POLICY

README 只用于定位产品入口;实现结论来自 turn/session、model client、context manager、tool registry、sandbox、MCP、agent control、rollout/state 和测试源码。

FACT POLICY

所有结论固定到该提交;明确区分协议兼容、Provider 能力、feature gate、默认配置和操作系统后端。

INFERENCE POLICY

源码未证明的服务端行为不外推;Require/Auto 等策略只按本地选择与变换代码描述,外部组件内部机制标为边界。

L1运行实现
L2接口契约
L3测试证明
L4文档佐证
L5明确推断

本页引用 28 个不同源码/测试文件;证据角色分布:实现 45 · 契约 12 · 配置 3 · 测试 3。代码块是固定提交中的原文截取,长区间仅在中部折叠,首尾行号保持真实。

01 · TECHNICAL MAPS

架构总图与单轮执行链路

两张图均由本页证据账本生成,并通过 Archify showcase 9 项校验(0 error / 0 warning)。图可单独打开、搜索、缩放和追踪关系。

FIGURE 01OpenAI Codex Harness 架构图全屏打开 ↗
FIGURE 02用户输入到工具回写的技术链路全屏打开 ↗
02 · COVERAGE MAP

审计维度与证据等级

架构与 Agent Loop verified L1 / L2 / L3

审计 turn loop、step snapshot、流式采样、重试、mailbox 抢占和停止钩子。

Provider、流式与重试 verified L1 / L2

审计 Responses-only wire API、可配置兼容 Provider、WebSocket/SSE 和认证边界。

上下文、压缩与恢复 verified L1 / L2 / L3

审计 COW history、配对规范化、截断、本地/远端压缩和模型可见 token 估算。

工具、编辑与执行 verified L1 / L2 / L3

审计工具运行时契约、工具规划、并发互斥、apply_patch、unified exec 和动态工具。

权限、审批与沙箱 verified L1 / L2 / L3

审计审批策略、Guardian/用户裁决、权限 profile 与 macOS/Linux/Windows sandbox 后端。

MCP 与连接器 verified L1 / L2 / L3

审计连接复用、OAuth、required server、工具过滤、catalog revision、elicitation 和超时。

指令、Skills、插件与 Hooks verified L1 / L2 / L3

审计 AGENTS.md 层级、skills 预算、plugin 注入和全生命周期 hooks。

子 Agent 与协作 verified L1 / L2 / L3

审计 V2 控制面、fork history、消息/mailbox、wait、完成通知、驻留和执行额度。

持久化与观测 verified L1 / L2 / L3

审计 JSONL rollout、SQLite 镜像、日志/目标/记忆分库、tracing/OTEL 和工具时延。

成熟度与许可证 verified L2 / L3

确认 Apache-2.0、源码规模与测试密度。

01
DIMENSION · ARCHITECTURE-LOOP

架构与 Agent Loop

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

01
L1事实codex-loop-001

每个 turn 由多个 step 组成,step 内共享一次不可漂移的上下文快照

源码事实

run_turn 在采样前处理压缩、skills/plugins、session/input hooks 和待处理输入;随后为一个 step 捕获 StepContext,并用同一视图构造上下文、工具与模型请求。

白话解释

一轮任务可以问模型很多次,但每一次“想一想并行动”的小步都先拍一张现场快照,避免工具清单和提示词在同一步里前后不一致。

对自研 Harness 的含义

配置热更新只能在安全边界生效,换来 prompt cache 和工具调用的确定性。

关键源码 · 实现
codex-rs/core/src/session/turn.rs · L153–L274
  153  pub(crate) async fn run_turn(
  154      sess: Arc<Session>,
  155      turn_context: Arc<TurnContext>,
  156      turn_extension_data: Arc<codex_extension_api::ExtensionData>,
  157      input: Vec<TurnInput>,
  158      prewarmed_client_session: Option<ModelClientSession>,
  159      cancellation_token: CancellationToken,
  160  ) -> CodexResult<Option<String>> {
  161      let mut client_session =
  162          prewarmed_client_session.unwrap_or_else(|| sess.services.model_client.new_session());
  163      // TODO(ccunningham): Pre-turn compaction runs before context updates and the
  164      // new user message are recorded. Estimate pending incoming items (context
  165      // diffs/full reinjection + user input) and trigger compaction preemptively
  166      // when they would push the thread over the compaction threshold.
  167      if let Err(err) = run_pre_sampling_compact(
  168          &sess,
  169          &turn_context,
  170          &mut client_session,
  171          &cancellation_token,
  172      )
  173      .await
  174      {
  175          if matches!(err.details(), CodexErrorDetails::TurnAborted) {
  176              run_hooks_and_record_inputs(&sess, &turn_context, &input).await;
      … 88 lines omitted; exact range 153–274 …
  265              break;
  266          }
  267  
  268          let window_id = sess.current_window_id().await;
  269          super::rollout_budget::maybe_record_reminder(
  270              sess.as_ref(),
  271              turn_context.as_ref(),
  272              &window_id,
  273          )
  274          .await;
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/turn.rs:153–274 turn 初始化、压缩、hooks 与 step context。
  • 实现 codex-rs/core/src/session/turn.rs:275–455 step 循环、待处理输入、压缩和停止控制。
02
L1事实codex-loop-002

流式采样与工具 Future 同时推进,并可被新消息抢占

源码事实

try_run_sampling_request 消费流式 ResponseEvent;完整 tool item 到达后进入 FuturesOrdered,工具参数 diff 可边流边展示;若 commentary/reasoning 期间 mailbox 有消息,则返回 needs_follow_up。

白话解释

模型说到一个完整动作就能开工,不必等整段回答结束;用户中途补充信息时,系统也能在安全位置收住并接新指令。

对自研 Harness 的含义

响应更快,但对调用顺序、取消、配对和幂等要求很高。

关键源码 · 实现
codex-rs/core/src/session/turn.rs · L2034–L2168
 2034      tool_runtime: ToolCallRuntime,
 2035      sess: Arc<Session>,
 2036      turn_context: Arc<TurnContext>,
 2037      turn_store: Arc<codex_extension_api::ExtensionData>,
 2038      client_session: &mut ModelClientSession,
 2039      responses_metadata: &CodexResponsesMetadata,
 2040      turn_diff_tracker: SharedTurnDiffTracker,
 2041      prompt: &Prompt,
 2042      cancellation_token: CancellationToken,
 2043  ) -> CodexResult<SamplingRequestResult> {
 2044      feedback_tags!(
 2045          model = turn_context.model_info.slug.clone(),
 2046          approval_policy = turn_context.approval_policy.value(),
 2047          sandbox_policy = &turn_context.sandbox_policy(),
 2048          effort = turn_context.reasoning_effort,
 2049          auth_mode = sess.services.auth_manager.auth_mode(),
 2050          features = sess.features.enabled_features(),
 2051      );
 2052      let inference_trace = sess.services.rollout_thread_trace.inference_trace_context(
 2053          turn_context.sub_id.as_str(),
 2054          turn_context.model_info.slug.as_str(),
 2055          turn_context.provider.info().name.as_str(),
 2056      );
 2057      let sampling_timing_guard = turn_context.turn_timing_state.begin_sampling();
      … 101 lines omitted; exact range 2034–2168 …
 2159                      flush_assistant_text_segments_for_item(
 2160                          &sess,
 2161                          &turn_context,
 2162                          plan_mode_state.as_mut(),
 2163                          &mut assistant_message_stream_parsers,
 2164                          &item_id,
 2165                      )
 2166                      .await;
 2167                  }
 2168                  if let Some(state) = plan_mode_state.as_mut()
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/turn.rs:2034–2168 流式事件、工具 future 与参数 diff。
  • 实现 codex-rs/core/src/session/turn.rs:2169–2265 mailbox 抢占和 follow-up。
03
L1事实codex-loop-003

重试预算属于 turn-scoped client session,窗口超限不当作普通网络错误重试

源码事实

run_sampling_request 在一个 turn 内复用 ModelClientSession;上下文超限和 usage limit 直接上抛,其他可重试错误才按 Provider 的 stream retry 上限重试。

白话解释

同一轮尽量复用连接和粘性状态;行李箱塞不下不会盲目重拨网络,而是交给压缩逻辑处理。

对自研 Harness 的含义

把语义恢复与传输恢复分开,避免无效重试放大费用。

关键源码 · 实现
codex-rs/core/src/session/turn.rs · L1176–L1273
 1176  async fn run_sampling_request(
 1177      sess: Arc<Session>,
 1178      step_context: Arc<StepContext>,
 1179      turn_store: Arc<codex_extension_api::ExtensionData>,
 1180      turn_diff_tracker: SharedTurnDiffTracker,
 1181      client_session: &mut ModelClientSession,
 1182      responses_metadata: &CodexResponsesMetadata,
 1183      input: Vec<ResponseItem>,
 1184      cancellation_token: CancellationToken,
 1185  ) -> CodexResult<(SamplingRequestResult, Vec<ResponseItem>)> {
 1186      let turn_context = Arc::clone(&step_context.turn);
 1187      let router = Arc::clone(&step_context.tool_router);
 1188  
 1189      let base_instructions = sess.get_base_instructions().await;
 1190  
 1191      let tool_runtime = ToolCallRuntime::new(
 1192          Arc::clone(&router),
 1193          Arc::clone(&sess),
 1194          Arc::clone(&step_context),
 1195          Arc::clone(&turn_diff_tracker),
 1196      );
 1197      let _code_mode_worker = sess.services.code_mode_service.start_turn_worker(
 1198          &sess,
 1199          Arc::clone(&step_context),
      … 64 lines omitted; exact range 1176–1273 …
 1264              err,
 1265              client_session,
 1266              &sess,
 1267              &turn_context,
 1268              ResponsesStreamRequest::Sampling,
 1269          )
 1270          .await?;
 1271          turn_context.turn_timing_state.record_sampling_retry();
 1272      }
 1273  }
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/turn.rs:1176–1273 turn-scoped client session 与错误分类重试。
  • 契约 codex-rs/core/src/client.rs:1–24 ModelClientSession 生命周期、WebSocket 复用与重试预算。
02
DIMENSION · PROVIDER-STREAMING

Provider、流式与重试

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

04
L1事实codex-provider-001

模型协议只保留 Responses API,但 Provider 端点与认证可扩展

源码事实

WireApi 枚举只有 Responses,反序列化 chat 会报迁移错误;ModelProviderInfo 允许自定义 base URL、环境密钥、命令认证、AWS SigV4、headers、query 和重试。

白话解释

它允许换“接线地址和门禁方式”,但要求对方都说 Responses 这门语言;不是任意 Chat Completions 方言翻译器。

对自研 Harness 的含义

兼容面更一致,第三方 Provider 必须实现 Responses 语义而非只暴露 chat/completions。

关键源码 · 契约
codex-rs/model-provider-info/src/lib.rs · L54–L84
   54  /// Wire protocol that the provider speaks.
   55  #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, JsonSchema)]
   56  #[serde(rename_all = "lowercase")]
   57  pub enum WireApi {
   58      /// The Responses API exposed by OpenAI at `/v1/responses`.
   59      #[default]
   60      Responses,
   61  }
   62  
   63  impl fmt::Display for WireApi {
   64      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
   65          let value = match self {
   66              Self::Responses => "responses",
   67          };
   68          f.write_str(value)
   69      }
   70  }
   71  
   72  impl<'de> Deserialize<'de> for WireApi {
   73      fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
   74      where
   75          D: serde::Deserializer<'de>,
   76      {
   77          let value = String::deserialize(deserializer)?;
   78          match value.as_str() {
   79              "responses" => Ok(Self::Responses),
   80              "chat" => Err(serde::de::Error::custom(CHAT_WIRE_API_REMOVED_ERROR)),
   81              _ => Err(serde::de::Error::unknown_variant(&value, &["responses"])),
   82          }
   83      }
   84  }
查看全部 2 处证据
  • 契约 codex-rs/model-provider-info/src/lib.rs:54–84 Responses-only wire API。
  • 配置 codex-rs/model-provider-info/src/lib.rs:86–144 Provider 端点、认证、headers、重试和能力配置。
05
L1事实codex-provider-002

传输层同时支持 SSE 与可复用 WebSocket,并带 turn 粘性状态

源码事实

ModelClientSession 按 turn 创建,延迟缓存 Responses WebSocket 和 x-codex-turn-state;预热是 generate=false 的 v2 response.create,失败后由常规重试/回退处理。

白话解释

每轮对话尽量占用一条可复用的高速通道,还带着本轮路由票据;热身失败不会把整轮任务判死。

对自研 Harness 的含义

交互延迟低,但 Provider 必须准确声明 WebSocket 能力,AWS 认证当前明确不能与 WebSocket 同开。

关键源码 · 契约
codex-rs/core/src/client.rs · L1–L24
    1  //! Session- and turn-scoped helpers for talking to model provider APIs.
    2  //!
    3  //! `ModelClient` is intended to live for the lifetime of a Codex session and holds the stable
    4  //! configuration and state needed to talk to a provider (auth, provider selection, conversation id,
    5  //! and transport fallback state).
    6  //!
    7  //! Per-turn settings (model selection, reasoning controls, telemetry context, and turn metadata)
    8  //! are passed explicitly to streaming and unary methods so that the turn lifetime is visible at the
    9  //! call site.
   10  //!
   11  //! A [`ModelClientSession`] is created per turn and is used to stream one or more Responses API
   12  //! requests during that turn. It caches a Responses WebSocket connection (opened lazily) and stores
   13  //! per-turn state such as the `x-codex-turn-state` token used for sticky routing.
   14  //!
   15  //! WebSocket prewarm is a v2-only `response.create` with `generate=false`; it waits for completion
   16  //! so the next request can reuse the same connection and `previous_response_id`.
   17  //!
   18  //! Turn execution performs prewarm as a best-effort step before the first stream request so the
   19  //! subsequent request can reuse the same connection.
   20  //!
   21  //! ## Retry-Budget Tradeoff
   22  //!
   23  //! WebSocket prewarm is treated as the first websocket connection attempt for a turn. If it
   24  //! fails, normal stream retry/fallback logic handles recovery on the same turn.
查看全部 2 处证据
  • 契约 codex-rs/core/src/client.rs:1–24 turn-scoped WebSocket、预热与 fallback。
  • 实现 codex-rs/model-provider-info/src/lib.rs:156–186 AWS 与 WebSocket/auth 冲突校验。
03
DIMENSION · CONTEXT-COMPACTION

上下文、压缩与恢复

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

06
L1事实codex-context-001

历史是带版本号的 Copy-on-Write 账本,不是随手拼接的消息数组

源码事实

ContextManager 用 Arc<Vec<ResponseItem>> 保存历史并维护 history_version、token info、reference context 和 world-state baseline;写入前过滤非 API item、截断并在取 prompt 时规范化。

白话解释

像有版本号的账本:读取者共享同一份快照,真要改时才复制,且每笔工具调用都要能对上回执。

对自研 Harness 的含义

适合并发读取和回滚,也让 compaction、fork 与增量世界状态有明确一致性边界。

关键源码 · 实现
codex-rs/core/src/context_manager/history.rs · L38–L60
   38  /// Transcript of thread history
   39  #[derive(Debug, Clone, Default)]
   40  pub(crate) struct ContextManager {
   41      /// The oldest items are at the beginning of the vector. Snapshots share the vector until a
   42      /// caller needs to mutate it, avoiding deep copies for read-only history consumers.
   43      items: Arc<Vec<ResponseItem>>,
   44      /// Bumped whenever history is rewritten, such as compaction or rollback.
   45      history_version: u64,
   46      token_info: Option<TokenUsageInfo>,
   47      /// Reference context snapshot used for diffing and producing model-visible
   48      /// settings update items.
   49      ///
   50      /// This is the baseline for the next regular model turn, and may already
   51      /// match the current turn after context updates are persisted.
   52      ///
   53      /// When this is `None`, settings diffing treats the next turn as having no
   54      /// baseline and emits a full reinjection of context state. Rollback may
   55      /// also clear this when it trims a mixed initial-context developer bundle
   56      /// whose non-diff fragments no longer exist in the surviving history.
   57      reference_context_item: Option<TurnContextItem>,
   58      /// World state most recently appended to model-visible history.
   59      world_state_baseline: Option<WorldStateSnapshot>,
   60  }
查看全部 2 处证据
  • 实现 codex-rs/core/src/context_manager/history.rs:38–60 COW history 与版本/状态字段。
  • 实现 codex-rs/core/src/context_manager/history.rs:123–146 record、truncate 与 normalize。
07
L1事实codex-context-002

上下文裁剪同时维护工具调用配对并计算多模态成本

源码事实

remove_oldest_item 会同步移除对应 call/output 并清 world baseline;normalize 修复配对并过滤不支持的图像/音频,token 估算覆盖 reasoning、compaction、图像、音频和 encrypted content。

白话解释

剪历史不能只撕掉一页:工具问题和答案必须一起处理;图片、音频和加密内容也不能当作零体积。

对自研 Harness 的含义

上下文预算比纯文本字符计数可靠,降低 Provider 因协议不完整而拒绝请求的概率。

关键源码 · 实现
codex-rs/core/src/context_manager/history.rs · L189–L248
  189      pub(crate) fn remove_first_item(&mut self) {
  190          if !self.items.is_empty() {
  191              // Remove the oldest item (front of the list). Items are ordered from
  192              // oldest → newest, so index 0 is the first entry recorded.
  193              let items = Arc::make_mut(&mut self.items);
  194              let removed = items.remove(0);
  195              // If the removed item participates in a call/output pair, also remove
  196              // its corresponding counterpart to keep the invariants intact without
  197              // running a full normalization pass.
  198              normalize::remove_corresponding_for(items, &removed);
  199              self.world_state_baseline = None;
  200          }
  201      }
  202  
  203      pub(crate) fn replace(&mut self, items: Vec<ResponseItem>) {
  204          self.items = Arc::new(items);
  205          self.history_version = self.history_version.saturating_add(1);
  206          self.world_state_baseline = None;
  207      }
  208  
  209      /// Drop the last `num_turns` instruction turns from this history.
  210      ///
  211      /// Instruction turns are history messages that should behave like a new prompt boundary:
  212      /// ordinary user messages and structured assistant inter-agent instructions.
      … 26 lines omitted; exact range 189–248 …
  239              first_instruction_turn_idx
  240          } else {
  241              user_positions[user_positions.len() - n_from_end]
  242          };
  243  
  244          cut_idx =
  245              self.trim_pre_turn_context_updates(&snapshot, first_instruction_turn_idx, cut_idx);
  246  
  247          self.replace(snapshot[..cut_idx].to_vec());
  248      }
查看全部 3 处证据
  • 实现 codex-rs/core/src/context_manager/history.rs:189–248 成对删除、替换和回滚。
  • 实现 codex-rs/core/src/context_manager/history.rs:295–386 usage、normalize 与工具输出截断。
  • 实现 codex-rs/core/src/context_manager/history.rs:493–558 模型可见 token 估算。
08
L1事实codex-context-003

本地压缩会自救:压缩请求自身超限时逐项删旧记录再重试

源码事实

compact 使用模型生成摘要;若压缩调用本身超出窗口,就删除最老 item 及其配对继续尝试,成功后保留真实 user 消息、插入摘要前缀、推进窗口并重算 usage。

白话解释

连“请帮我整理行李”这句话都塞不进去时,它会先扔掉最旧且成对的票据,直到能完成整理。

对自研 Harness 的含义

长会话更耐用;源码也明确提示多次摘要会逐步降低准确性。

关键源码 · 实现
codex-rs/core/src/compact.rs · L240–L318
  240  async fn run_compact_task_inner_impl(
  241      sess: Arc<Session>,
  242      turn_context: Arc<TurnContext>,
  243      input: Vec<UserInput>,
  244      initial_context_injection: InitialContextInjection,
  245      compaction_metadata: CompactionTurnMetadata,
  246  ) -> CodexResult<String> {
  247      let compaction_item = TurnItem::ContextCompaction(ContextCompactionItem::new());
  248      sess.emit_turn_item_started(&turn_context, &compaction_item)
  249          .await;
  250      let initial_input_for_turn: ResponseInputItem = ResponseInputItem::from(input);
  251  
  252      let mut history = sess.clone_history().await;
  253      history.record_items(
  254          &[initial_input_for_turn.into()],
  255          turn_context.model_info.truncation_policy.into(),
  256      );
  257  
  258      let max_retries = turn_context.provider.info().stream_max_retries();
  259      let mut retries = 0;
  260      let mut client_session = sess.services.model_client.new_session();
  261      // Reuse one client session so turn-scoped state (sticky routing, websocket incremental
  262      // request tracking)
  263      // survives retries within this compact turn.
      … 45 lines omitted; exact range 240–318 …
  309              Err(e) if matches!(e.details(), CodexErrorDetails::ContextWindowExceeded) => {
  310                  if turn_input_len > 1 {
  311                      // Trim from the beginning to preserve cache (prefix-based) and keep recent messages intact.
  312                      error!(
  313                          "Context window exceeded while compacting; removing oldest history item. Error: {e}"
  314                      );
  315                      history.remove_first_item();
  316                      retries = 0;
  317                      continue;
  318                  }
查看全部 2 处证据
  • 实现 codex-rs/core/src/compact.rs:240–318 compact overflow 自救与重试。
  • 实现 codex-rs/core/src/compact.rs:319–392 摘要替换、窗口推进和准确性警告。
04
DIMENSION · TOOLS-EDITING

工具、编辑与执行

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

09
L1事实codex-tools-001

工具有统一 typed runtime 契约,hooks、观测和流式参数 diff 都是一级能力

源码事实

CoreToolRuntime 扩展 ToolExecutor,统一声明 payload 匹配、取消清理、telemetry tags、pre/post hook payload、hook 输入改写和参数 diff consumer。

白话解释

每个新工具不只是写一个 execute 函数,还要说明如何取消、怎么记日志、钩子看什么、参数流到一半时如何展示。

对自研 Harness 的含义

扩展成本高于轻量 Agent,但跨工具的安全和观测语义更一致。

关键源码 · 契约
codex-rs/core/src/tools/registry.rs · L48–L149
   48  /// Typed runtime contract for locally executed tools.
   49  ///
   50  /// Implementers provide the shared `ToolExecutor` behavior plus optional
   51  /// core-owned metadata for hooks, telemetry, tool search, and argument diffs.
   52  pub(crate) trait CoreToolRuntime: ToolExecutor<ToolInvocation> {
   53      fn matches_kind(&self, payload: &ToolPayload) -> bool {
   54          matches!(
   55              payload,
   56              ToolPayload::Function { .. } | ToolPayload::ToolSearch { .. }
   57          )
   58      }
   59  
   60      /// Whether cancellation should let the handler finish teardown before the
   61      /// host returns an aborted tool response.
   62      fn waits_for_runtime_cancellation(&self) -> bool {
   63          false
   64      }
   65  
   66      fn telemetry_tags<'a>(
   67          &'a self,
   68          _invocation: &'a ToolInvocation,
   69      ) -> BoxFuture<'a, ToolTelemetryTags> {
   70          Box::pin(async { Vec::new() })
   71      }
      … 68 lines omitted; exact range 48–149 …
  140              payload: ToolPayload::Function { arguments },
  141              ..invocation
  142          })
  143      }
  144  
  145      /// Creates an optional consumer for streamed tool argument diffs.
  146      fn create_diff_consumer(&self) -> Option<Box<dyn ToolArgumentDiffConsumer>> {
  147          None
  148      }
  149  }
查看全部 2 处证据
  • 契约 codex-rs/core/src/tools/registry.rs:48–149 CoreToolRuntime 完整契约。
  • 契约 codex-rs/core/src/tools/registry.rs:151–188 参数 diff 与统一结果。
10
L1事实codex-tools-002

并发工具用读写锁实现“并行组 + 全局排他工具”

源码事实

ToolCallRuntime 对支持并发的 handler 取读锁,不支持并发的取写锁;取消时按 handler 语义等待清理或 abort,并输出结构化 aborted result 与分段时延。

白话解释

能并行的工具像多人同时读资料;危险或有状态的工具拿独占钥匙,等所有并行动作结束后自己运行。

对自研 Harness 的含义

不是简单 Promise.all,避免非并行工具与其他调用交叉污染环境。

关键源码 · 实现
codex-rs/core/src/tools/parallel.rs · L74–L145
   74      #[instrument(level = "trace", skip_all)]
   75      pub(crate) fn handle_tool_call(
   76          self,
   77          call: ToolCall,
   78          cancellation_token: CancellationToken,
   79      ) -> impl std::future::Future<Output = Result<ResponseInputItem, CodexErr>> {
   80          let error_call = call.clone();
   81          let future =
   82              self.handle_tool_call_with_source(call, ToolCallSource::Direct, cancellation_token);
   83          async move {
   84              match future.await {
   85                  Ok(response) => Ok(response.into_response()),
   86                  Err(FunctionCallError::Fatal(message)) => Err(CodexErr::Fatal(message)),
   87                  Err(other) => Ok(Self::failure_response(error_call, other)),
   88              }
   89          }
   90          .in_current_span()
   91      }
   92  
   93      #[instrument(level = "trace", skip_all)]
   94      pub(crate) fn handle_tool_call_with_source(
   95          self,
   96          call: ToolCall,
   97          source: ToolCallSource,
      … 38 lines omitted; exact range 74–145 …
  136                      Either::Right(lock.write().await)
  137                  };
  138                  // Admission through the parallel-execution gate marks the end
  139                  // of dispatch waiting and the start of handler execution.
  140                  if let Some(execution_started_at) = execution_started_at {
  141                      let _ = execution_started_at.set(Instant::now());
  142                  }
  143  
  144                  router
  145                      .dispatch_tool_call_with_terminal_outcome(
查看全部 2 处证据
  • 实现 codex-rs/core/src/tools/parallel.rs:74–145 读写锁并发策略。
  • 实现 codex-rs/core/src/tools/parallel.rs:146–202 取消与 timing 记录。
11
L3事实codex-tools-003

工具暴露与分发分离,兼容旧 shell 又不污染模型可见清单

源码事实

工具规划测试确认 unified exec 可把 exec_command/write_stdin 暴露给模型,同时保留隐藏的 legacy shell_command 仅供分发;apply_patch、web search 和动态工具也按环境、模型及 Provider capability gate。

白话解释

后台可以保留旧插座做兼容,但模型眼前只摆当前应该用的工具,避免同功能多把扳手。

对自研 Harness 的含义

迁移期兼容性强,且 prompt tool schema 保持紧凑稳定。

关键源码 · 测试
codex-rs/core/src/tools/spec_plan_tests.rs · L637–L708
  637  async fn shell_family_registers_visible_unified_exec_and_hidden_legacy_shell() {
  638      let plan = probe(|turn| {
  639          set_features(turn, &[Feature::ShellTool, Feature::UnifiedExec]);
  640          set_feature(turn, Feature::ShellZshFork, /*enabled*/ false);
  641          turn.model_info.shell_type = ConfigShellToolType::ShellCommand;
  642      })
  643      .await;
  644  
  645      plan.assert_visible_contains(&["exec_command", "write_stdin"]);
  646      plan.assert_visible_lacks(&["shell_command"]);
  647      plan.assert_registered_contains(&["exec_command", "write_stdin", "shell_command"]);
  648      assert_eq!(plan.exposure("shell_command"), ToolExposure::Hidden);
  649      assert!(has_parameter(plan.visible_spec("exec_command"), "shell"));
  650  }
  651  
  652  #[tokio::test]
  653  async fn shell_zsh_fork_stays_standalone_until_unified_exec_composition_is_enabled() {
  654      let standalone = probe(|turn| {
  655          set_features(turn, &[Feature::ShellTool, Feature::UnifiedExec]);
  656          set_feature(turn, Feature::ShellZshFork, /*enabled*/ true);
  657          set_feature(turn, Feature::UnifiedExecZshFork, /*enabled*/ false);
  658          turn.model_info.shell_type = ConfigShellToolType::ShellCommand;
  659      })
  660      .await;
      … 38 lines omitted; exact range 637–708 …
  699          set_features(
  700              turn,
  701              &[
  702                  Feature::ShellTool,
  703                  Feature::UnifiedExec,
  704                  Feature::ShellZshFork,
  705                  Feature::UnifiedExecZshFork,
  706              ],
  707          );
  708          turn.unified_exec_shell_mode =
查看全部 3 处证据
  • 测试 codex-rs/core/src/tools/spec_plan_tests.rs:637–708 unified exec 与隐藏 legacy shell。
  • 实现 codex-rs/core/src/tools/spec_plan.rs:310–328 web search capability gate。
  • 实现 codex-rs/core/src/tools/spec_plan.rs:917–936 动态工具与 namespace handler。
05
DIMENSION · PERMISSIONS-SANDBOX

权限、审批与沙箱

本章共 4 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

12
L2事实codex-permission-001

审批策略把“何时问”与“允许做什么”分成两条轴

源码事实

AskForApproval 有 UnlessTrusted、OnRequest、Granular 和 Never;SandboxPolicy 独立描述 DangerFullAccess、ReadOnly、ExternalSandbox 与 WorkspaceWrite。

白话解释

一条轴决定要不要敲门,另一条轴决定进门后活动范围;“不用问”不等于“拥有整台机器”。

对自研 Harness 的含义

企业策略能单独收紧提权频率与文件/网络能力。

关键源码 · 契约
codex-rs/protocol/src/protocol.rs · L890–L932
  890  /// Determines the conditions under which the user is consulted to approve
  891  /// running the command proposed by Codex.
  892  #[derive(
  893      Debug,
  894      Clone,
  895      Copy,
  896      Default,
  897      PartialEq,
  898      Eq,
  899      Hash,
  900      Serialize,
  901      Deserialize,
  902      Display,
  903      JsonSchema,
  904      TS,
  905  )]
  906  #[serde(rename_all = "kebab-case")]
  907  #[strum(serialize_all = "kebab-case")]
  908  pub enum AskForApproval {
  909      /// Under this policy, only "known safe" commands—as determined by
  910      /// `is_safe_command()`—that **only read files** are auto‑approved.
  911      /// Everything else will ask the user to approve.
  912      #[serde(rename = "untrusted")]
  913      #[strum(serialize = "untrusted")]
      … 9 lines omitted; exact range 890–932 …
  923      /// When a field is `true`, commands in that category are allowed. When it
  924      /// is `false`, those requests are automatically rejected instead of shown
  925      /// to the user.
  926      #[strum(serialize = "granular")]
  927      Granular(GranularApprovalConfig),
  928  
  929      /// Never ask the user to approve commands. Failures are immediately returned
  930      /// to the model, and never escalated to the user for approval.
  931      Never,
  932  }
查看全部 2 处证据
  • 契约 codex-rs/protocol/src/protocol.rs:890–932 审批策略枚举。
  • 契约 codex-rs/protocol/src/protocol.rs:995–1043 legacy sandbox policy 枚举。
13
L1事实codex-permission-002

审批缺失默认中止,且可授予一次、本会话或规则/网络修订

源码事实

命令审批包含 command、cwd、reason、network amendment、execpolicy amendment、additional permissions 和 plugin provenance;等待通道消失时默认 Abort。ReviewDecision 支持单次、session、execpolicy/network amendment、拒绝、超时和 abort。

白话解释

授权不是一个“永远允许”按钮;可以只放这次、放本会话、或把精确规则写进政策,没人回答则停下。

对自研 Harness 的含义

失败关闭且授权可结构化沉淀,适合审计。

关键源码 · 实现
codex-rs/core/src/session/mod.rs · L2295–L2376
 2295      pub async fn request_command_approval(
 2296          &self,
 2297          turn_context: &TurnContext,
 2298          call_id: String,
 2299          approval_id: Option<String>,
 2300          environment_id: Option<String>,
 2301          command: Vec<String>,
 2302          cwd: AbsolutePathBuf,
 2303          reason: Option<String>,
 2304          network_approval_context: Option<NetworkApprovalContext>,
 2305          proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
 2306          additional_permissions: Option<AdditionalPermissionProfile>,
 2307          available_decisions: Option<Vec<ReviewDecision>>,
 2308          plugin_attribution_override: Option<PluginCommandAttribution>,
 2309      ) -> ReviewDecision {
 2310          let _elicitation = self.services.elicitations.register();
 2311          //  command-level approvals use `call_id`.
 2312          // `approval_id` is only present for subcommand callbacks (execve intercept)
 2313          let effective_approval_id = approval_id.clone().unwrap_or_else(|| call_id.clone());
 2314          // Add the tx_approve callback to the map before sending the request.
 2315          let (tx_approve, rx_approve) = oneshot::channel();
 2316          let prev_entry = {
 2317              let mut active = self.active_turn.lock().await;
 2318              match active.as_mut() {
      … 48 lines omitted; exact range 2295–2376 …
 2367              reason,
 2368              network_approval_context,
 2369              proposed_execpolicy_amendment,
 2370              proposed_network_policy_amendments,
 2371              additional_permissions,
 2372              available_decisions: Some(available_decisions),
 2373              parsed_cmd,
 2374          });
 2375          self.send_event(turn_context, event).await;
 2376          rx_approve.await.unwrap_or(ReviewDecision::Abort)
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/mod.rs:2295–2376 命令审批请求与默认 Abort。
  • 契约 codex-rs/protocol/src/protocol.rs:4094–4135 ReviewDecision 完整类型。
14
L1事实codex-sandbox-001

沙箱按平台变换真实进程:macOS Seatbelt、Linux seccomp/bwrap/landlock、Windows restricted token

源码事实

SandboxManager 将抽象策略映射到平台后端;Auto 只在策略要求时选沙箱,Require/Forbid 明确覆盖选择,随后把命令变换为对应 launcher。

白话解释

不是在提示词里说“请别乱动”,而是在启动进程前给命令套上操作系统能执行的限制器。

对自研 Harness 的含义

强度取决于平台与后端可用性;报告不把 unsupported 平台推断成同等隔离。

关键源码 · 实现
codex-rs/sandboxing/src/manager.rs · L34–L73
   34  #[derive(Clone, Copy, Debug, PartialEq, Eq)]
   35  pub enum SandboxType {
   36      None,
   37      MacosSeatbelt,
   38      LinuxSeccomp,
   39      WindowsRestrictedToken,
   40  }
   41  
   42  impl SandboxType {
   43      pub fn as_metric_tag(self) -> &'static str {
   44          match self {
   45              SandboxType::None => "none",
   46              SandboxType::MacosSeatbelt => "seatbelt",
   47              SandboxType::LinuxSeccomp => "seccomp",
   48              SandboxType::WindowsRestrictedToken => "windows_sandbox",
   49          }
   50      }
   51  }
   52  
   53  #[derive(Clone, Copy, Debug, PartialEq, Eq)]
   54  pub enum SandboxablePreference {
   55      Auto,
   56      Require,
   57      Forbid,
      … 6 lines omitted; exact range 34–73 …
   64          Some(SandboxType::LinuxSeccomp)
   65      } else if cfg!(target_os = "windows") {
   66          if windows_sandbox_enabled {
   67              Some(SandboxType::WindowsRestrictedToken)
   68          } else {
   69              None
   70          }
   71      } else {
   72          None
   73      }
查看全部 2 处证据
  • 实现 codex-rs/sandboxing/src/manager.rs:34–73 平台 sandbox 类型映射。
  • 实现 codex-rs/sandboxing/src/manager.rs:280–367 Auto/Require/Forbid 选择与命令变换。
15
L1事实codex-sandbox-002

自定义 permission profile 默认从受限文件系统和受限网络开始

源码事实

custom profile 编译器先建立 restricted filesystem 与 restricted network,再应用条目;网络只有显式 true 才启用,WorkspaceWrite 默认也关闭网络,并保护 .git hooks 等元数据子路径。

白话解释

自定义政策从“什么都别给”开始逐项开门,而不是先全开再查漏补缺。

对自研 Harness 的含义

默认拒绝更适合作为组织级安全基线。

关键源码 · 配置
codex-rs/core/src/config/permissions.rs · L203–L213
  203  fn extensible_builtin_parent_profile(profile_name: &str) -> Option<PermissionProfileToml> {
  204      let file_system = match profile_name {
  205          BUILT_IN_READ_ONLY_PROFILE => FileSystemSandboxPolicy::read_only(),
  206          BUILT_IN_WORKSPACE_PROFILE => FileSystemSandboxPolicy::workspace_write(
  207              &[],
  208              /*exclude_tmpdir_env_var*/ false,
  209              /*exclude_slash_tmp*/ false,
  210          ),
  211          _ => return None,
  212      };
  213      Some(permission_profile_toml_from_file_system_policy(file_system))
查看全部 3 处证据
  • 配置 codex-rs/core/src/config/permissions.rs:203–213 内建 read-only/workspace profile。
  • 实现 codex-rs/core/src/config/permissions.rs:347–407 自定义 profile 编译与 glob 警告。
  • 实现 codex-rs/core/src/config/permissions.rs:507–520 网络显式开启。
06
DIMENSION · MCP-CONNECTORS

MCP 与连接器

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

16
L1事实codex-mcp-001

MCP 是带复用、认证、required gate 和 catalog revision 的运行时

源码事实

McpConnectionSet 同时管理 server、required servers、工具目录版本、Codex Apps cache、plugin provenance、工具命名前缀和 elicitation;连接配置/OAuth 凭据一致且存活时才复用。

白话解释

它不是每轮临时扫一遍外接工具,而是维护一套有版本、有健康状态、有认证身份的连接池。

对自研 Harness 的含义

工具清单可稳定捕获到 step snapshot,连接变化不会悄悄污染正在执行的一步。

关键源码 · 实现
codex-rs/codex-mcp/src/connection_manager.rs · L66–L117
   66  pub(crate) struct McpServerConnection {
   67      identity: Option<McpServerConnectionIdentity>,
   68      client: AsyncManagedClient,
   69  }
   70  
   71  impl McpServerConnection {
   72      async fn reusable_client(
   73          &self,
   74          desired: &McpServerConnectionIdentity,
   75      ) -> Option<ManagedClient> {
   76          let current = self.identity.as_ref()?;
   77          if !current.has_same_connection_config(desired) {
   78              return None;
   79          }
   80          if !self.client.startup_complete.load(Ordering::Acquire) {
   81              return None;
   82          }
   83          let client = self.client.client().await.ok()?;
   84          if client.client.is_closed().await {
   85              return None;
   86          }
   87          let Ok(desired_credentials) = desired.oauth_credentials() else {
   88              return Some(client);
   89          };
      … 18 lines omitted; exact range 66–117 …
  108          if !self.client.startup_complete.load(Ordering::Acquire) {
  109              self.client.cancel_token.cancel();
  110          }
  111      }
  112  }
  113  
  114  impl Drop for McpServerConnection {
  115      fn drop(&mut self) {
  116          self.client.cancel_token.cancel();
  117      }
查看全部 2 处证据
  • 实现 codex-rs/codex-mcp/src/connection_manager.rs:66–117 连接复用、OAuth 一致性和取消。
  • 实现 codex-rs/codex-mcp/src/connection_manager.rs:143–199 连接集状态、required server 与 catalog revision。
17
L1事实codex-mcp-002

模型只能看到显式可见且能绑定到同一目录版本的 MCP 工具

源码事实

tool_catalog 过滤 UI visibility,不含 metadata 时默认可见;capture_binding 在读锁下捕获 revision、ready client、过滤后的 tools 和 prepared calls,无法精确绑定的工具被省略。

白话解释

展示给模型的工具名和真正执行它的连接必须来自同一版目录,不能拿新版菜单去点旧版厨房。

对自研 Harness 的含义

减少热刷新导致的工具错配和 TOCTOU 风险。

关键源码 · 实现
codex-rs/codex-mcp/src/connection_manager/tool_catalog.rs · L34–L55
   34  /// Returns whether a tool may be included in model-facing tool declarations.
   35  ///
   36  /// Tools without visibility metadata remain visible. Tools with visibility
   37  /// metadata are hidden unless they explicitly include `model`.
   38  ///
   39  /// <https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/2026-01-26/apps.mdx#resource-discovery>
   40  pub fn tool_is_model_visible(tool: &ToolInfo) -> bool {
   41      let Some(visibility) = tool
   42          .tool
   43          .meta
   44          .as_deref()
   45          .and_then(|meta| meta.get(MCP_UI_META_KEY))
   46          .and_then(serde_json::Value::as_object)
   47          .and_then(|ui| ui.get(MCP_UI_VISIBILITY_META_KEY))
   48          .and_then(serde_json::Value::as_array)
   49      else {
   50          return true;
   51      };
   52      visibility
   53          .iter()
   54          .any(|target| target.as_str() == Some(MCP_UI_MODEL_VISIBILITY))
   55  }
查看全部 2 处证据
  • 实现 codex-rs/codex-mcp/src/connection_manager/tool_catalog.rs:34–55 model visibility 规则。
  • 实现 codex-rs/codex-mcp/src/connection_manager/tool_catalog.rs:127–230 revision 锁、ready client 与 prepared call 绑定。
07
DIMENSION · INSTRUCTIONS-SKILLS-PLUGINS-HOOKS

指令、Skills、插件与 Hooks

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

18
L1事实codex-instructions-001

AGENTS.md 从项目根向 cwd 分层合并,局部 override 优先且有总字节预算

源码事实

发现逻辑以 project root marker 截断上行范围,从根到 cwd 每层最多选 AGENTS.override.md、AGENTS.md 或 fallback 文件之一;按总预算读取,超出部分截断。

白话解释

公司规章先读,走进子目录后再叠加本地规章;同一层的 override 像贴在门上的最新通知。

对自研 Harness 的含义

目录作用域明确,但超预算时越靠后的深层说明更可能被截断,需要可视化告警。

关键源码 · 契约
codex-rs/core/src/agents_md.rs · L1–L16
    1  //! AGENTS.md discovery and user instruction assembly.
    2  //!
    3  //! Project-level documentation is primarily stored in files named `AGENTS.md`.
    4  //! Additional fallback filenames can be configured via `project_doc_fallback_filenames`.
    5  //! We include the concatenation of all files found along the path from the
    6  //! project root to the current working directory as follows:
    7  //!
    8  //! 1.  Determine the project root by walking upwards from the current working
    9  //!     directory until a configured `project_root_markers` entry is found.
   10  //!     When `project_root_markers` is unset, the default marker list is used
   11  //!     (`.git`). If no marker is found, only the current working directory is
   12  //!     considered. An empty marker list disables parent traversal.
   13  //! 2.  Collect every `AGENTS.md` found from the project root down to the
   14  //!     current working directory (inclusive) and concatenate their contents in
   15  //!     that order.
   16  //! 3.  We do **not** walk past the project root.
查看全部 3 处证据
  • 契约 codex-rs/core/src/agents_md.rs:1–16 根到 cwd 的发现语义。
  • 实现 codex-rs/core/src/agents_md.rs:89–150 总字节预算与截断。
  • 实现 codex-rs/core/src/agents_md.rs:207–247 候选文件优先级。
19
L1事实codex-extension-001

Skills、plugins 和 extensions 都在初始上下文构建期受预算与来源控制

源码事实

build_initial_context 按 context window 计算 skill metadata budget,超限发 warning;plugins 先按配置加载,再生成推荐插件上下文;extension contributors 可注入 developer、contextual user 或独立 developer fragment。

白话解释

扩展不是把所有说明一股脑塞进提示词,而是先做预算,再按可信来源和消息层级装配。

对自研 Harness 的含义

可扩展性强且照顾 prompt cache;插件推荐与已安装插件被区分。

关键源码 · 实现
codex-rs/core/src/session/mod.rs · L3336–L3397
 3336      pub(crate) async fn build_initial_context_with_world_state(
 3337          &self,
 3338          turn_context: &TurnContext,
 3339          world_state: &WorldState,
 3340      ) -> Vec<ResponseItem> {
 3341          let mut developer_sections = Vec::<String>::with_capacity(8);
 3342          let mut contextual_user_sections = Vec::<String>::with_capacity(2);
 3343          let mut separate_developer_sections = Vec::<String>::new();
 3344          let (session_source, auto_compact_window_ids) = {
 3345              let state = self.state.lock().await;
 3346              (
 3347                  state.session_configuration.session_source.clone(),
 3348                  state.auto_compact_window_ids(),
 3349              )
 3350          };
 3351          let separate_guardian_developer_message =
 3352              crate::guardian::is_guardian_reviewer_source(&session_source);
 3353          // Keep the guardian policy prompt out of the aggregated developer bundle so it
 3354          // stays isolated as its own top-level developer message for guardian subagents.
 3355          if !separate_guardian_developer_message
 3356              && let Some(developer_instructions) = turn_context.developer_instructions.as_deref()
 3357              && !developer_instructions.is_empty()
 3358          {
 3359              developer_sections.push(developer_instructions.to_string());
      … 28 lines omitted; exact range 3336–3397 …
 3388                              message: warning_message,
 3389                          }),
 3390                      })
 3391                      .await;
 3392                  }
 3393                  if !host_catalog_in_world_state {
 3394                      developer_sections.push(skills_instructions.render());
 3395                  }
 3396              }
 3397          }
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/mod.rs:3336–3397 skills 预算、warning 和 developer 注入。
  • 实现 codex-rs/core/src/session/mod.rs:3398–3440 plugins 推荐与 extension contributors。
20
L1事实codex-hooks-001

Hooks 覆盖 session、prompt、permission、tool、compact、stop 与 subagent 生命周期

源码事实

runtime 为 session/subagent start、PreToolUse、PermissionRequest、PostToolUse、UserPromptSubmit 等构造稳定 payload;hook 可阻断、改写输入或注入额外上下文,完成事件同时进入指标和 analytics。

白话解释

钩子既能当门卫,也能当翻译器和旁路记录员;每次执行都有开始、结束和耗时记录。

对自研 Harness 的含义

组织可插入治理逻辑,但 hook 本身应被当作有权限的代码并受项目信任策略保护。

关键源码 · 实现
codex-rs/core/src/hook_runtime.rs · L103–L220
  103  pub(crate) async fn run_pending_session_start_hooks(
  104      sess: &Arc<Session>,
  105      turn_context: &Arc<TurnContext>,
  106  ) -> bool {
  107      while let Some(session_start_source) = sess.take_pending_session_start_source().await {
  108          // Pending session-start hooks are reused to dispatch thread-spawn subagent
  109          // starts. Other subagent sessions are internal/system work and do not run
  110          // start hooks.
  111          let target = match &turn_context.session_source {
  112              SessionSource::SubAgent(SubAgentSource::ThreadSpawn { agent_role, .. })
  113                  if matches!(
  114                      session_start_source,
  115                      codex_hooks::SessionStartSource::Startup
  116                  ) =>
  117              {
  118                  let context = subagent_hook_context(sess, agent_role);
  119                  StartHookTarget::SubagentStart {
  120                      turn_id: turn_context.sub_id.clone(),
  121                      agent_id: context.agent_id,
  122                      agent_type: context.agent_type,
  123                  }
  124              }
  125              SessionSource::SubAgent(_) => return false,
  126              _ => StartHookTarget::SessionStart {
      … 84 lines omitted; exact range 103–220 …
  211          PreToolUseHookResult::Blocked(format!(
  212              "Command blocked by PreToolUse hook: {reason}. Command: {command}"
  213          ))
  214      } else {
  215          PreToolUseHookResult::Blocked(format!(
  216              "Tool call blocked by PreToolUse hook: {reason}. Tool: {}",
  217              tool_name.name()
  218          ))
  219      }
  220  }
查看全部 3 处证据
  • 实现 codex-rs/core/src/hook_runtime.rs:103–220 session/subagent start 与 PreToolUse。
  • 实现 codex-rs/core/src/hook_runtime.rs:222–285 PermissionRequest 与 PostToolUse。
  • 实现 codex-rs/core/src/hook_runtime.rs:649–705 hook events、metrics 与 analytics。
08
DIMENSION · SUBAGENTS-COLLABORATION

子 Agent 与协作

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

21
L1事实codex-agent-001

多 Agent 是共享控制面的线程树,不是主循环里的递归函数

源码事实

每棵 root thread 树共享 AgentControl、registry、V2 residency、execution limiter 和 rollout budget;spawn 通过 ThreadManager 创建独立 thread,子线程继承环境与 exec policy。

白话解释

每个子 Agent 都有自己的会话账本,但兄弟们共用一张组织架构表、并发配额和总预算。

对自研 Harness 的含义

隔离了对话状态,同时能做全树限流、恢复和协作观测。

关键源码 · 实现
codex-rs/core/src/agent/control.rs · L70–L111
   70      pub(crate) fork_parent_spawn_call_id: Option<String>,
   71      pub(crate) fork_mode: Option<SpawnAgentForkMode>,
   72      pub(crate) parent_thread_id: Option<ThreadId>,
   73      pub(crate) environments: Option<Vec<TurnEnvironmentSelection>>,
   74  }
   75  
   76  #[derive(Clone, Debug)]
   77  pub(crate) struct LiveAgent {
   78      pub(crate) thread_id: ThreadId,
   79      pub(crate) metadata: AgentMetadata,
   80      pub(crate) status: AgentStatus,
   81  }
   82  
   83  #[derive(Clone, Debug, Serialize, PartialEq, Eq)]
   84  pub(crate) struct ListedAgent {
   85      pub(crate) agent_name: String,
   86      pub(crate) agent_status: AgentStatus,
   87  }
   88  
   89  /// Control-plane handle for multi-agent operations.
   90  /// `AgentControl` is held by each session (via `SessionServices`). It provides capability to
   91  /// spawn new agents and the inter-agent communication layer.
   92  /// An `AgentControl` instance is intended to be created at most once per root thread/session
   93  /// tree. That same `AgentControl` is then shared with every sub-agent spawned from that root,
      … 8 lines omitted; exact range 70–111 …
  102      /// `ThreadManagerState -> CodexThread -> Session -> SessionServices -> ThreadManagerState`.
  103      manager: Weak<ThreadManagerState>,
  104      state: Arc<AgentRegistry>,
  105      v2_residency: Arc<V2Residency>,
  106      agent_execution_limiter: Arc<AgentExecutionLimiter>,
  107      /// Session-scoped state shared by the root thread and every cloned sub-agent control handle.
  108      rollout_budget: Arc<RolloutBudget>,
  109  }
  110  
  111  impl AgentControl {
查看全部 2 处证据
  • 实现 codex-rs/core/src/agent/control.rs:70–111 root-scoped control plane 状态。
  • 实现 codex-rs/core/src/agent/control/spawn.rs:365–445 spawn、额度、驻留与环境/策略继承。
22
L1事实codex-agent-002

fork 可选全历史、最近 N 轮或空白;消息可只入队也可触发 turn

源码事实

spawn_agent V2 解析 fork_turns none/all/正整数,默认 all;send_message 只投递队列,followup 类通信可触发空闲 agent 开新 turn,wait 同时监听 mailbox、steer 和 timeout。

白话解释

派工时可把整本案卷、最近几页或一张白纸交给下属;便签可以只塞进邮箱,也可以按门铃让他立即处理。

对自研 Harness 的含义

上下文成本可控,并避免普通消息总是打断正在执行的子任务。

关键源码 · 实现
codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs · L39–L165
   39  async fn handle_spawn_agent(
   40      invocation: ToolInvocation,
   41  ) -> Result<SpawnAgentResult, FunctionCallError> {
   42      let ToolInvocation {
   43          session,
   44          turn,
   45          payload,
   46          call_id,
   47          ..
   48      } = invocation;
   49      let arguments = function_arguments(payload)?;
   50      let args: SpawnAgentArgs = parse_arguments(&arguments)?;
   51      let fork_mode = args.fork_mode()?;
   52      let role_name = args
   53          .agent_type
   54          .as_deref()
   55          .map(str::trim)
   56          .filter(|role| !role.is_empty());
   57  
   58      let message = message_content(args.message)?;
   59      let session_source = turn.session_source.clone();
   60      let child_depth = next_thread_spawn_depth(&session_source);
   61      let mut config =
   62          build_agent_spawn_config(&session.get_base_instructions().await, turn.as_ref())?;
      … 93 lines omitted; exact range 39–165 …
  156      let hide_agent_metadata = turn.config.multi_agent_v2.hide_spawn_agent_metadata;
  157      if hide_agent_metadata {
  158          Ok(SpawnAgentResult::HiddenMetadata { task_name })
  159      } else {
  160          Ok(SpawnAgentResult::WithNickname {
  161              task_name,
  162              nickname,
  163          })
  164      }
  165  }
查看全部 3 处证据
  • 实现 codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs:39–165 spawn 参数、子配置和 telemetry。
  • 实现 codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs:173–220 fork_turns 解析和限制。
  • 实现 codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs:37–118 mailbox/steer/timeout wait。
23
L1事实codex-agent-003

驻留上限与同时执行上限分离,V2 子 Agent 才受执行 limiter

源码事实

V2 的 effective_agent_max_threads 从 max_concurrent_threads_per_session 减去 root;AgentExecutionLimiter 只在 V2 SubAgent 启动新 turn 时检查 active 数,已有 active turn 的消息不重复占槽,guard drop 释放名额。

白话解释

可以让许多子会话留在通讯录里,但只有有限几个同时开工;已经在干活的人收到补充便签不会再算一个工位。

对自研 Harness 的含义

资源治理比单一 agent count 精细,恢复/驻留和运行并发可以独立调优。

关键源码 · 配置
codex-rs/core/src/config/mod.rs · L1547–L1560
 1547      pub(crate) fn effective_agent_max_threads(
 1548          &self,
 1549          multi_agent_version: MultiAgentVersion,
 1550      ) -> Option<usize> {
 1551          match multi_agent_version {
 1552              MultiAgentVersion::V2 => Some(
 1553                  self.multi_agent_v2
 1554                      .max_concurrent_threads_per_session
 1555                      .saturating_sub(1),
 1556              ),
 1557              MultiAgentVersion::Disabled | MultiAgentVersion::V1 => {
 1558                  self.agent_max_threads.or(DEFAULT_AGENT_MAX_THREADS)
 1559              }
 1560          }
查看全部 2 处证据
  • 配置 codex-rs/core/src/config/mod.rs:1547–1560 V2/legacy 有效线程数计算。
  • 实现 codex-rs/core/src/agent/control/execution.rs:14–118 执行 limiter、guard 与适用范围。
09
DIMENSION · PERSISTENCE-OBSERVABILITY

持久化与观测

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

24
L1事实codex-persistence-001

会话采用 JSONL rollout 作为事件事实源,后台 writer 支持 persist、flush 与失败记忆

源码事实

RolloutRecorder 将创建/恢复参数与 RolloutItem 送入后台命令队列;writer task 保存 terminal failure,公开 Persist、Flush、Shutdown acknowledgement。

白话解释

先把每一步写成可重放流水账,后台书记员负责落盘;书记员一旦坏掉,后续调用会记得这次故障而不是假装成功。

对自研 Harness 的含义

支持 resume/fork/审计,也给崩溃恢复和一致性测试提供稳定基线。

关键源码 · 实现
codex-rs/rollout/src/recorder.rs · L93–L171
   93  pub enum RolloutRecorderParams {
   94      Create {
   95          session_id: SessionId,
   96          conversation_id: ThreadId,
   97          forked_from_id: Option<ThreadId>,
   98          parent_thread_id: Option<ThreadId>,
   99          source: Box<SessionSource>,
  100          thread_source: Option<ThreadSource>,
  101          originator: String,
  102          base_instructions: BaseInstructions,
  103          dynamic_tools: Vec<DynamicToolSpec>,
  104          selected_capability_roots: Vec<SelectedCapabilityRoot>,
  105          multi_agent_version: Option<MultiAgentVersion>,
  106          history_mode: ThreadHistoryMode,
  107          history_base: Option<HistoryPosition>,
  108          subagent_history_start_ordinal: Option<u64>,
  109          initial_window_id: Option<String>,
  110      },
  111      Resume {
  112          path: PathBuf,
  113      },
  114  }
  115  
  116  enum RolloutCmd {
      … 45 lines omitted; exact range 93–171 …
  162  
  163      /// Return the terminal writer-task failure, if the task exited with an error.
  164      fn terminal_failure(&self) -> Option<IoError> {
  165          let guard = self
  166              .terminal_failure
  167              .lock()
  168              .unwrap_or_else(std::sync::PoisonError::into_inner);
  169          guard.as_ref().map(|err| clone_io_error(err.as_ref()))
  170      }
  171  }
查看全部 2 处证据
  • 实现 codex-rs/rollout/src/recorder.rs:93–171 RolloutCmd 和 writer failure state。
  • 实现 codex-rs/rollout/src/recorder.rs:177–290 create/resume 参数和 history metadata。
25
L1事实codex-persistence-002

SQLite 是可查询镜像,并把状态、日志、目标和记忆拆库降低锁竞争

源码事实

state crate 从 JSONL rollout 提取元数据镜像到 SQLite;StateRuntime 分别打开 state、logs、goals、memories 数据库,并明确把日志和分页历史分离以降低锁竞争。

白话解释

流水账负责忠实记录,SQLite 像索引卡片箱,负责快速搜索;不同类型卡片分柜,避免大家抢同一把锁。

对自研 Harness 的含义

兼顾可恢复事件源与 UI 查询性能,代价是要处理 backfill/reconciliation。

关键源码 · 契约
codex-rs/state/src/lib.rs · L1–L10
    1  //! SQLite-backed state for rollout metadata.
    2  //!
    3  //! This crate is intentionally small and focused: it extracts rollout metadata
    4  //! from JSONL rollouts and mirrors it into a local SQLite database. Backfill
    5  //! orchestration and rollout scanning live in `codex-core`.
    6  
    7  const _: () = assert!(
    8      libsqlite3_sys::SQLITE_VERSION_NUMBER >= 3_051_003,
    9      "bundled SQLite must include the WAL-reset corruption fix",
   10  );
查看全部 3 处证据
  • 契约 codex-rs/state/src/lib.rs:1–10 rollout 到 SQLite 镜像定位。
  • 实现 codex-rs/state/src/runtime.rs:71–125 分库状态与初始化。
  • 实现 codex-rs/state/src/runtime.rs:126–170 各数据库独立打开与失败清理。
26
L1事实codex-observe-001

观测横跨模型、工具、hooks、MCP、rollout 与 SQLite,不只是一份 CLI 日志

源码事实

模型 client 注入 SessionTelemetry 与 rollout inference trace;工具 runtime 记录 dispatch/handler/total timing;hooks 发开始/完成事件与 duration;MCP 记录 tool list/refresh;state 定义初始化、错误、回填与 fallback 指标。

白话解释

既能看模型这段花了多久,也能拆出排队、工具处理、钩子、连接器和数据库的时间与故障。

对自研 Harness 的含义

适合做端到端性能归因和故障回放,但需要明确遥测数据的隐私与导出策略。

关键源码 · 实现
codex-rs/core/src/client.rs · L74–L91
   74  use codex_otel::SessionTelemetry;
   75  use codex_otel::current_span_w3c_trace_context;
   76  use codex_protocol::auth::AuthMode;
   77  
   78  use codex_protocol::ThreadId;
   79  use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
   80  use codex_protocol::config_types::Verbosity as VerbosityConfig;
   81  use codex_protocol::models::ContentItem;
   82  use codex_protocol::models::ResponseItem;
   83  use codex_protocol::openai_models::ModelInfo;
   84  use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;
   85  use codex_protocol::protocol::InternalSessionSource;
   86  use codex_protocol::protocol::SessionSource;
   87  use codex_protocol::protocol::W3cTraceContext;
   88  use codex_rollout_trace::CompactionTraceContext;
   89  use codex_rollout_trace::InferenceTraceAttempt;
   90  use codex_rollout_trace::InferenceTraceContext;
   91  use codex_tools::create_tools_json_for_responses_api;
查看全部 3 处证据
  • 实现 codex-rs/core/src/client.rs:74–91 SessionTelemetry 与 rollout trace。
  • 实现 codex-rs/core/src/hook_runtime.rs:649–691 hook events 和 duration metric。
  • 契约 codex-rs/state/src/lib.rs:81–95 SQLite/backfill/fallback metrics。
10
DIMENSION · MATURITY-LICENSE

成熟度与许可证

本章共 1 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

27
L3事实codex-maturity-001

这是大型、多前端、测试密集的 Rust Harness,许可证为 Apache-2.0

源码事实

固定快照含约 2,780 个 Rust 文件、645 个 TypeScript 文件;源码树中约 487 个 test 命名文件、1,170 个含 Rust test attribute 的文件,根许可证为 Apache License 2.0。

白话解释

它不是一段 CLI 脚本,而是一套带协议、TUI、app server、状态库、插件和跨平台后端的系统工程。

对自研 Harness 的含义

可借鉴性高,但直接复刻意味着承担很大的平台与回归测试成本。

边界
  • 文件数与测试文件数是对该固定 checkout 的机械统计,不等于测试覆盖率。
关键源码 · 契约
LICENSE · L1–L28
    1                                   Apache License
    2                             Version 2.0, January 2004
    3                          http://www.apache.org/licenses/
    4  
    5  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    6  
    7  1.  Definitions.
    8  
    9      "License" shall mean the terms and conditions for use, reproduction,
   10      and distribution as defined by Sections 1 through 9 of this document.
   11  
   12      "Licensor" shall mean the copyright owner or entity authorized by
   13      the copyright owner that is granting the License.
   14  
   15      "Legal Entity" shall mean the union of the acting entity and all
   16      other entities that control, are controlled by, or are under common
   17      control with that entity. For the purposes of this definition,
   18      "control" means (i) the power, direct or indirect, to cause the
   19      direction or management of such entity, whether by contract or
   20      otherwise, or (ii) ownership of fifty percent (50%) or more of the
   21      outstanding shares, or (iii) beneficial ownership of such entity.
   22  
   23      "You" (or "Your") shall mean an individual or Legal Entity
   24      exercising permissions granted by this License.
   25  
   26      "Source" form shall mean the preferred form for making modifications,
   27      including but not limited to software source code, documentation
   28      source, and configuration files.
查看全部 3 处证据
  • 契约 LICENSE:1–28 Apache License 2.0。
  • 测试 codex-rs/core/src/tools/spec_plan_tests.rs:637–708 代表性的工具规划回归测试。
  • 测试 codex-rs/core/src/agent/control_tests.rs:2047–2174 线程额度、释放与共享 limiter 测试。
APPENDIX · SOURCE INDEX

本报告引用过的实现文件

这是一份代码阅读索引,不是仓库文件总表。机器候选扫描覆盖整个仓库;进入结论的文件必须经人工沿调用链复核。

  1. 01codex-rs/core/src/session/turn.rsL153–274, 275–455, 2034–2168, 2169–2265, 1176–1273
  2. 02codex-rs/core/src/client.rsL1–24, 1–24, 74–91
  3. 03codex-rs/model-provider-info/src/lib.rsL54–84, 86–144, 156–186
  4. 04codex-rs/core/src/context_manager/history.rsL38–60, 123–146, 189–248, 295–386, 493–558
  5. 05codex-rs/core/src/compact.rsL240–318, 319–392
  6. 06codex-rs/core/src/tools/registry.rsL48–149, 151–188
  7. 07codex-rs/core/src/tools/parallel.rsL74–145, 146–202
  8. 08codex-rs/core/src/tools/spec_plan_tests.rsL637–708, 637–708
  9. 09codex-rs/core/src/tools/spec_plan.rsL310–328, 917–936
  10. 10codex-rs/protocol/src/protocol.rsL890–932, 995–1043, 4094–4135
  11. 11codex-rs/core/src/session/mod.rsL2295–2376, 3336–3397, 3398–3440
  12. 12codex-rs/sandboxing/src/manager.rsL34–73, 280–367
  13. 13codex-rs/core/src/config/permissions.rsL203–213, 347–407, 507–520
  14. 14codex-rs/codex-mcp/src/connection_manager.rsL66–117, 143–199
  15. 15codex-rs/codex-mcp/src/connection_manager/tool_catalog.rsL34–55, 127–230
  16. 16codex-rs/core/src/agents_md.rsL1–16, 89–150, 207–247
  17. 17codex-rs/core/src/hook_runtime.rsL103–220, 222–285, 649–705, 649–691
  18. 18codex-rs/core/src/agent/control.rsL70–111
  19. 19codex-rs/core/src/agent/control/spawn.rsL365–445
  20. 20codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rsL39–165, 173–220
  21. 21codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rsL37–118
  22. 22codex-rs/core/src/config/mod.rsL1547–1560
  23. 23codex-rs/core/src/agent/control/execution.rsL14–118
  24. 24codex-rs/rollout/src/recorder.rsL93–171, 177–290
  25. 25codex-rs/state/src/lib.rsL1–10, 81–95
  26. 26codex-rs/state/src/runtime.rsL71–125, 126–170
  27. 27LICENSEL1–28
  28. 28codex-rs/core/src/agent/control_tests.rsL2047–2174