# Codex 执行计划（ExecPlans）

本文档说明执行计划（“ExecPlan”）的要求。ExecPlan 是一份设计文档，编码代理可以依照它交付一个可工作的功能或系统变更。请把读者视为这个仓库里的完全新手：他们手里只有当前工作树，以及你提供的这一份 ExecPlan 文件。他们不记得之前的任何计划，也没有外部上下文。

## 如何使用 ExecPlans 和 PLANS.md

在编写可执行规格（ExecPlan）时，必须逐字遵循 PLANS.md。如果它不在你的上下文里，就重新完整阅读一遍 PLANS.md 来刷新记忆。为了产出准确的规格，必须彻底阅读并反复阅读源材料。创建规格时，从骨架开始，并随着调研逐步补充完善。

在实现可执行规格（ExecPlan）时，不要向用户询问“下一步做什么”；直接推进到下一个里程碑。始终保持所有章节为最新状态，在每一个停顿点都要新增或拆分列表项，明确说明已经完成的进展以及接下来的步骤。对于含糊之处，主动自行消解，并频繁提交。

在讨论可执行规格（ExecPlan）时，要把决策记录到规格中的日志里以供后续参考；必须让人能够毫不含糊地理解为什么对规格做出某项变更。ExecPlan 是活文档，并且应当始终能够仅依靠 ExecPlan 本身，而不依赖其他工作内容，就重新开始。

在研究一个要求困难或存在重大未知数的设计时，可以使用里程碑来实现概念验证、玩具实现等，以验证用户的提议是否可行。通过查找或获取相关库并阅读其源码，做深入研究，并包含原型来指导后续更完整的实现。

## 要求

不可协商的要求：

* 每一份 ExecPlan 都必须完全自包含。所谓自包含，是指它在当前形态下已经包含了新手成功所需的全部知识和指令。
* 每一份 ExecPlan 都是活文档。随着进展推进、发现出现、设计决策定稿，贡献者都必须修订它。每一次修订后，它仍然必须保持完全自包含。
* 每一份 ExecPlan 都必须让一个对本仓库毫无先验知识的完全新手，能够端到端实现这个功能。
* 每一份 ExecPlan 都必须产出可被证明有效的工作行为，而不只是代码层面“满足某个定义”的改动。
* 每一份 ExecPlan 都必须用通俗语言定义所有术语，否则就不要使用这些术语。

目的和意图优先。开头先用几句话说明这项工作为什么对用户有意义：这项变更完成后，用户能做到哪些以前做不到的事情，以及如何看到它生效。然后引导读者通过准确步骤达到这个结果，包括要修改什么、要运行什么，以及他们应当观察到什么。

执行你计划的代理可以列出文件、读取文件、搜索、运行项目和执行测试。它不了解任何既有上下文，也无法从你之前的里程碑中推断你的本意。你依赖的任何假设都要重复写出来。不要引用外部博客或文档；如果需要知识，就用你自己的话把它写进计划本身。如果一个 ExecPlan 建立在之前某个已经签入仓库的 ExecPlan 之上，可以通过引用把它纳入上下文。如果那个文件没有签入，你就必须把其中所有相关上下文都写进当前计划。

## 格式

格式和包裹方式都简单而严格。每一份 ExecPlan 都必须是一个单独的、标记为 `md` 的围栏代码块，并且以三反引号开始、以三反引号结束。不要在里面再嵌套额外的三反引号代码块；当你需要展示命令、终端记录、diff 或代码时，应当在这个唯一围栏内部使用缩进块来呈现。为了避免意外提前结束 ExecPlan 的代码围栏，优先使用缩进来表达清晰度，而不要在 ExecPlan 内再放代码围栏。每个标题后留两个换行，使用 `#`、`##` 等标准 Markdown 标题语法，并正确使用有序列表和无序列表。

如果你是把 ExecPlan 写入一个 Markdown（`.md`）文件，并且这个文件的全部内容就是这一份 ExecPlan，那么应省略最外层的三反引号。

使用普通散文式写法。优先使用句子，而不是列表。除非为了简洁而不得不使用，否则避免使用检查清单、表格和冗长枚举。只有在 `Progress` 章节中允许使用检查清单，而且在那里它是强制要求。叙述性章节必须以散文为主。

## 指导原则

自包含和通俗语言是首要原则。如果你引入了一个并非常见英语的词组（例如 “daemon”、 “middleware”、 “RPC gateway”、 “filter graph”），必须立刻定义它，并提醒读者它在这个仓库里是如何体现的（例如点名相关文件或命令）。不要写“如前所述”或“根据架构文档”。即使会重复，也要把所需解释写在这里。

