English

第 25 章:CI、策略与架构治理

阅读契约: 用本章把 CI 读成可执行架构。跟住 policy lanes、test targets、generated checks,以及保护 runtime contracts 的失败信号。

CI 治理通道:连接策略检查、生成产物、Rust 测试、Bazel 校验和发布保护
CI 通过分离 behavior tests、boundary linting、schema checks、artifact checks、risk policy 和 docs evidence 来保护架构。

源码边界: 本章只有在链接到固定 Codex commit 或本章源码地图的 files、types、functions、tests、schemas、request/event shapes 时,才把说法视为 verified source。像 runtime、owner、projection、contract 这类架构归纳是从可见 anchors 得出的 surrounding contract inference,不是对 OpenAI 服务内部的断言。

第 24 章展示了发布打包如何防止平台蔓延改变运行时。最后一个系统压力是时间。代码库不是一次性失去架构,而是通过一个个小例外失去架构:一个不应该被 core 触达的依赖,一个没有更新的生成 schema,一个为了方便提交的大二进制,一个 UI crate 绕过协议边界。

Codex 用可执行治理回答很多这类压力。CI 不只是测试运行器,而是一组用脚本、lint、生成检查、workflow lane 和发布 gate 写下来的架构断言。本章解释为什么这些检查属于设计,以及如何借鉴这个模式而不把 CI 变成缓慢嘈杂的墙。

策略就是带失败退出码的架构

本书每一章都描述过边界:协议先于客户端,策略先于工具,app-server 先于 UI surface,扩展加载先于模型可见能力,生成 schema 先于外部客户端。不能让变更失败的边界,比它看起来更弱。

可执行策略把“请不要破坏这个边界”变成“这个 pull request 在边界仍然成立之前不能合并”。这不是官僚主义。对 agent 运行时来说,这是风险管理。系统可以运行命令、修改文件、调用外部服务并协调远端工作。治理让这些能力在仓库变化时仍然受约束。

merge confidence 不是说 CI 证明了一切。它只证明项目选择变成可执行规则的那些内容。难点是选择真正保护架构的规则,而不是把个人偏好编码进去。

CI lane 应该匹配风险

Codex 的 CI 表面按目的拆分。有面向普通变更的快速检查,有提供平台信心的更广矩阵,有验证 hermetic 发布假设的 Bazel 路径,有保护客户端契约的 schema 与生成文件检查,有外部 surface 的 SDK 检查,也有组装产物的 release workflow。

这是一张风险地图。协议类型变更的爆炸半径不同于 TUI 渲染 helper 变更。打包变更的风险不同于测试 helper 变更。CI 设计应该让这些差异可见。

反模式是一个不区分目的的“run everything”按钮。它隐藏了失败的是哪种架构承诺,并让工程师把失败当成 CI 天气。lane 应该解释自己提供哪一种信任。

边界检查胜过人的记忆

review 大变更时,人不可能记住每一条架构规则。所以 Codex 对容易被侵蚀的边界使用检查:生成 schema 同步、依赖策略、大二进制 blob、lint 同步、源格式,以及运行时层之间的分离。

具体检查不如模式重要:

// Pseudocode - illustrates executable architecture policy.
policies = [
    generated_files_are_current,
    client_contracts_are_stable,
    forbidden_dependencies_are_absent,
    binary_blobs_are_justified,
    custom_lints_are_in_sync,
]

for policy in policies:
    result = policy.run(change_set)
    if result.failed:
        report(policy.name, result.explanation)
        stop_merge()

report 是设计的一部分。只说“failed”的策略会训练开发者去日志里猜谜。好的治理检查会说明边界、违规文件和预期修复路径。

深入:把生成漂移建模成状态机

生成产物需要特别严格,因为 drift 可能有多种含义。开发者忘了重新生成?生成器变了?源码契约有意变化?实验字段泄漏进稳定 schema?

这个状态机很小,但它改变行为。契约变化会作为契约变化被 review。仓库不再要求 reviewer 从内部类型 diff 里猜客户端影响。

治理必须保持比例感

可执行策略也可能走错。如果每个偏好都变成硬 gate,项目会变慢但不一定更安全。Codex 里有价值的检查都和产品风险相关:客户端兼容性、发布可复现性、运行时边界、产物信任、依赖安全、生成契约漂移。

判断标准应该是:这条规则是否保护 reviewer 可能漏掉的架构承诺?如果是,就让它可执行;如果不是,把它留给 review 规范、本地工具或文档。

这也是为什么治理作为本书收尾。Codex 的架构不是一组图,而是一组能在日常开发中继续存在的规则。最好的系统会让重要规则遵守起来便宜、意外破坏起来困难。

应用到实践

  1. 可执行架构策略 -> 解决边界随时间侵蚀 -> 把关键架构承诺变成 CI 检查 -> 风险:执行的是品味而不是风险。
  2. 按风险组织 CI lane -> 解决反馈慢且不透明 -> 按信任类型分组:快速、契约、hermetic、平台、供应链 -> 风险:一个没人理解的巨大 lane。
  3. 把 drift 当 review 产物 -> 解决隐藏客户端契约变化 -> 要求重新生成的 schema 和源码变更同批出现 -> 风险:把生成 diff 当噪音。
  4. 诊断型失败 -> 解决 policy fatigue -> 每个失败都命名边界和修复路径 -> 风险:让开发者反向解析治理脚本。
  5. 比例化执行 -> 解决治理膨胀 -> 只 gate 保护兼容性、安全性或发布正确性的规则 -> 风险:硬性失败低价值偏好。

下一步

这本书的机器已经完整:契约、运行时、工具、客户端、扩展、协调、记忆、构建、打包和治理。epilogue 会从 Codex 抽身出来,命名那些即使你的系统不是 AI coding agent 也值得带走的架构经验。

源码地图

概念源码锚点
Main CI workflow.github/workflows/rust-ci.yml
Full CI matrix.github/workflows/rust-ci-full.yml
Bazel verification workflow.github/workflows/bazel.yml
Blob-size policyscripts/check_blob_size.py
TUI/core boundary check.github/scripts/verify_tui_core_boundary.py
Cargo workspace governance.github/scripts/verify_cargo_workspace_manifests.py