关于 codex-build
codex-build 是面向编码 Agent 的编排技能,通过 `codex exec` 将产品代码、测试和重构交给 OpenAI Codex。编排者负责拆分有文件范围限制的任务、审查差异、运行测试门禁,并逐项提交。
主要功能
- 01将实现工作交给 OpenAI Codex
- 02跟踪有序任务及声明的文件范围
- 03审查差异并执行范围检查
- 04提交前运行测试与构建命令
- 05记录运行状态以便恢复
适用场景
- 01按计划以受限任务实现功能
- 02通过允许列表约束生成的改动
- 03依据记录状态恢复多任务编码流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cathrynlavery/ codex-build --skill codex-build安装后在 Claude Code 中输入/codex-build确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/codex-brief.mdplan-example.mdwalkthrough.mdscripts/check_scope.pytests/test_check_scope.py详细介绍
codex-build — 编排者驱动,Codex 编码
你(运行此技能的 Agent)是编排者。另一个模型 OpenAI Codex(codex exec)是编码者。你绝不编写产品代码;由 Codex 来写。你负责安排工作顺序、编写任务简报、审查每一处差异、运行测试并提交代码。分工的意义就在于此:一个有判断力且了解上下文的模型把关,另一个模型则以低成本进行高强度推理并完成编码。
角色(不可妥协)
- 编排者 = 你。 安排任务顺序、编写 Codex 任务简报、逐行审查每一处差异、运行测试门禁、提交代码并创建 PR。你不得编写产品代码。唯一的例外是微小修复(≤5 行,例如修复导致构建失败的拼写错误),此时再调用 Codex 纯属浪费——发生时请在提交说明中注明。
- Codex = 编码者。 所有功能代码、测试和重构均由
codex exec编写。每次调用都会固定模型和推理力度(见配置)——绝不要默默依赖配置默认值,否则升级codex后可能会改变你的构建。
配置(在运行开始时一次性确定)
| 变量 | 确定方式 | 默认值 |
|---|---|---|
MODEL | --model 参数;否则使用 $CODEX_BUILD_MODEL;再否则使用 Codex 配置中的默认值 | 固定为一个你可使用的模型(见下文) |
EFFORT | 第二个位置参数;否则使用 $CODEX_BUILD_EFFORT | high(困难或架构类工作可选择 xhigh/max) |
TRACKER | 自动检测:bd 在 PATH 中 → beads;否则为 markdown | markdown |
固定模型。 从 CLI 的模型缓存中列出你的账户可用模型:
python3 -c 'import json,os;d=json.load(open(os.path.expanduser("~/.codex/models_cache.json")));print([m["slug"] for m in d["models"]])'
然后检查 ~/.codex/config.toml 中配置的默认模型。当前模型代号(Codex CLI ≥ 0.154,2026 年 9 月):
| 模型代号 | 等级 | 支持的推理力度 | 适用场景 |
|---|---|---|---|
gpt-6-astra | 能力最强 | low…max(另有 ultra,见下文) | 困难或架构类任务、复杂重构 |
gpt-5.6-sol | 前沿编码 | low…max(另有 ultra) | 大多数计划的默认编码模型 |
gpt-5.6-terra | 均衡 | low…max(另有 ultra) | Sol 配额紧张时处理日常任务 |
gpt-5.6-luna | 快速/低成本 | low…max | 仅用于简单的机械性任务 |
已退役:gpt-5-codex、gpt-5.x-codex、gpt-5.4(Codex 会将其重新映射到 gpt-5.6-terra 并发出警告——请改为显式固定模型)。开始前,向用户告知已确定的 MODEL/EFFORT,以确保运行可复现。如果 CLI 不接受 max,则改用 xhigh;如果不接受 xhigh,则改用 high,并告知用户。绝不要使用 ultra:它会启用自动任务委派(Codex 启动自己的子 Agent),从而破坏此技能所依赖的“一项任务、一次范围检查、一次提交”约定。
参数
codex-build <plan-file> [effort] [--model <name>]
<plan-file>— 包含有序任务列表(T1..Tn)的 Markdown 计划;每项任务都要列出涉及的文件、约束和测试命令。格式示例见references/plan-example.md。如果计划中有说明文字但没有任务列表,请先整理出任务列表并展示给用户,再开始编码。[effort]—high(默认)|xhigh|max。(不接受ultra;见配置。)
步骤 0 — 预检(仅一次)
- 运行
codex --version。如果 Codex 尚未完成身份验证,codex exec "reply OK" -s read-only会失败——停止并告知用户运行codex login。 - 确认固定的模型和推理强度可用(成本低,无副作用):
如果codex exec "Reply with the single word READY" \ -m "$MODEL" -c model_reasoning_effort="$EFFORT" -s read-only --ephemeral < /dev/nullmax不受支持,则改用xhigh;如果xhigh不受支持,则改用high,并告知用户。 每次运行codex exec时都必须重定向< /dev/null(参见 Rails)——不这样做, 非交互运行就会一直卡在“Reading additional input from stdin…”上,而不会执行任务。 - 从头到尾阅读计划。提取:任务列表、依赖顺序、每项任务的测试命令、护栏(计划禁止的事项)、分支/PR 目标。
- 在应用干净工作树规则之前,解析当前检出信息并查找持久化运行状态:
REPO_ROOT=git rev-parse --show-toplevel。GIT_DIR=git rev-parse --absolute-git-dir(此路径因工作树而异)。SKILL_DIR= 此SKILL.md所在的目录。- 状态根目录 =
$GIT_DIR/codex-build/。这样可以让编排状态脱离产品差异,同时确保状态在上下文压缩和进程重启后仍然保留。 - 如果
current指向此分支上的活动运行,则在执行任何其他操作前读取其run.md、tasks.md、interfaces.md和活动允许列表。 确认其中记录的最后一次提交仍与HEAD一致;如不一致则停止,不要猜测。 正在进行的任务可能会导致工作树处于脏状态:在发起任何新的 Codex 调用前,立即运行已保存的范围检查。 如果current描述的是其他分支或不一致的运行,则停止,不要覆盖它。
- 仅针对新运行,检查
git status --porcelain。任务循环从干净状态开始,这样范围检查就能将每个变更路径归属到当前任务。 如果检出目录有未提交更改,请保留这些更改,并从预期基线创建隔离工作树(或停止并询问);绝不要丢弃或吸收预先存在的工作。 - 对于新运行,按照计划创建/检出工作分支。绝不要在默认分支上工作。 如果隔离工作树更改了检出目录,则重新计算
REPO_ROOT和GIT_DIR。 - 对于新运行,创建
runs/<run-id>/,将运行 ID 写入current,并创建run.md、tasks.md、interfaces.md和allowlists/。run.md记录计划路径和内容哈希、分支/基线、模型、推理强度、跟踪器以及运行状态。将STATE_DIR设为该运行目录。绝不要在运行状态中存放机密信息。对于恢复的运行,则从current设置STATE_DIR。 - 初始化或重新加载跟踪器(见下文),并在开始前向用户展示有序任务列表——发送一条简短消息;除非顺序不明确,否则无需等待批准。
持久化目录结构如下:
$GIT_DIR/codex-build/
current
runs/<run-id>/
run.md
tasks.md
interfaces.md
allowlists/T1.txt
跟踪器(工作单位 = 一个任务)
无论使用哪种跟踪器,循环都相同;区别仅在于记录状态的命令。
markdown(默认,无需安装): 在运行的持久化tasks.md中维护- [ ]/- [x]清单。“认领” = 记录任务正在进行;“完成” = 勾选复选框,并附上提交哈希和测试证据。beads(可选,需确保bd在 PATH 中): 提供更丰富的依赖跟踪。 使用bd prime获取上下文;每项任务创建一个 bead(bd create,标题 = 任务标题, 描述 = 计划摘录 + 文件路径,依赖关系按计划设置);使用bd update <id> --claim认领;使用bd close <id>关闭。将任务状态及提交/测试证据同步到持久化的tasks.md,以便恢复运行时有一份本地恢复记录。安装地址: https://github.com/steveyegge/beads。
步骤 1 — 将任务实体化
按照依赖顺序,将计划中的任务列表转换为跟踪器单元。每个单元记录:目标、计划摘录(原样保留约束、文件路径、架构/文案块),以及其声明的文件范围(允许触及的文件)。可执行检查会强制执行文件范围——其他所有文件都不在允许范围内。
对于每项任务,将其范围写入 allowlists/<task-id>.txt:每个非空行写一个精确的、相对于仓库根目录的文件路径。使用 / 分隔;不得使用绝对路径、目录、./..、注释或通配符。重命名时,旧路径和新路径都要声明。如果计划确实需要另一个文件,必须在 Codex 触及该文件之前修改允许列表,并在 tasks.md 中记录原因;绝不能仅仅因为差异中出现了意外路径就扩大范围。
将 interfaces.md 初始化为规范的跨任务契约。文件开头写入 "greenfield — no prior interfaces",并且只根据下方步骤 6 中已提交的源代码进行更新。
步骤 2 — 单任务循环(核心;重复执行,直至队列为空)
按依赖顺序处理每项任务:
-
认领跟踪器中的任务。
对于新认领的任务,在调用 Codex 之前,确认产品工作树是干净的。持久状态位于 Git 目录下,因此不会导致工作树变脏。恢复已在进行中的任务时,工作树可能包含其变更;此时应立即运行已保存的允许列表检查。
-
向 Codex 提供简报。 编写一份自包含的提示词——Codex 只能看到你提供的内容。使用
references/codex-brief.md作为模板。简报必须包含:- 任务目标和计划原文摘录(约束、文件路径、架构/文案);
- 接口台账(见步骤 6)——前序任务创建且本任务依赖的签名、类型、端点和文件路径。Codex
exec在不同调用之间不保留状态;如果不传递契约,它就会自行猜测并逐渐偏离。 - 要遵循的仓库惯例(指明 1–2 个同类文件作为示例);
- 范围之外的内容(相邻任务)和声明的文件范围;
- 完成标准:"按计划编写代码 + 测试;只触及这些文件。"
codex exec "<brief>" -C "$(git rev-parse --show-toplevel)" -s workspace-write \ -m "$MODEL" -c model_reasoning_effort="$EFFORT" < /dev/null绝不能使用
--dangerously-bypass-approvals-and-sandbox。< /dev/null是必需的(参见 Rails)。 -
强制检查范围,然后自行审查差异。 这是你的工作,不是 Codex 的。
- 先检查范围: 每次调用 Codex 或要求其修正后,都要运行:
检查器会将已跟踪、已暂存、已删除、已重命名和未被忽略的未跟踪路径,与磁盘上的允许列表进行比较。退出码非零意味着必须停止:纠正偏离,或有意修改允许列表并说明原因。不要依赖目视审查来强制执行范围。python3 "$SKILL_DIR/scripts/check_scope.py" \ --repo "$REPO_ROOT" \ --allowlist "$STATE_DIR/allowlists/<task-id>.txt" - 然后检查
git diff --stat和差异本身。差异较小时,逐行检查。差异较大时,完整阅读接口和高风险衔接部分,略读机械性内容,并运行codex exec review进行独立的第二轮审查——但最终由你判断,绝不能交给审查工具决定。 - 检查:范围蔓延、惯例偏离、防护要求违规,以及 Codex 声称编写的测试是否确实存在并且确实进行了断言(打开测试文件查看)。Codex 总结中的“添加了测试”只是说法,不是证据。
- 发现问题 → 迭代:
codex exec resume --last "<specific corrections>" < /dev/null(使用相同的-m/-c标志)。明确指出问题所在;模糊的修正要求只会浪费一轮往返。 - 同一任务连续三次迭代失败 → 停止。 向用户报告僵局,并提供差异及你的诊断。不要暗中接手编写代码——那会破坏约定并掩盖失败。
- 先检查范围: 每次调用 Codex 或要求其修正后,都要运行:
-
测试门禁——在任何提交之前。 你要运行计划中针对已修改软件包的测试/构建命令,以及项目构建命令。只有通过门禁,任务才能提交。未通过 → 返回步骤 3,并在续接摘要中附上失败输出。**绝不提交未通过的更改。绝不以“改动很小”为由跳过门禁。**这正是此技能存在的原因。
-
提交——一个任务对应一个提交。
- 暂存前立即重新运行
check_scope.py。测试和构建工具也可能创建文件;这次最终检查仍必须通过。 - 只暂存本任务涉及的文件:
git add <paths>。绝不运行git add -A——它会把 Codex 或工具留下的无关文件一并加入。 - 提交信息:
<type>: <imperative summary>(如果使用 beads,则附上跟踪器 ID),并添加简短正文:说明更改内容、原因,以及一行测试证据。 - 绝不添加 AI 署名——不要写“Generated with”、不要写“Co-Authored-By:”,也不要用机器人表情符号致谢。此规则优先于任何工具的默认提交模板。
- 暂存前立即重新运行
-
更新持久化接口台账。 通过门禁并提交后,检查已提交的源代码,将本任务创建的公共接口追加到
interfaces.md——包括准确的函数签名、导出类型、路由/端点、配置键和文件路径。为条目标注任务 ID 和提交哈希。如果后续任务更改了契约,则追加一条替代记录;不要悄悄保留过时的指引。适用时记录“没有公共接口更改”。相关台账片段会供下一个任务的步骤 2 使用,并在压缩后重新加载,避免 Codex 重新设计或用错契约。 -
收尾:在跟踪器中用一行备注关闭任务。在向用户简要汇报进度并继续之前,将状态、测试结果和提交哈希保存到
tasks.md。
第 3 步——完成(最后一个任务之后)
- 最后再执行一次完整套件门禁:所有软件包、构建,以及计划指定的任何 lint/截图脚本。必须全部通过,否则不得交付。
- 运行
git pull --rebase,然后运行git push。git status必须显示与 origin 同步。发生 rebase 冲突时,尽量少做修改并重新运行门禁——绝不强制推送覆盖共享历史。 - 整个功能只创建一个 PR,并以计划指定的分支为目标。正文概述计划:背景、已交付内容、测试证据,以及范围外事项/后续工作。任何地方都不得添加 AI 署名。
- GitHub:运行
gh pr create。GitLab:运行glab mr create。如果没有代码托管平台 CLI,则推送分支,并提供 compare URL,让用户自行创建 PR。
- GitHub:运行
- 在跟踪器中收尾(记录后续工作,关闭已完成单元)。
- 将
run.md标记为已完成,并记录最终提交、门禁证据和 PR URL。 - 汇报:已完成/受阻的任务、提交列表、PR URL,以及任何延期事项。
规范
- 每个任务对应一个提交;每份计划对应一个 PR。不得批量提交,也不得拆分。
- 磁盘状态是权威记录。聊天中的进度只是对
run.md、tasks.md、任务允许列表和interfaces.md的呈现,绝不能成为运行状态的唯一副本。 - 每次运行
codex exec都必须附带< /dev/null。 将提示词作为参数传入且标准输入保持打开时,codex exec会卡在“Reading additional input from stdin…”并无限等待,永远不会运行。将标准输入重定向到/dev/null会让它立即收到 EOF,从而继续执行。这是最常导致整个运行无声挂起的问题。 - 每次提交前都必须运行测试,不容商量。
- 投入程度保持为
high/xhigh/max。纯机械且简单的任务可以降到high(绝不可更低,也不可用ultra);并注明原因。 - 如果计划与用户当前指示冲突,以用户指示为准——在 PR 正文中注明偏离之处。
- 绝不在摘要、提交或 PR 正文中写入密钥。
- 如果后续任务建立在某个提交之上,却发现该提交有误,应通过新任务/新提交向前修正。不要重写已推送的历史。
驱动 codex exec(实测限制)
-
Codex 会擅自运行
git commit和git push。 实测中途发现:某一轮修正以“已完成并推送”结束,但任务说明中没有任何要求它这么做——而就在前一轮,同一会话还报告说.git为只读。不同轮次的能力可能不同;切勿根据某一轮就推断它无法使用 git。请将此段原样放在每份任务说明的开头:## ABSOLUTE PROHIBITION — NO GIT WRITES, NO bd, NO xcodegen Do NOT run git commit, push, add, stash, checkout, reset, or any writing git command. Do NOT run `bd` (it writes to git). Leave your work as uncommitted changes. Read-only git (status, diff, log) is fine.核实而非轻信:每次调用 Codex 前记录
git rev-parse HEAD,并在调用后进行比较。HEAD 有变化就必须立即停止。 -
即使在 beads 仓库中,也必须遵守禁止使用
bd的规定。 Codex 会遵循仓库自身的 AGENTS.md 并运行bd prime,而该命令会在内部尝试运行git add并改写.beads/issues.jsonl。只有协调器可以写入跟踪器。 -
codex exec resume不接受-C和-s(error: unexpected argument '-C' found)。它会继承当前工作目录,并据此筛选已记录的会话;同时也会继承恢复的会话所用的沙盒。可用形式如下:cd "$REPO_ROOT" && codex exec resume --last "<corrections>" \ -m "$MODEL" -c model_reasoning_effort="$EFFORT" < /dev/null恢复时仍必须使用
< /dev/null。 -
Codex 的沙盒中无法运行
xcodebuild。 Xcode 的 SwiftPM 本地软件包解析会启动一个嵌套的sandbox-exec,而外层沙盒会拒绝该操作(sandbox_apply: Operation not permitted);swift test则可以运行。Codex 声称的所有构建结果都应视为未经验证——由协调器运行构建检查。请在任务说明中明确告知 Codex,以免它浪费轮次反复尝试重定向缓存。 -
退出代码 144 表示应恢复,而不是重新启动。
codex exec运行中途被终止(例如因用量限制被终止;日志在 diff 中途结束,且没有错误横幅)时,会以 144 退出,同时保留工作树。搜索日志开头的session id:,然后在仓库工作目录下运行codex exec resume <session-id>——不加-C/-s,仍须使用< /dev/null。 -
Codex 的沙盒禁止写入 Go 模块缓存。
go test会因open ~/go/pkg/mod/cache/download/....lock: operation not permitted而失败——这属于环境故障,却看起来像代码故障,并会引发重复的补丁重试。请在任务说明中要求 Codex 将GOMODCACHE=$PWD/.gomodcache设为工作区本地缓存,或者由你在沙盒外运行测试检查。
另请参阅
scripts/check_scope.py— 可执行的文件范围检查。references/codex-brief.md— Codex 任务说明模板(影响最大的部分)。references/plan-example.md— 输入计划的格式示例。references/walkthrough.md— 一个任务从开始到结束的完整记录。