避免常见失败模式。不要依赖未定义的术语。不要把“某个功能的字面要求”描述得过于狭窄，以至于最后代码虽然能编译，但没有任何真实意义。不要把关键决策外包给读者。当存在歧义时，在计划本身里消解它，并解释你为什么选择这条路径。宁可把用户可见的效果解释得更充分，也不要对实现细枝末节做过度规定。

用可观察结果来锚定计划。说明实现后用户能做什么、要运行什么命令，以及应该看到什么输出。验收标准应当表述为人类可验证的行为（例如“启动服务器后，访问 [http://localhost:8080/health](http://localhost:8080/health) 会返回 HTTP 200，响应体为 OK”），而不是内部属性（例如“添加了一个 `HealthCheck` 结构体”）。如果改动是内部性的，也要解释如何证明它的影响，例如通过运行修改前失败、修改后通过的测试，或者展示一个使用了新行为的场景。

明确写出仓库上下文。使用完整的仓库相对路径点名文件，精确写出函数名和模块名，并说明新文件应创建在哪里。如果会涉及多个区域，加入一段简短的定位说明，解释这些部分如何彼此配合，这样新手才能有把握地定位。运行命令时，写清楚工作目录和完整命令行。如果结果依赖环境，明确说明假设条件，并在合理情况下给出替代方案。

保持可幂等且安全。步骤要写成可以重复运行而不会造成损坏或漂移的形式。如果某个步骤可能执行到一半失败，说明如何重试或调整。如果必须进行迁移或破坏性操作，清楚写明备份方式或安全回退方案。优先选择可增量进行、可测试、并且可以边做边验证的改动。

验证不是可选项。必须包含运行测试的说明；如果适用，也必须说明如何启动系统并观察它做出有用行为。对于任何新特性或新能力，都要描述全面的测试方案。包含预期输出和错误消息，以便新手判断成功或失败。尽可能展示如何证明改动不仅仅是能编译，例如通过一个小型端到端场景、一次 CLI 调用，或一段 HTTP 请求/响应记录。写明与该项目工具链对应的精确测试命令，以及如何解读它们的结果。

记录证据。当你的步骤产出终端输出、简短 diff 或日志时，把它们作为缩进示例包含在这个唯一围栏中。保持简短，只保留能证明成功的关键内容。如果需要包含补丁，优先使用以文件为范围的 diff 或小片段，让读者能够通过你的说明自行重建，而不是直接粘贴大块内容。

## 里程碑

里程碑是叙事工具，不是官僚流程。如果你要把工作拆分为多个里程碑，每个里程碑都应以前置的一小段文字开头，说明范围、该里程碑结束时将新增什么、要运行什么命令，以及你期望观察到的验收结果。要把它写成一个容易阅读的故事：目标、工作、结果、证据。`Progress` 和里程碑是两个不同概念：里程碑讲述整体故事，`Progress` 追踪细粒度工作。两者都必须存在。不要仅仅为了简洁而把里程碑写得过于简略，不要遗漏那些对未来实现至关重要的细节。

每一个里程碑都必须可以独立验证，并且要以渐进方式实现执行计划的总体目标。

## 活文档与设计决策

* ExecPlan 是活文档。当你做出关键设计决策时，要更新计划，记录该决策以及背后的思考过程。所有决策都要记录在 `Decision Log` 章节中。
* ExecPlan 必须包含并持续维护 `Progress`、`Surprises & Discoveries`、`Decision Log` 和 `Outcomes & Retrospective` 四个章节。它们不是可选项。
* 当你发现了影响实现路径的优化器行为、性能权衡、意外 bug，或逆变换 / 还原语义时，要把这些观察记录到 `Surprises & Discoveries` 章节中，并附上简短证据片段（测试输出最理想）。
* 如果你在实现过程中中途改变了方向，要在 `Decision Log` 中记录原因，并在 `Progress` 中体现相应影响。计划既是给下一位贡献者的指引，也是你自己的执行清单。
* 在完成一个重要任务或整份计划时，要在 `Outcomes & Retrospective` 中写一条总结，说明完成了什么、还剩什么，以及得到了哪些经验。

# 原型里程碑与并行实现

当原型能为更大的变更降风险时，明确加入原型里程碑是允许的，而且通常值得鼓励。示例包括：给某个依赖新增一个底层操作符来验证可行性，或者探索两种组合顺序并测量优化器效果。保持原型是增量式且可测试的。明确标注其范围为“原型验证”；说明如何运行和观察结果；并写清楚提升为正式方案或废弃该原型的判定标准。

优先采用先加法后减法的代码改动方式，并保证测试始终通过。并行实现（例如在迁移期间保留一个适配器与旧路径并存）是可以接受的，只要它能降低风险，或让测试在大型迁移过程中持续通过。说明如何验证两条路径，以及如何借助测试安全地退役其中一条。当涉及多个新库或功能区域时，可以考虑创建若干 spike（探索性实现），分别独立验证这些特性的可行性，以证明外部库在隔离场景下的行为符合预期，并确实提供了我们需要的能力。

## 一份优秀 ExecPlan 的骨架

    # <简短、面向行动的描述>

    这份 ExecPlan 是活文档。随着工作推进，必须持续维护 `Progress`、`Surprises & Discoveries`、`Decision Log` 和 `Outcomes & Retrospective` 这几个章节。

    如果 PLANS.md 文件已经签入仓库，请在这里写出从仓库根目录出发到该文件的路径，并注明本文档必须按照 PLANS.md 的要求持续维护。

    ## Purpose / Big Picture

    用几句话说明这项变更完成后，别人会得到什么，以及他们如何看到它运行成功。写出你将启用的用户可见行为。

    ## Progress

    使用带复选框的列表来总结细粒度步骤。每一个停顿点都必须在这里记录，即使这意味着要把一个部分完成的任务拆成两个条目（“已完成” 与 “剩余部分”）。这一节必须始终反映工作的真实当前状态。

    - [x] (2025-10-01 13:00Z) 示例：已完成步骤。
    - [ ] 示例：未完成步骤。
    - [ ] 示例：部分完成步骤（已完成：X；剩余：Y）。

    使用时间戳来衡量进展速度。

    ## Surprises & Discoveries

    记录在实现过程中发现的意外行为、bug、优化点或洞见。提供简洁证据。

    - Observation: …
      Evidence: …

    ## Decision Log

    以如下格式记录在执行计划过程中做出的每一项决策：

    - Decision: …
      Rationale: …
      Date/Author: …

    ## Outcomes & Retrospective

    在重要里程碑或计划完成时，总结产出、缺口和经验。把结果与最初的目标进行对比。

    ## Context and Orientation

    假设读者一无所知，描述与当前任务相关的现状。用完整路径点名关键文件和模块。定义所有不明显的术语。不要引用之前的计划。

    ## Plan of Work

    用散文方式描述编辑与新增的顺序。对于每一处改动，点名文件和位置（函数、模块），说明要插入或修改什么。内容要具体且克制。

    ## Concrete Steps

    写出需要运行的准确命令，以及在哪里运行它们（工作目录）。如果命令会生成输出，给出一小段预期终端记录，供读者对照。本节必须随着工作推进持续更新。

    ## Validation and Acceptance

    说明如何启动或操作系统，以及应当观察到什么。把验收标准写成行为，并给出具体输入与输出。如果涉及测试，写成 “运行 <项目测试命令>，预期 <N> 项通过；新增测试 <name> 在修改前失败、修改后通过”。

    ## Idempotence and Recovery

    如果步骤可以安全重复执行，要明确写出来。如果某一步有风险，提供安全的重试或回滚路径。完成后保持环境整洁。

    ## Artifacts and Notes

    把最重要的终端记录、diff 或片段作为缩进示例包含进来。保持简短，只保留能证明成功的内容。

    ## Interfaces and Dependencies

    要写得有规定性。明确指出要使用哪些库、模块和服务，以及原因。明确写出在该里程碑结束时必须存在的类型、trait / interface 和函数签名。优先使用稳定的名字和路径，例如 `crate::module::function` 或 `package.submodule.Interface`。例如：

    在 `crates/foo/planner.rs` 中定义：

        pub trait Planner {
            fn plan(&self, observed: &Observed) -> Vec<Action>;
        }

如果你遵循上述指导，那么一个单次执行、无状态的代理，或者一个人类新手，都可以从头到尾读完你的 ExecPlan，并产出一个可工作、可观察的结果。这就是标准：自包含、自给自足、能指导新手、以结果为导向。

当你修订一份计划时，必须确保你的变更被完整地反映到所有章节中，包括这些活文档章节；并且你必须在计划底部写一条说明，描述改动内容以及这么改的原因。ExecPlan 不仅要描述做什么，还要尽可能描述几乎所有内容背后的原因。
