关于 codex-plan-review
一种对抗式实施计划审查工作流,由 Claude 编写计划、Codex CLI 只读评审。它限制审查轮数并记录讨论,最终由人工决定是否实施。
主要功能
- 01使用 Codex CLI 进行只读评审
- 02维持跨轮次的评审会话
- 03限制评审轮数
- 04记录评审意见与计划修改
- 05实施前要求人工批准
适用场景
- 01审查高风险变更的计划
- 02在实施前发现具体遗漏
- 03跟踪规划者与评审者的分歧
- 04在有限轮审查后决定是否推进
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tsmura/ grill-me-codex --skill codex-plan-review安装后在 Claude Code 中输入/codex-plan-review确认已加载。
详细介绍
Codex-Plan-Review — 对抗式计划审查循环
两个模型,一个计划,一场有界争论。Claude 是构建者和协调者。Codex 是只读评论者,可以读取代码仓库和计划,但不能修改任何文件。它们严格通过 PLAN_FILE + 一个跨轮次持久存在的 Codex 会话进行沟通。人类只在两个确切节点介入:启动和最终签字确认。
这是一个有意设计的高风险工具——遇到身份验证、数据模型、并发、迁移、支付,以及任何出错代价高昂的事情时,使用它。显而易见或成本低廉的工作则跳过。
前置条件(快速验证一次)
- 已安装较新的 Codex CLI:
codex --version(需要 ≥ 0.130;默认的gpt-5.5模型在较旧的 CLI 上会报错)。 - Codex 已完成身份验证:之前执行过
codex login(ChatGPT 账户即可)。如果运行返回身份验证/模型错误,请告知用户——不要静默重试。 - 除非用户要求,否则不要指定
-m。使用用户~/.codex/config.toml中的默认模型。使用 ChatGPT 账户身份验证时,指定gpt-5.x-codex变体会失败。 - 在第 1 轮之前回显当前模型,以便用户确认:读取
~/.codex/config.toml中的model行(若不存在,则为 “CLI default”);与解析后的可调参数一并说明。如果用户有异议,请在消耗一轮之前停止。 - 两个命令的沙箱标志不同。
codex exec接受-s read-only。codex exec resume不接受——它会拒绝-s(“unexpected argument”)。恢复会话时,必须通过-c sandbox_mode="read-only"强制设为只读,因为config.toml的默认值可能是sandbox_mode为danger-full-access(并且approval_policy="never")——这会让 Codex 在循环过程中写入文件。这是此技能中最重要的安全细节:已于 2026-06-04 端到端验证。
可调变量(从技能参数读取,否则使用默认值)
| 变量 | 默认值 | 含义 |
|---|---|---|
MAX_ROUNDS | 5 | 审查轮数上限。循环始终会在此轮数终止。 |
PLAN_FILE | PLAN.md | 存放不断演进的计划的位置。默认位于代码仓库根目录;采用计划目录约定的代码仓库应传入该任务专用的路径。 |
LOG_FILE | PLAN-REVIEW-LOG.md | 仅追加的争论记录(每轮的批评意见 + 变更内容)。即产物。 |
如果用户调用技能时传入类似 rounds=3 的参数,请将其用于 MAX_ROUNDS。开始之前回显解析后的值。
在编写或审查任何内容之前,先解析 PLAN_FILE / LOG_FILE,将两者记录在日志头部,并且在下面的每个提示词中替换为解析后的路径——像 <PLAN_FILE> 这样的占位符需要由你填写,绝不能原样发送。如果传入了覆盖值,却在审查者提示词中保留字面值 PLAN.md,Codex 就会审查该路径下任何过时的文件,并可能对错误的文档返回 VERDICT: APPROVED。
流程
第 0 步 — 启动(人类关卡 #1)
调用本身就是启动。用一句话确认范围:要规划什么。如果用户没有说明任务,就提出一个问题。然后继续——不要逐轮请求批准;批准环节在最后。
第 1 步 — Claude 制定计划
认真规划:阅读相关代码,仔细考虑方案,并说明决策与权衡。然后按以下结构将计划写入 PLAN_FILE:
# Plan: <task>
_Round 0 — initial draft by Claude_
## Goal
<one paragraph>
## Approach
<numbered steps, concrete>
## Key decisions & tradeoffs
<the contestable choices — name them explicitly so Codex has something to bite>
## Risks / open questions
<what you're unsure about>
## Out of scope
<bounds>
初始化 LOG_FILE:
# Plan Review Log: <task>
Started <stamp the user's local time if known, else "session start">. MAX_ROUNDS=<n>.
向用户展示计划全文,并说明你将把计划发送给 Codex 进行对抗式审查。
第 2 步 — 循环
维护 ROUND(从 1 开始)和 THREAD_ID(直到第 1 轮返回前保持为空)。
每轮发送给 Codex 的评审提示词(调整任务行):
你是实现计划的对抗式评审者。请保持怀疑并提出具体意见——你的任务是找出会出问题的地方,而不是一味赞同。阅读
<PLAN_FILE>中的计划(以及所需的任何仓库文件;你只能读取)。找出具体缺陷:安全漏洞、竞态条件、遗漏的边缘情况、架构冲突、错误假设、可观测性缺口、更简单的替代方案。针对每个问题,给出一行修复建议。不要修改任何文件。回复末尾必须严格包含一行:如果计划足够可靠,可以着手实现,则写VERDICT: APPROVED;如果仍有实质性问题,则写VERDICT: REVISE。
第 1 轮(创建会话——捕获 thread_id):
codex exec -s read-only --json \
-o /tmp/codex-verdict.txt \
"$(cat REVIEW_PROMPT)" \
< /dev/null 2>/dev/null | grep '"type":"thread.started"'
从 {"type":"thread.started","thread_id":"..."} 行中解析 thread_id → 这就是 THREAD_ID。评审意见会写入 /tmp/codex-verdict.txt(Codex 的最后一条消息)。读取该文件。
注意:某些环境中,stderr 会输出无关紧要的 MCP/身份验证信息;因此有意使用
2>/dev/null。请通过 verdict 文件和thread.started行确认成功。如果两者都没有出现,则运行失败(身份验证/模型问题)——停止并告知用户。
< /dev/null必不可少:codex exec除了提示词参数外,还会读取 stdin,因此在非交互式驱动(Claude Code 的 Bash 工具、CI、任何非 TTY 管道)中,它会一直阻塞等待 stdin EOF——陷入近乎 0% CPU 的无声挂起。这个重定向会立即向其发送 EOF。下面的恢复调用也必须使用此重定向。超时保护: 每次运行
codex exec/codex exec resume都必须设置 10 分钟上限,以便将来发生停滞时能明确失败,而不是无声挂起。使用 Claude Code 的 Bash 工具时,在工具调用中传入timeout: 600000(默认的 2 分钟工具超时对于实际评审来说太短,会在运行中途将其终止)。在普通 shell 中,在命令前加上timeout 600(Linux / Git Bash),或gtimeout 600(通过 coreutils 安装在 macOS 上——macOS 自带的 shell 没有timeout)。如果触发超时,则将其视为运行失败:停止并告知用户,不要盲目重试。下面的恢复调用也适用此规则。
第 2 至 MAX 轮(恢复同一会话——Codex 会记得之前的评审意见,不会重新争论已解决的问题):
# NOTE: resume rejects -s. Force read-only via -c sandbox_mode, or Codex
# inherits config.toml (possibly danger-full-access) and could write files.
codex exec resume "$THREAD_ID" -c sandbox_mode="read-only" --json \
-o /tmp/codex-verdict.txt \
"I revised the plan. Re-review <PLAN_FILE>. Same rules. End with VERDICT: APPROVED or VERDICT: REVISE." \
< /dev/null 2>/dev/null >/dev/null
codex exec 和 codex exec resume 都支持 --json(流式输出 → 在第一轮解析 thread_id)和 -o/--output-last-message(捕获 verdict)。
每轮 Codex 返回后:
- 读取
/tmp/codex-verdict.txt。将## Round <n> — Codex和完整评审意见追加到LOG_FILE。 - 使用 grep 检查最后一行中的 verdict 标记。
VERDICT: APPROVED→ 跳出循环,进入第 3 步(达成一致)。VERDICT: REVISE→ Claude 阅读评审意见,判断哪些建议确实值得采纳(Claude 拥有最终决定权——Codex 提供建议,不发号施令)。修改PLAN_FILE。将### Claude's response以及所做的修改、未采纳的建议及原因追加到LOG_FILE。递增ROUND。
- 如果
ROUND > MAX_ROUNDS→ 跳出循环,进入第 3 步(陷入僵局)。
第 3 步 — 结论(人工关卡 #2)
如果 APPROVED: 向用户展示最终的 PLAN_FILE、一份包含 3 个要点的改进摘要,以及轮数。询问:“计划经过 Codex N 轮评审。现在开始实现吗——由 Codex 实现(/codex-build)、由 Claude 实现,还是到此为止?” 只有用户同意后才能编写代码。循环期间不会编写任何代码。 如果用户选择 Codex,则使用 SPEC_FILE=<PLAN_FILE> 和相同的 LOG_FILE 调用 codex-build skill——角色互换(Codex 编写,Claude 评审差异),构建轮次会追加到同一日志中。
如果达到 MAX_ROUNDS 但仍未 APPROVED(陷入僵局): 不要假装双方已达成一致。明确指出尚未解决的分歧:列出 Codex 仍在指出的每个问题,以及 Claude 的反方立场。交由人工打破僵局。这是合理且有用的结果——指出分歧胜过给出虚假的“已批准”。
硬性规则
- 每一轮中,Codex 都必须处于只读模式:首次调用使用
-s read-only,每次恢复调用使用-c sandbox_mode="read-only"(恢复调用没有-s)。它绝不会写入。如果你想给它写入权限,请停下——那属于另一项技能。 - 循环始终会在
MAX_ROUNDS处终止。不会进行无界递归。 - 每次 REVISE 时,Claude 都是最终裁决者——采纳合理的批评,有理由地驳回不合理的批评,并记录理由。不要对 Codex 言听计从(那会失去跨模型检查的意义),也不要忽视它(那会失去这项检查的意义)。
- 只有通过人工关卡 #2 后才能编写代码。
LOG_FILE是交付物——它完整记录了这场讨论。务必保持完整。
不要做的事
- 不要用它来审查现有代码——请使用
/codex-code-review或/codex:review。 - 使用 ChatGPT 账号认证时,不要指定
-codex模型变体,否则会返回 400 错误。 - 不要跳过日志——讨论记录是最有价值的产物。
- 绝不要让 Codex 编辑文件。始终保持只读模式。