方案文档多轮评审循环

SKILL开发

原名 方案评审循环(spec/plan 多轮审计) · 标识 spec-review-loop

开发 未标注权限 许可证不明确
安装这个技能

对 spec 与实施方案做多轮评审,由专职评审者提意见、你改稿后再审同一会话,直到通过或连续两轮无新增严重问题为止,轮次上限可配置。

一句话选型结论

按资料字段整理

方案文档多轮评审循环是开发类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类开发 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_569675e9/spec-review-loop
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

开发
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_569675e9仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验2026-11-06上游最后核验时间 · 数据更新 2026-11-06
正文体量58.1 KBSKILL.md 原文大小,越大说明说明书写得越细

能做什么

0 项能力
上游给出的能力概览与适用场景
评审 spec 文档评审实施方案多轮改稿直至通过

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
写代码与改 bug

按需求补代码、定位并修掉报错。

读仓库与生成改动

让模型读懂项目结构,再给出可落地的改动。

跑测试与排查故障

按现象排查问题,补测试用例并复跑。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在开发场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
方案文档多轮评审循环当前 未标注权限 未标注 未标注 未标注 有
技能审查员 浏览器控制 ClawHub 市场 877.9 万 OpenClaw 有
Vercel React 最佳实践 浏览器控制 GitHub 仓库 849.1 万 Codex、Claude、Cursor 有
GitHub 代码协作 联网访问 ClawHub 市场 763.3 万 OpenClaw 有
网页设计指南 联网访问 GitHub 仓库 668.6 万 Codex、Claude、Cursor 有
本体论 只读 ClawHub 市场 663.7 万 OpenClaw 有

SKILL.md 全文

58.1 KB
模型实际读到的说明书原文,来自技能仓库

方案评审循环(spec / plan 双轨)

主请求(编排者,唯一写权限) ⇄ codex CLI(只读评审者)交替推进,直到文档收敛。
取代「人肉复制粘贴」和「自己批自己」:评审者默认是 codex CLI(外部模型、独立上下文),每轮 resume 同一会话保持记忆;改稿永远由主请求完成。评审者绝不是本会话里的自己。

适用文档类型与入参解析

类型 性质 判据基准 越界/缺失判定
spec 需求与约束基线("必须满足什么") 自身内部自洽 + 用户范围基线 实现细节缺失=plan 职责,不算 P0(标 owner=plan)
plan 可执行实施计划("怎么做") 其声明的 spec 基线版本 + 自身可执行性 ①违反 spec 冻结契约=P0;②spec 未定义却自行拍板=P0/P1;③实现细节缺失=P1(属本类型职责)

判定方法:文档头部若自称"需求与约束基线 / 不含实现方式"→ spec;若含任务步骤、文件路径、命令、执行顺序 → plan。

入参解析(用户只说「评审 <path>」时)

用户往往只给一句话 + 一个路径。按此表解析,不要为可自行判断的事反复追问:

用户输入 动作
「评审 &lt;文件路径&gt;」(单独) 建议模式(默认):判定类型,调用 codex 单轮评审并给建议;完成后结束,不动文档、不续跑。
建议模式写入 review-state.json:doc、mode:&quot;advisory&quot;、round:0、codex_thread_id、reviewed_at、doc_fingerprint 与 size_baseline。
「评审并改进 / 按评审改 / 循环评审 &lt;文件路径&gt;」 循环模式:直接起轮次(见编排流程·循环模式),评审→改稿→评审→改稿直到收敛
「评审」+ 自然语言描述(无路径) 按描述定位候选文件,列 2~3 个让用户一次选定
「评审 &lt;目录&gt;」 列出该目录候选文档(md 优先、按修改时间倒序),让用户指定
「评审 &lt;代码文件&gt;」(.py/.go/.ts/.js/.sql/.rs 等) 不适用本技能 —— 明确告知这是代码评审请求,改走代码评审流程(已装 superpowers 走其 references/05-code-review.md,或 requesting-code-review),不要硬套 spec/plan 维度
路径不存在 / 读不到 直接报错,并列出同目录最接近的候选文件名,不要静默猜测或退化成"评审上一次那个"
未声明类型且头部无自述 按内容判定;仍不确定 → 在评审 prompt 里同时给出 A/B 两套维度,让评审者自行归类并在 verdict_reason 说明

两种运行模式(核心,务必区分)

模式 触发 行为 改文档? 续跑?
建议模式(默认) 用户单独说「评审 <path>」 调 codex 评审一轮,输出 P0/P1/P2 建议 + verdict + strongest_objection 否(但落盘 review-state.json,mode=advisory) 否(一轮即止)
循环模式 ①新建/写完方案后由主请求主动进入;②用户给建议、主请求改完方案后进入;③显式词「评审并改进/按评审改/循环评审」 codex 评审 → 主请求按评审改稿 → codex resume 再审 → 再改 → 直到收敛(PASS / 连续 2 轮无新 P0·P1 / 达轮次上限(默认 10)) 是(主请求改) 是(review-state.json 续跑)

原则:用户只说"评审"= 只给建议,绝不自动改文档、绝不自动续跑。完整循环只在方案生成/修订工作流中由主请求主动驱动,或用户显式要求"改进/迭代"时触发。
续跑优先原则(仅循环模式):循环模式的「评审 <path>」请求,先查 review-state.json。已 PASS 的文档不自动重跑 —— 重跑前必须让用户确认基线已变更(否则会重复消耗轮次)。
advisory 会话复用(建议模式 → 循环模式):循环第 1 轮前,若存在 mode=advisory 的 review-state.json,重算当前文档 SHA-256 并与 doc_fingerprint 对比。一致 → resume advisory 会话作为循环第 1 轮,不重跑评审、不消耗额外轮次,仅补齐 scope-snapshot.md 等循环模式特有产物;不一致 → 禁止复用,重开会话并注入「当前文档全文 + 旧评审结论(audit-r*.md
若存在,否则对话内 P0/P1 清单)」,轮次从 1 计。advisory resume 调用失败(包括超时或会话不存在)→ 按调用纪律第 4 条 停止并报告,不按本节规则自动重开。上述不一致导致的重开情形中,新会话 thread_id 建立后写回 review-state.json.codex_thread_id,旧 id 追加进 prev_thread_ids[],不得覆盖丢失;旧 advisory 会话保留不删。无 mode=advisory 字段的旧 state
按原「续跑优先原则」处理,保持向后兼容。
默认只读 + 改前确认:本技能会修改目标文档。首次对某文档起轮次时,用一句话说明"评审意见回来后我将按 P0/P1 改该文件(改前备份到评审工作区 .agent/plans/&lt;doc-slug&gt;/,不污染文档目录)",除非用户此前已明确授权自动修。

核心约束(必读)

约束 内容
单向编排 主请求是编排者,codex 是被调用的只读评审者。评审者不改稿,也不得反向派单
评审者只读 codex 以 -s danger-full-access 运行(2026-10-12 用户拍板:-s read-only 沙箱在本机有自竞态故障,见 §4.8 第 8 条);只读靠三件套兜底——① prompt 明确禁止改稿,② jsonl 逐轮写操作审计(正则扫写盘类命令),③ 文档指纹(SHA-256)前后比对
修改权在主请求 所有文档改动由主请求在会话里做
上下文连续 首选 resume 同一 thread_id(换文档 / 换基线才开新会话);resume 已实测恢复可用(2026-10-12,alpha.17.2)。resume 失败 → 按调用纪律第 4 条 退出报用户,不做自动降级兜底(2026-10-12 用户拍板)
基线版本锁定 plan 评审时对照组=该 plan 声明依赖的 spec 版本,不得拿"最新 spec"去挑 plan;版本不符则先记「基线漂移」(P1),再决定是否同步
证据优于声称 引用问题必须带 章节号/行号 或原文关键短语,禁止「感觉不够严谨」类空泛意见
对抗性 每轮评审者必须给出「推翻这份文档的最强三条理由」;确实没有时显式声明 no_strong_objection
范围扩展必须重评审 PASS spec 因用户扩大范围而违反冻结契约时,不得直接据此写 plan;须先更新并重评审。
执行:①同步范围、术语、需求、硬约束、验收、风险、影响面、前置与回滚;②版本 +1,注明范围扩展重评审;③ resume 同一会话至收敛;④ plan 依赖新版本。
会话 id 必报 每轮汇报与最终结束汇报都必须向用户给出 codex thread_id,并同步落盘 review-state.json.codex_thread_id(两处必须一致)—— 用户下次要接着评审时直接 resume 它,不重开会话

评审者优先级与 Claude 路由

评审者选择顺序

新评审循环开始时,按以下优先级选择评审者(顺序不可变):

  1. 当前循环 Codex override(review-state.json.override.scope=current_cycle 且未取消)
  2. 持续 Codex override(reviewer-routing.json.force_codex=true 且未取消)
  3. 安全外部同名 Claude 专职子评审员(spec-reviewer / plan-reviewer,read_only=true 且可调用)
  4. Skill 内捆绑 Claude 专职子评审员(agents/reviewers.json,通过 --agents 注入)
  5. Codex CLI

记录 discovery.source 为 external、bundled 或 none。文档类型必须精确匹配:spec 只用 spec-reviewer,plan 只用 plan-reviewer。仅存在另一类型评审员或通用代理时按无匹配处理,直接走 Codex CLI。非用户事件不得携带 user_choice;携带时返回 stop_report,不发起评审调用。

Claude 调用与模型锁定

Claude 调用统一使用 references/run-claude-review.ps1,以原生 claude.exe 执行,限制 --tools Read,Grep,Glob 与 --strict-mcp-config。所有模型分辨率规则:

  1. 新循环:reviewer-routing.json.claude_model → agent 定义中的显式模型 → Claude CLI 默认
  2. 第一次成功调用后记录实际模型到 reviewer.model 与 reviewer.model_source;后续轮次锁定该模型
  3. 修改 claude_model 只影响新循环,不影响本循环后续轮次
  4. 无法取得实际模型时记 unknown,按失败规则处理

Claude 会话续接使用 --resume &lt;session_id&gt;;同一循环内所有轮次使用同一会话。不同循环不复用旧循环会话。

失败与回退

一次 Claude 评审调用成功要求返回可解析 JSON、包含有效 verdict 且符合输出契约。启动失败、超时、非零退出、envelope 错误、结果解析失败或 schema 不合格均为一次调用失败。初始调用失败自动重试一次;重试仍失败后按编排模型分派:

编排模型 动作
Codex 弹出结构化选择:再发起一次 Claude 调用 / 改用 Codex CLI / 停止本轮
非 Codex 自动改用 Codex CLI 完成本轮,并记录 fallback
无法判定 暂停并询问用户,不静默选择

用户选择"改由 Codex"后,本循环后续所有轮次保持 Codex;Codex 始终以新会话开始,不得复用 Claude session ID。用户选择"停止本轮"后状态标记 interrupted,不报 PASS,不改文档。

reviewer-routing.json 配置

位于 skill 根目录 reviewer-routing.json(即 $env:USERPROFILE\.agents\skills\spec-review-loop\reviewer-routing.json),不存在时使用默认值:

{
  &quot;force_codex&quot;: false,
  &quot;timeout_seconds&quot;: 240,
  &quot;claude_model&quot;: null,
  &quot;set_at&quot;: null,
  &quot;cancelled_at&quot;: null
}
  • force_codex:true 期间即使发现匹配 Claude 代理也调用 Codex
  • timeout_seconds:Claude CLI 超时(1–2147483,默认 240)
  • claude_model:非空时覆盖 agent 定义与 CLI 默认
  • 无效 JSON 或无效值返回 configuration_error,不发起评审调用,不修改 review state
  • 持续 override 取消时设置 cancelled_at;取消后新循环恢复发现流程

状态字段

review-state.json 新增字段(兼容旧状态):

  • reviewer.provider:claude 或 codex-cli
  • reviewer.type:spec-reviewer / plan-reviewer / codex-cli
  • reviewer.session_id:Claude 会话 ID(可续接时记录);Codex 继续写 codex_thread_id
  • reviewer.model 与 reviewer.model_source:Claude 实际模型与来源
  • reviewer.selected_at:选择时间
  • discovery.source / discovery.matched / discovery.candidates / discovery.callable
  • history[] 每轮:provider、reviewer_type、session_id(若有)、context_mode(resume/context_pass/none)
  • fallback:from / to / stage / reason / auto_retry_count / decision_source / time / failed_session_id(Claude 失败后切 Codex 时记录)
  • override:scope / set_at / cancelled_at

旧状态若只有 codex_thread_id,按 Codex CLI 循环续跑,不重新发现 Claude 评审员,不迁移。切换到 Codex 后,Claude session ID 只保留在 history[] 和 fallback 记录中。

.pi junction 不变式

$env:USERPROFILE\.pi\agent\skills\spec-review-loop 是指向 $env:USERPROFILE\.agents\skills\spec-review-loop 的目录 junction,不是独立副本。不得在 .pi\references 或 .pi\agents 维护内容副本。

评审者调用:codex CLI

4.1 能力与默认模型

能力 codex CLI(默认主路径) 同模型子代理(仅限无 codex 的环境且用户显式授权)
起一轮评审 codex exec ... - &lt; prompt.txt(见 §4.5 模板) Agent(subagent_type=general-purpose)
续跑同一评审者 codex exec resume &lt;thread_id&gt; ...,id 存 review-state.json.codex_thread_id Agent(resume=&lt;agent_id&gt;),id 存 review-state.json.agent_id
只读保证 三件套,见 §4.3 prompt 约束 + 环境只读子代理
结构化输出 --output-schema &lt;schema.json&gt;(强制 JSON,直接可解析;2026-10-12 拍板解禁:alpha.2 的 node.exe 持锁故障在 0.162.0-alpha.17.2 三组探针复测未复现;编排者保留 json.loads 解析失败 → 该轮不计的兜底) 靠 prompt 约束
会话内消息续轮 不适用(用 resume) ⚠ 不可用:SendMessage 报 Not in a team
独立性 高(外部模型、独立上下文;与改稿者同一套权重和先验易产生确认偏差) 低(同模型自评,必须在 verdict_reason 标注)
成本 / 延迟 较高(启动 40–60s 为 0.155 时代实测;2026-10-10 评审轮单轮全程 133–413s) 低
默认模型 -m gpt-6-luna(2026-09-24 用户指定;本机 ~/.codex/config.toml 的 model 值若不同,以模板显式写的为准)。该值随账号/套餐可能变化,每次调用都显式带上,不依赖配置默认;换模型只改本行;全文其余模板/示例一律写 &lt;REVIEW_MODEL&gt; 占位符,执行时替换为本行实际值

评审者 = codex CLI(外部模型),每轮都走,不允许静默换成同模型。

4.2 调用纪律(五条,2026-09-30 用户确认)

# 纪律 内容
1 禁止 WSL codex 一律在 Windows 原生环境调用(Git Bash / PowerShell 直接跑 exe),不得借道 WSL
2 prompt 走 stdin codex exec ... - &lt; review-prompt.txt 是官方正规用法(帮助文档明示),v1.2.0 起多轮实测可靠、不受 Windows 32KB 参数限制。prompt 只写路径 + 评审维度 + 输出要求,保持精简
3 让 codex 自己读文件 评审材料不内联进 prompt——文档路径、spec 基线路径、代码位置用路径引用,由 codex 在 -C 项目根下自己读,resume 模式下保留上轮上下文。禁止把文档全文、源码 grep 结果塞进 prompt
4 失败即停即报 单轮总尝试≤3,首调计1。CLI启动前准备错(缺二进制、参数/配置、prompt/schema)修正后可重跑。启动后仅退出码0且JSONL空、JSON解析失败、schema不符或缺verdict可重跑;记录命令、退出码、宿主错误流(空文件无ERROR行)。非零退出(含参数解析/鉴权/限流/版本)立即停止汇报。网络刷新超时至多重试1次,计入总数。
5 执行器适配 只有 PowerShell 执行器的会话禁止照抄 Bash 模板(炸点:&lt; 输入重定向、VAR=x cmd 前缀、[ -x ]、$(ls)),一律用§4.5的 pwsh 版模板

4.3 只读三件套(2026-10-12 实测)

评审者使用 -s danger-full-access。只读由三件套保证:prompt 明确禁止改稿;逐轮审计 JSONL 写操作;调用前后比对目标文档 SHA-256。其他文件另以 git status --short 核查。

4.4 代理策略(2026-09-24 用户确认)

codex 调用固定走 http://127.0.0.1:10808,不使用可能指向不可达 sandbox-cli.exe 的会话代理。先按各执行器下列命令探测;非 200 按调用纪律第 4 条停止。config.toml 的 proxy 键无效。
Bash 会话先 export 四个代理变量,再探测(curl.exe,与 pwsh 同一判据):

export HTTP_PROXY=http://127.0.0.1:10808 HTTPS_PROXY=http://127.0.0.1:10808
export http_proxy=http://127.0.0.1:10808 https_proxy=http://127.0.0.1:10808
PROXY=http://127.0.0.1:10808
code=$(curl.exe -s -o /dev/null -w &#x27;%{http_code}&#x27; --max-time 8 -x &quot;$PROXY&quot; https://chatgpt.com/) || { echo &quot;代理探测失败: curl exit $?&quot; &gt;&amp;2; exit 1; }
if [ &quot;$code&quot; != 200 ]; then echo &quot;代理探测失败: HTTP $code&quot; &gt;&amp;2; exit 1; fi

4.5 调用模板:按执行器选择

  • 按当前执行器选择模板:PowerShell 会话用 pwsh,Bash 会话用 Bash;不确定时先探测,不猜。pwsh 不支持 &lt; 或 VAR=value cmd,PATH 上的 bash 可能是 WSL;需要 Bash 时写死 Git Bash 路径。

以下模板仅用于 pwsh 7.4+。先设置本轮变量,再按轮次执行对应模板。
PowerShell 模板共用以下环境保存/恢复函数;每个模板调用 Set-ReviewProxy,并在 finally 调 Restore-ReviewProxy:

$ReviewProxyNames = @(&#x27;HTTP_PROXY&#x27;, &#x27;HTTPS_PROXY&#x27;, &#x27;http_proxy&#x27;, &#x27;https_proxy&#x27;)
function Set-ReviewProxy([string]$Proxy) {
  $script:ReviewProxyPrevious = @{}
  foreach ($name in $ReviewProxyNames) { $script:ReviewProxyPrevious[$name] = [Environment]::GetEnvironmentVariable($name, &#x27;Process&#x27;) }
  $env:HTTP_PROXY = $Proxy; $env:HTTPS_PROXY = $Proxy
  $env:http_proxy = $Proxy; $env:https_proxy = $Proxy
}
function Restore-ReviewProxy {
  foreach ($name in $ReviewProxyNames) {
    if ($null -eq $script:ReviewProxyPrevious[$name]) { Remove-Item &quot;Env:$name&quot; -ErrorAction SilentlyContinue }
    else { Set-Item -Path &quot;Env:$name&quot; -Value $script:ReviewProxyPrevious[$name] }
  }
}

PowerShell:变量与二进制定位(三保险)

$Model = &#x27;gpt-6-luna&#x27; # 换模型只改本行
$Project = &#x27;D:\path\to\project-root&#x27;
$OutDir = &#x27;D:\path\to\.agent\plans\&lt;doc-slug&gt;&#x27;
$PromptFile = Join-Path $OutDir &#x27;review-prompt.txt&#x27;
$CodexBin = Join-Path $HOME &#x27;.local\bin\codex.cmd&#x27;
if (-not (Test-Path $CodexBin)) {
  $p = (Select-String (Join-Path $HOME &#x27;.codex\config.toml&#x27;) &#x27;CODEX_CLI_PATH&#x27; | Select-Object -First 1).Line -replace &quot;^[^&#x27;]*&#x27;&quot;, &#x27;&#x27; -replace &quot;&#x27;\s*$&quot;, &#x27;&#x27;
  if ($p -and (Test-Path $p)) { $CodexBin = $p }
}
if (-not (Test-Path $CodexBin)) {
  $d = Get-ChildItem (Join-Path $env:LOCALAPPDATA &#x27;OpenAI\Codex\bin&#x27;) -Directory | Sort-Object LastWriteTime -Descending | Where-Object { Test-Path (Join-Path $_.FullName &#x27;codex.exe&#x27;) } | Select-Object -First 1
  if ($d) { $CodexBin = Join-Path $d.FullName &#x27;codex.exe&#x27; }
}
if (-not (Test-Path $CodexBin)) { throw &#x27;[codex] 未找到可用的 codex CLI&#x27; }
&amp; $CodexBin --version

PowerShell 代理探测

$proxy = &#x27;http://127.0.0.1:10808&#x27;
$code = &amp; curl.exe -s -o NUL -w &#x27;%{http_code}&#x27; --max-time 8 -x $proxy https://chatgpt.com/
if ($code -ne &#x27;200&#x27;) { throw &quot;代理 $proxy 探测失败: $code(按调用纪律第 4 条 停止)&quot; }

必须调用 curl.exe(真实 curl),不要调用 pwsh 的 curl 别名(即 Invoke-WebRequest,没有 -w 参数)。

PowerShell 首轮(新会话)

$proxy = &#x27;http://127.0.0.1:10808&#x27;
$JsonlPath = Join-Path $OutDir &#x27;codex-r1.jsonl&#x27;
try {
  Set-ReviewProxy $proxy
  Get-Content -Raw -Encoding UTF8 $PromptFile | &amp; $CodexBin exec -m $Model -s danger-full-access --skip-git-repo-check `
    -C $Project --json --output-schema (Join-Path $OutDir &#x27;review-schema.json&#x27;) - 2&gt;&amp;1 | Out-File -Encoding utf8NoBOM $JsonlPath
  $codexExitCode = $LASTEXITCODE
  if ($codexExitCode -ne 0) { throw &quot;codex exec 失败,退出码: $codexExitCode&quot; }
  if ((Get-Item $JsonlPath).Length -eq 0) { throw &#x27;codex-r1.jsonl 为 0 字节;按调用纪律第 4 条记录命令与宿主错误流后,方可重跑同轮&#x27; }
} finally {
  Restore-ReviewProxy
}
# thread_id 取首行:{&quot;type&quot;:&quot;thread.started&quot;,&quot;thread_id&quot;:&quot;...&quot;}

PowerShell 后续轮(resume)

$ThreadId = (Get-Content (Join-Path $OutDir &#x27;review-state.json&#x27;) -Raw | ConvertFrom-Json).codex_thread_id
$PromptFile = Join-Path $OutDir &#x27;review-prompt-rN.txt&#x27;
$proxy = &#x27;http://127.0.0.1:10808&#x27;
$JsonlPath = Join-Path $OutDir &#x27;codex-rN.jsonl&#x27;
Push-Location $Project   # resume 继承首轮 cwd;显式切到同一项目根
try {
  Set-ReviewProxy $proxy
  Get-Content -Raw -Encoding UTF8 $PromptFile | &amp; $CodexBin exec resume $ThreadId -m $Model --skip-git-repo-check `
    --json --output-schema (Join-Path $OutDir &#x27;review-schema.json&#x27;) - 2&gt;&amp;1 | Out-File -Encoding utf8NoBOM $JsonlPath
  $codexExitCode = $LASTEXITCODE
  if ($codexExitCode -ne 0) { throw &quot;codex exec resume 失败,退出码: $codexExitCode&quot; }
  if ((Get-Item $JsonlPath).Length -eq 0) { throw &#x27;codex-rN.jsonl 为 0 字节;按调用纪律第 4 条记录命令与宿主错误流后,方可重跑同轮&#x27; }
} finally {
  try {
  Restore-ReviewProxy
  } finally {
    Pop-Location
  }
}

resume 在同一工作目录执行,不带 -C、-s 或 --color。

Bash 二进制定位(三保险)

本机并存多份 codex CLI,且桌面应用那份不在 PATH(路径含哈希、随应用更新变化)。按下述顺序解析,每一步都必须落到真实可执行的文件上:

# 仅限 Bash 执行器;PowerShell 会话使用 §4.5 中的 pwsh 模板。
CODEX=&quot;&quot;
# ① 稳定入口 shim
[ -x &quot;$HOME/.local/bin/codex&quot; ] &amp;&amp; CODEX=&quot;$HOME/.local/bin/codex&quot;
# ② config.toml 记录的桌面应用 CLI 路径
if [ -z &quot;$CODEX&quot; ]; then
  p=$(grep -m1 &#x27;^[[:space:]]*CODEX_CLI_PATH&#x27; &quot;$HOME/.codex/config.toml&quot; 2&gt;/dev/null \
      | sed &quot;s/^[^&#x27;]*&#x27;//; s/&#x27;[[:space:]]*$//&quot; | tr -d &#x27;\r&#x27; | tr &#x27;\\&#x27; &#x27;/&#x27;)
  [ -n &quot;$p&quot; ] &amp;&amp; [ -x &quot;$p&quot; ] &amp;&amp; CODEX=&quot;$p&quot;
fi
# ③ 按修改时间取最新的哈希目录(务必过滤「确实含 codex.exe」的目录)
if [ -z &quot;$CODEX&quot; ]; then
  for d in $(ls -1dt &quot;$LOCALAPPDATA/OpenAI/Codex/bin&quot;/*/ 2&gt;/dev/null); do
    [ -x &quot;${d}codex.exe&quot; ] &amp;&amp; CODEX=&quot;${d}codex.exe&quot; &amp;&amp; break
  done
fi
[ -n &quot;$CODEX&quot; ] || { echo &quot;[codex] 未找到可用的 codex CLI&quot; &gt;&amp;2; exit 127; }
&quot;$CODEX&quot; --version    # 自检:版本过低会驱动不了新模型(见下)
事项 说明
CLI 定位 禁止用 ls ... | head -1;按时间倒序,并过滤真实含 codex.exe 的目录。
版本 &quot;$CODEX&quot; --version 可用;若提示模型要求更新客户端,按 §4.8 第 5 条处理。
稳定入口与历史坑 优先本机 ~/.local/bin/codex shim;standalone PATH 案例见 references/troubleshooting.md#历史坑。
#### Bash 首轮
先执行 §4.4 的 Bash export 块。
&quot;$CODEX&quot; exec -m &lt;REVIEW_MODEL&gt; -s danger-full-access --skip-git-repo-check \
  -C &lt;被测代码/项目根&gt; --json \
  --output-schema &lt;out-dir&gt;/review-schema.json \
  - &lt; &lt;out-dir&gt;/review-prompt.txt &gt; &lt;out-dir&gt;/codex-r1.jsonl 2&gt;&amp;1
  • 从首行读取 thread_id;最终结论取最后一个带 text 的 item.completed 项。

Bash 后续轮(resume)

复用当前 shell 中 §4.4 设置的代理变量。

&quot;$CODEX&quot; exec resume &lt;thread_id&gt; -m &lt;REVIEW_MODEL&gt; --skip-git-repo-check \
  --json --output-schema &lt;out-dir&gt;/review-schema.json \
  - &lt; &lt;out-dir&gt;/review-prompt-rN.txt &gt; &lt;out-dir&gt;/codex-rN.jsonl 2&gt;&amp;1

resume 恢复同一会话上下文;失败按调用纪律第 4 条停止。

4.6 参数坑

坑 事实
-s 只在首轮 exec 写(现行值 -s danger-full-access)。resume 不接受 -s;带上会报 unexpected argument &#x27;-s&#x27; found,且 JSONL 可为 0 字节。按纪律 4 依据退出码分类,不从空文件读 ERROR 或重跑。
--color exec 接受、resume 不接受,带上直接退出码 2(unexpected argument &#x27;--color&#x27;)
-C exec 接受、resume 不接受(2026-10-10 实测退出码 2);resume 继承首轮 cwd,会话按 cwd 过滤,必须在同一工作目录执行
--ephemeral 不持久化会话 → 与 resume 互斥,绝不要加(会话落盘是 jsonl 审计的依据)
--output-schema 恢复使用(2026-10-12 用户拍板解禁,见 §4.8 第 8 条);strict 对象须 additionalProperties:false 且列全 required;最终 JSON 解析失败按调用纪律第 4 条处理
sandbox_mode 默认 首轮 exec 显式设置,避免配置漂移(2026-10-12 拍板)

参数坑背景与实测速查见 references/troubleshooting.md#参数坑;完整事实以本节表格为准。

4.7 审计与状态恢复

每轮自检:记录退出码、JSONL 字节和尝试数(首调计1,共≤3)。非零退出按纪律4停;退出码0但JSONL空、解析失败、schema不符或缺verdict时,记命令、退出码及宿主错误流(空文件无ERROR行)后可重跑。成功提取thread_id/verdict并落audit-rN.md。
无效轮次:verdict 依据是无法读取文件/环境故障(§4.8 第 7 条)时不计轮次;关键是评审者确实读到材料。
写操作审计(三件套第 2 项,2026-10-12 沉淀):每轮解析 codex-rN.jsonl 全部命令事件,按正则扫写操作嫌疑:Set-Content|Out-File|Add-Content|Remove-Item|New-Item|rm -|mv |cp |copy |&gt;&gt;|echo .*&gt;|tee|sed -i|del |rmdir|touch;命中 → 立即停下报用户。判败标记:helper_unknown_error(见失败处理第 8 条)。resume
会话审计盲区(2026-10-12 实测)
:resume 路径的 JSONL 中命令事件可能只有 item.started(aggregated_output 为空、状态 in_progress、无 completed)——命令真实执行但过程记录缺失,故审计须同时扫 started 事件的 command 字段做写操作比对(命令原文在 started 里就有,只是没有退出码和输出);该盲区下 git status + 文档指纹兜底权重更高。
其他文件变更兜底(三件套之三):每轮审计后在项目根跑 git status --short,确认除评审工作区(.agent/)外无任何变更;有 → 立即报告。非 git 项目跳过此检查,仅依赖 jsonl 审计 + 文档指纹。

4.8 失败处理:报错停下,不降级

CLI 已启动后退出码非零(未登录 / 限流 / 超时 / 版本不符 / 参数解析失败等)时,立即停止并向用户报错,不得静默改用同模型子代理。网络刷新请求超时仅可按第 3 项重试一次,计入调用纪律第 4 条的单轮总尝试上限 3 次。排查顺序:

  1. &quot;$CODEX&quot; --version:核对模型所需的 CLI 版本。
  2. 登录态:鉴权失败即停下报告。
  3. codex-rN.jsonl 的 ERROR:模型刷新超时最多重试一次;再次失败即停,不重开或降级。
  4. config.toml 告警:核对 proxy、disable_response_storage 等未识别项是否影响链路。
  5. requires a newer version of Codex:换最新版 CLI 或更新桌面应用;不要反复重试。
  6. 代理探测:按 §4.4 检查 10808;非 200 即停。
  7. os error 231(命令宿主管道握手失败,服务端下发 code_mode_only 时触发):按调用纪律第 4 条 停止并报告,不自行改模型缓存。详见 references/failure-archive.md#os-error-231。
  8. helper_unknown_error(-s read-only 沙箱自竞态):评审一律 -s danger-full-access + 三件套兜底,禁用 -s read-only。详见 references/failure-archive.md#helper_unknown_error。

停下后在 review-state.json 记 stop_reason=codex_unavailable + 具体错误,并把上述排查结果反馈用户;不要自行改成子代理继续跑。

  1. 评审者不可用矩阵(2026-10-23~26 plan 24 轮实战沉淀;全部限定在现行纪律内,不推翻「非零退出即停 / resume 失败即停 / 网络刷新超时最多重试一次」任一条):
故障 判定 处置(均不改变现行纪律)
codex 限额(usage limit,含恢复时点提示) 明确拒绝,非瞬态 停止循环并报用户(调用纪律第 4 条);记录服务端提示的恢复时点;是否在恢复后 resume 原 thread 由用户决定——用户说「继续」即构成授权,恢复评审前先探测模型可用性 + 文档指纹未变 + 任务书就绪
网络故障(代理出口/直连均不通,curl 探测 000) 连通性中断 停止并报用户(调用纪律第 4 条);重试一次仅适用于「失败处理」第 3 条的模型刷新超时,连通性探测失败不自动重试——恢复后由用户决定是否续跑
子代理(获授权代跑时)连续 2 次无输出失败 无输出 ≠ 瞬态,是路由不可用 停止代跑并报用户;间隔较久(≥1 天)可再探测一次,仍失败即弃用该路由;每次代跑视为一次性任务,交付后不可复用(实测 send_message 报 not found)
恢复评审(任何中断后) — 先探测(模型可用性 + 文档指纹未变 + 任务书就绪),再按用户指示 resume 原 thread(上下文连续)或重开;任务书缺失时按消息内嵌 fallback(已实测可靠)

4.9 评审输出 JSON Schema

{
  &quot;type&quot;: &quot;object&quot;,
  &quot;properties&quot;: {
    &quot;verdict&quot;: { &quot;type&quot;: &quot;string&quot;, &quot;enum&quot;: [&quot;PASS&quot;, &quot;FAIL&quot;] },
    &quot;p0&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;object&quot;, &quot;properties&quot;: { &quot;loc&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;issue&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;fix&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;evidence&quot;: {&quot;type&quot;:&quot;string&quot;} }, &quot;required&quot;: [&quot;loc&quot;,&quot;issue&quot;,&quot;fix&quot;,&quot;evidence&quot;], &quot;additionalProperties&quot;: false } },
    &quot;p1&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;object&quot;, &quot;properties&quot;: { &quot;loc&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;issue&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;fix&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;evidence&quot;: {&quot;type&quot;:&quot;string&quot;} }, &quot;required&quot;: [&quot;loc&quot;,&quot;issue&quot;,&quot;fix&quot;,&quot;evidence&quot;], &quot;additionalProperties&quot;: false } },
    &quot;p2&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;object&quot;, &quot;properties&quot;: { &quot;loc&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;issue&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;fix&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;evidence&quot;: {&quot;type&quot;:&quot;string&quot;} }, &quot;required&quot;: [&quot;loc&quot;,&quot;issue&quot;,&quot;fix&quot;,&quot;evidence&quot;], &quot;additionalProperties&quot;: false } },
    &quot;spec_conflicts&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;object&quot;, &quot;properties&quot;: { &quot;plan_loc&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;spec_clause&quot;: {&quot;type&quot;:&quot;string&quot;}, &quot;kind&quot;: {&quot;type&quot;:&quot;string&quot;,&quot;enum&quot;:[&quot;违反&quot;,&quot;未覆盖&quot;,&quot;扩展&quot;]}, &quot;fix&quot;: {&quot;type&quot;:&quot;string&quot;} }, &quot;required&quot;: [&quot;plan_loc&quot;,&quot;spec_clause&quot;,&quot;kind&quot;,&quot;fix&quot;], &quot;additionalProperties&quot;: false } },
    &quot;out_of_scope&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; } },
    &quot;unresolved_ack&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; } },
    &quot;already_declared&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; } },
    &quot;strongest_objection&quot;: { &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; } },
    &quot;verdict_reason&quot;: { &quot;type&quot;: &quot;string&quot; }
  },
  &quot;required&quot;: [&quot;verdict&quot;,&quot;p0&quot;,&quot;p1&quot;,&quot;p2&quot;,&quot;spec_conflicts&quot;,&quot;out_of_scope&quot;,&quot;unresolved_ack&quot;,&quot;already_declared&quot;,&quot;strongest_objection&quot;,&quot;verdict_reason&quot;],
  &quot;additionalProperties&quot;: false
}

数组字段没有内容时返回 [],不要省略字段。

评审 prompt 模板

通用段落(两类共用)

codex 是独立进程。按调用纪律第 2、3 条,prompt 只给路径、维度与输出要求,材料由 codex 自己读取:

你是只读评审者。禁止修改、创建、删除任何文件,禁止一切写盘操作(当前运行无沙箱物理限制,只读靠你自觉遵守,调用方会做事后写操作审计与文档指纹比对)。

目标文档(唯一真源):&lt;绝对路径&gt;
冻结范围基线:&lt;out-dir&gt;/scope-snapshot.md
未决意见清单:&lt;out-dir&gt;/unresolved.md(可能不存在)
项目约束:&lt;可选,如 AGENTS.md 路径&gt;

(可选增强)若当前环境已装 `superpowers` 技能,可加载该技能目录下的 `references/05-code-review.md` 作为补充纪律;未装则跳过,直接按下方维度评审——本模板已自包含,不依赖任何外部技能,不要为缺少 superpowers 而中断评审。

A 类:spec 评审维度

1. 内部一致性——章节/术语/数字互相矛盾之处
2. 可执行性——步骤能否照做;命令、路径、参数、文件名是否齐全且真实存在
3. 范围边界——是否超出冻结范围;超出项标 in_scope=false
4. 风险与回滚——失败模式是否覆盖,回滚是否可执行
5. 验收标准——是否给出可验证断言(不是「测试通过」这种空话)
6. 遗漏——该有而没有的章节/字段/边界情况

B 类:plan 评审维度(第 1 条最重要,不得省)

引用 spec 条款时须给 §号 + 原文关键短语。

1. 【最高优先】spec 符合度——逐条核对 plan 的每个决定是否与 &lt;spec 路径&gt;(版本 &lt;spec rev&gt;)的冻结契约一致。
   必须分三类列出:
   - 违反:plan 的决定与 spec 冻结契约冲突
   - 未覆盖:spec 要求了,plan 没有对应编排
   - 擅自扩展:spec 未定义,plan 自行拍板(须回写 spec 或降为待定项)
2. 未闭合契约误用——plan 是否把 spec 声明为「未闭合 / 待实测」的契约当作已闭合使用
3. 可执行性——每个任务步骤能否直接照做:文件路径、命令、参数、前置条件、预期输出是否齐全
4. 任务粒度与顺序——是否小到可单次完成;依赖是否显式;有无循环依赖;可否并行
5. 验证步骤——每个任务是否带验证方法(如何确认做对了),是否可自动断言
6. 回滚点——破坏性操作(改表、删数据、改配置、切换状态)是否有回滚/备份步骤
7. 范围——是否超出 spec 范围
8. 遗漏——spec 要求但 plan 未编排的部分
9. Spec 判据宽严 diff——把 plan 的每个验收判据/触发条件与 spec 冻结条文逐条对比;差异**按基线既有三分类映射**(不得把宽严差异都记「扩展」):
   与冻结条文**冲突**(含&quot;更严但无授权&quot;——spec 允许的场景被无依据收紧)→ kind=违反;
    spec **要求**了但 plan 没有对应编排 → kind=未覆盖;
    spec **未定义**且 plan 自行拍板(更宽的触发/豁免/降级,或新增约束)→ kind=扩展;
    扩展若属安全方向,可标注「待 spec 升版追认」,但**必须登记**——只看&quot;plan 是否自洽&quot;抓不到这类漂移,必须回到 spec 原文逐条对。
10. 关键命令实测级验证——对方案中的关键脚本/判据,做超出&quot;通读&quot;的实测验证:
    `bash -n` 语法检查、纯内建替身推演(**按方案实际使用的外部命令/判据**构造函数替身模拟各分支——shell 方案常用 ps/test 作替身对象,其他类型方案按需选择,非固定要求)、配置 JSON 解析、
    正则与测试函数名的匹配计数。纯&quot;读&quot;抓不到运行时缺陷(如恒假表达式、退出码被管道掩盖)。

输出格式(两类共用,plan 多一栏)

{&quot;verdict&quot;:&quot;FAIL&quot;,&quot;p0&quot;:[{&quot;loc&quot;:&quot;§1&quot;,&quot;issue&quot;:&quot;...&quot;,&quot;fix&quot;:&quot;...&quot;,&quot;evidence&quot;:&quot;...&quot;}],&quot;p1&quot;:[],&quot;p2&quot;:[],&quot;spec_conflicts&quot;:[{&quot;plan_loc&quot;:&quot;§2&quot;,&quot;spec_clause&quot;:&quot;§1 范围&quot;,&quot;kind&quot;:&quot;违反&quot;,&quot;fix&quot;:&quot;...&quot;}],&quot;out_of_scope&quot;:[],&quot;unresolved_ack&quot;:[],&quot;already_declared&quot;:[],&quot;strongest_objection&quot;:[&quot;...&quot;],&quot;verdict_reason&quot;:&quot;...&quot;}

说明:p1/p2 元素同 p0;kind 取「违反/未覆盖/扩展」;空数组保持 []。
判定规则:p0 非空 → FAIL;p0 空且 p1 非空 → FAIL;p0/p1 均空 → PASS(机读判定不变)。
分级映射(引用 05-code-review.md L11-15,已装时):Critical(不符合规格/会炸生产/丢功能)→ P0;
Major(明显质量债/验收判据失真/不可执行)→ P1;Minor(风格/命名/文档一致性)→ P2。
未装 05-code-review 时按同语义自行分级并在 verdict_reason 声明所用口径。
p0 = 会导致实现出错或验收失效的阻断项;p1 = 应修但不阻断;p2 = 可选优化。

首轮任务书组装清单(循环模式第 1 轮按此组装;后续轮按需增删)

通用段落 + A/B 类维度之外,按方案特征追加专项指令——首轮就下发,不要等评审者自己发现
(实战:状态组合漏洞晚加 5 轮才被点名):

方案特征 必追加的专项指令
含状态机 / 清理流程 / 多门槛联动 状态组合穷举:先从方案(或其声明的 spec/设计)提取状态集合与判定规则——不预设互斥性、优先级、fail-closed 的答案,仅在方案自身声明了这些性质时核验其声明与实现一致;穷举各组合路径,核对「状态分类 → 判定 → 分流 → 证据保全」多处的一致性;对「方案未定义但实现暗含」的状态组合,标为遗漏
含回滚 / 分级恢复 回滚材料唯一源核对 + 回滚后状态与恢复守卫的联动 + 备份自身的完整性(自哈希/自覆盖类缺陷)
含后台进程 / watchdog / 采样 进程生命周期核对:启动参数与 PID 记录、身份校验(唯一标识,非通用字符串)、退出路径、证据归档、遗留进程对后续任务的影响
含数学阈值 / 计数断言 阈值可达性验算(采样粒度 × 点数 vs 窗口时长的边界余量;判据在"最自然执行"下是否可达)
含外部接口 / 环境依赖 可达性探针的时点覆盖(只在初始化时测一次不够——使用点前须复测)、依赖工具存在性检查

编排流程与产物布局

6.1 产物布局

&lt;out-dir&gt;/
├── scope-snapshot.md
├── audit-r1.md / audit-rN.md
├── unresolved.md
├── review-prompt.txt / review-prompt-rN.txt
├── codex-rN.jsonl(含 stderr)
├── review-schema.json
├── doc.rev&lt;N&gt;.bak.md
└── review-state.json
字段 必填 用途
doc 必填 目标文档路径
doc_rev 必填 目标文档版本
round 必填 当前轮次
reviewer 必填 评审者类型
model 必填 评审模型
codex_thread_id 必填 当前评审会话 ID
last_p0p1_signature 必填 最近 P0/P1 签名
no_new_p0p1_streak 必填 连续无新 P0/P1 轮数
stop_reason 必填 停止原因
history[] 必填 历轮记录
mode 必填 advisory 或循环模式
reviewed_at 必填 评审时间(ISO 8601)
doc_fingerprint 必填 评审对象 SHA-256
baseline_input_tokens 条件必填 复用模式的输入 token 基线
size_baseline 必填 初始体积基线
prev_thread_ids[] 条件必填 重开会话时保存旧 ID
doc_fingerprint_final 条件必填 PASS 后修正的终稿指纹
doc_fingerprint_note 条件必填 两个指纹差异说明
regression_note 可选 同类回归记录
orchestration_note 可选 编排疏漏记录

表中必填性针对循环模式;建议模式仅需 doc/mode/round/codex_thread_id/reviewed_at/doc_fingerprint/size_baseline 七项。

PASS 后工作区处置:建议保留 audit-r*.md / review-state.json / unresolved.md;备份和临时评审材料可删除,是否删除由用户决定,不自动删。
改文档前先备份:备份文件必须放进评审工作区 &lt;out-dir&gt;/doc.rev&lt;N&gt;.bak.md(N=轮次,每轮改稿前复制一份当前版本)。
&lt;out-dir&gt; = .agent\plans\&lt;doc-slug&gt;($OutDir 已含)。
禁止把 .bak 落在正式文档所在目录;历史坑详见 references/troubleshooting.md#历史坑。
review-state.json 是断点续跑的唯一依据。会话上下文丢失后读它即可恢复,不要从第 1 轮重来。
unresolved.md 只登记三类:改不动(技术/成本限制)、等用户拍板、明确不采纳。一行一条:

- [P1] 章节 4.2 建议补 backfill 断点续传 —— 等用户拍板(成本待评估)

多会话并行写同一批产物(2026-09-24 实战):实施会话可能也在更新同一 spec/plan 的 unresolved.md(如实施中登记负责人确认)。改前必须重读最新文件再 Edit(撞 Edit 冲突就是并行写的信号);合并时保留两边记录、注明各自时间与来源会话,不要用旧内容覆盖新登记。

建议模式(单独评审,默认)

  1. 读文件头部判定类型(spec / plan)。
  2. 调 codex 评审一轮(见 §4.5模板),按 A/B 类维度输出 P0/P1/P2 建议 + verdict + strongest_objection。
  3. 落盘轻量 review-state.json:记录 doc、mode:&quot;advisory&quot;、round:0、codex_thread_id、reviewed_at(ISO 8601,落盘时点)、doc_fingerprint(SHA-256)与 size_baseline。
  4. 向用户汇报建议;结束,不改文档、不续跑。
  5. 若用户认可建议并要落地,转入下方循环模式,先按§3 核心约束·advisory 会话复用判定;指纹一致则直接复用评审结论,不消耗新一轮。

6.2 第 1 轮与循环启动

循环第 1 轮
0. 若存在 mode=advisory 的 review-state.json,先按「advisory 会话复用(建议模式 → 循环模式)」判定;一致时复用 advisory 会话并将其作为第 1 轮,不重跑评审、不消耗轮次。
1. 冻结范围基线:写 &lt;out-dir&gt;/scope-snapshot.md。
- spec:优先抽取 &lt;!-- SCOPE:START --&gt;...&lt;!-- SCOPE:END --&gt; 区块,没有则提取 §1 范围段 + 章节标题。
- plan:额外冻结「依赖的 spec 路径 + spec rev + 该 spec 的未闭合项清单」(plan 评审的对照锚点)。
2. 调 codex 起新会话评审:先把 &lt;out-dir&gt;/review-schema.json 与评审 prompt 落盘,执行后从 JSONL 首行取 thread_id 存进 review-state.json.codex_thread_id。
3. 读结论 → 落盘 audit-r1.md → 按 P0/P1 改文档 → 更新 unresolved.md。
4. 向用户汇报:本轮改了什么、还剩什么、下一步。

6.3 第 N+1 轮

  1. 优先 resume 同一 codex 会话(codex exec resume &lt;thread_id&gt; ...),保留上下文、避免重复提已修意见。实测该方式下 codex 能回忆上轮读过哪些文件,不会重读盘。resume 已实测恢复可用(2026-10-12,alpha.17.2);调用失败 → 按调用纪律第 4 条 退出报用户,不自动降级(用户拍板)。
    - thread_id 取自 review-state.json.codex_thread_id。出现以下任一信号时触发统一兜底:① thread_id 丢失;② 单轮 JSONL token 计数事件的 input_tokens > 基线轮的 3 倍(基线轮为复用时的 advisory 轮,否则为循环第 1 轮;基线值记入 review-state.json.baseline_input_tokens);③ 结论明显退化(重复提已修意见、自相矛盾、verdict
    依据与前轮冲突)。JSONL 无 input_tokens 字段或值为 0 时,token 倍率判据停用,不算故障,仅信号③仍可触发。
    - 兜底时重开会话,注入「最近 audit-rN.md 摘要 + unresolved.md」;若 unresolved.md 不存在,注入「无未决意见」或跳过该文件,不得阻止切换。新会话 thread_id 写回 review-state.json.codex_thread_id,旧 id 追加进 prev_thread_ids[],不得覆盖丢失。
    - 本节「重开会话」仅针对信号①②③;resume 命令本身调用失败仍按调用纪律第 4 条 停止,二者不冲突。
    - 任何情况下都以 review-state.json 为断点续跑唯一依据;会话上下文丢失后读它恢复,不要从第 1 轮重来。
  2. 重复第 3~4 步,轮次 +1。

codex 调用参数选择

参数 用法
-m, --model 显式写 &lt;REVIEW_MODEL&gt;(实际值见§4.1 模型行;不写则吃 config.toml 静默漂移)
-C, --cd 指向被测代码 / 项目根(评审 plan 时给项目根,不是文档所在目录)
-s danger-full-access 必带,显式写防配置漂移(read-only 沙箱有自竞态故障,失败处理第 8 条)
--output-schema 必带(强制 JSON 输出,2026-10-12 解禁,见参数坑表;schema 文件每轮起轮次前落盘到 &lt;out-dir&gt;/review-schema.json)
--json 必带,用于提取 thread_id 与事件流
--ephemeral 禁用(与 resume 互斥;会话落盘是 jsonl 审计的依据)

改稿纪律(循环模式每轮改稿必做,按顺序四步)

改稿完成后、发起下一轮评审前,必须完成以下机械验证;任何一步以输出为准,不以记忆为准。
未通过 → 修复后重跑该步,不得带着未验证的"已改"进入下一轮。

  1. 逐条意见标志字符串实测:本轮每条 P0/P1 的修法确定一个"标志字符串"(新增的关键短语、
    删除后应消失的旧表述、改写后的新判据),逐条 grep 目标文档:该在的必须在、该删的必须为 0。
    在对话中给出 grep 命令与命中行原文,不写"已修改"三个字。
    标志字符串必须锚定到结构位置、不得只取裸短语(实测反例:grep -c &#x27;改稿纪律&#x27; 会命中
    §变更记录里"新增改稿纪律节"这句声称本身,5/5 次全部误判为"已改";而 grep -c &#x27;^## 改稿纪律&#x27;
    锚定标题行后 5/5 正确判为"未改")。新增内容优先锚定标题/行首(^##、^\| v、^[0-9]+\.),
    删除内容优先取"改前独有、改后必消失"的原句;命中后必须人工读命中行,确认它是正文而非变更记录/审计记录里的自述。
  2. 状态与版本行实测:文档头状态行(版本号 + 轮次)、§变更记录末行(新版本行)逐一核对。
    版本序核验按执行器分别使用;正则必须对基线真实格式实测(SKILL.md 更新记录
    的真实格式是 | v10 |、| v11 |——整数版本、无小数点;v[0-9]+\.[0-9]+ 这类要求小数点的
    正则会提取不到任何行,等于校验空转。写正则前先 grep -n &quot;^| v&quot; &lt;文件&gt; 看真实格式):
    - Bash 提取:grep -E &#x27;^\| v[0-9]+(\.[0-9]+)? \|&#x27; &lt;文件&gt; | sed -E &#x27;s/^\| (v[0-9]+(\.[0-9]+)?) \|.*/\1/&#x27; | tr -d &#x27;\r&#x27; → 版本号数组(按出现顺序)。
    必须从锚定的表格首格提取,不得用 grep -oE &quot;v...&quot; 扫全文——变更说明正文里的 v1.5.0 / v1.7.0 会被一并抓出,实测得到 v10,v1.5,v11,v12,v1.7(假命中);
    - PowerShell 提取:$vs = (Select-String -Path &lt;文件&gt; -Pattern &#x27;^\| (v[0-9]+(\.[0-9]+)?) \|&#x27;).Matches | ForEach-Object { $_.Groups[1].Value }(按 Matches 顺序,实测 v10,v11,v12 正确);
    - 逐索引序列断言(Compare-Object 比较集合差异、不验证顺序,乱序仍通过——禁止使用):
    断言 ① 提取数组与预期数组长度相等;② 逐索引相等(PowerShell:$vs[$i] -eq $expect[$i] 循环;Bash:数组下标 ${vs[$i]} 与 ${expect[$i]} 循环比对);
    ③ 数值化后逐项递增 +1 无缺号;④ sort | uniq -d(Bash)/ Group-Object | Where Count -gt 1(PowerShell)查重为零。
    - 三个失败样例验证断言本身有效:[v10,v11,v11,v12](重复)必须被抓;[v10,v12](缺号)必须被抓;
    [v10,v12,v11](乱序,集合相同、行数相同)必须被抓——三个样例分别跑断言脚本,确认全部报错。
    断言脚本必须实际运行验证(历史方案里曾写出 ${expect[i]]} 这类语法错误,
    静态通读发现不了)
    :写完断言脚本后,用三个失败样例数组构造实际输入运行,每个都必须按预期报错;
    再用一个正确样例运行确认通过。运行记录(命令 + 输出)附在实施记录里。
    任何「递增/缺号/重复/乱序」判断以上述断言输出为准,不做肉眼比对。
    PowerShell 正则替换对含中文括号/引号的行经常静默不命中(不报错、只是没改到)——
    替换后必须 grep 复核;重要行建议改用「行数组按行号直写」或 Edit 工具(old_string 不命中会报错,
    比 -replace 静默失败安全)。
  3. 同模式残留扫描:修完评审者点名的具名位置后,全文 grep 同类模式(同款命令、同款判据、
    同款措辞)一次清干净;含代码块的文档额外做词法围栏扫描(列出全部 ``` 配对行号,
    检查围栏配平与重复/残留块——成对数量突变或孤立围栏即残留信号)。
  4. bash 块质量门:本轮新增/修改的 shell 代码块,逐块执行 bash -n(语法);语法通过不等于
    语义正确
    ——对关键判据表达式(test/条件判断/退出码依赖)逐条做语义实测或纯内建替身推演
    (例:[ ! echo x ] 是无效 test 表达式,bash -n 通过但运行返回 2 且恒假)。
    方案中的验收判据若本身是脚本,按"生产代码"标准对待。

停止条件(三条件制,取最先触发)

# 条件 动作
1 verdict = PASS 循环结束,文档可执行
2 连续 2 轮无新增 P0/P1 视为收敛,结束;剩余 P2 记入 unresolved.md
3 轮次 = 上限(默认 10;用户启动时可显式调高——含状态机/清理流程/多门槛联动的复杂 plan 建议 15~25,此类方案的执行细节长尾需要逐轮暴露) 硬停,不自动续跑,列出残留分歧给用户拍板

「无新增」判定以问题内容为准,不看措辞 —— 同一问题换个说法不算新增。
「收敛中」判定(硬停时向用户提供的决策参考;可操作定义):同时满足以下三条,判定为
「执行细节长尾收敛中」:
① P2 已清零(连续 ≥1 轮 p2=[],取 review-state.json.history[] 实测计数);
② p1 连续 ≥3 轮 ≤2 且逐轮下降或持平(同上实测计数);
③ 本轮 p1 按意见内容归类全部属"命令级可执行性/文档一致性长尾"(分类依据 = 本文件
§8.4 收敛经验;归类时须引用意见原文并说明为何属长尾,不得凭修复位置数推断)。
「每条修法改动位置数」仅作描述性信息记录,不作为缺陷性质的判定依据(设计层缺陷也可能单点修复;
执行细节缺陷也可能多点多改)。
三条都满足时,向用户报告继续轮次的历史观察值(如"R20~R23 各轮 p1 为 1~2 条,R24 p1=0 且达成 PASS"(p1 数量 ≠ 每轮修复数,仅作负载观察))
与继续成本,由用户拍板是否延长——不自动续跑、不承诺收益(样本观察 ≠ 普遍效果)。
延长时点只有一种:硬停发生后凭用户显式授权延长(更新轮次上限并记录授权);
「启动时调高上限」仅适用于尚未开始的新循环,二者不混用。
硬停且末轮 FAIL 时的收口动作(必做,实战校准):
1. 结论必须显式回答"能否进入实施" —— 末轮有 P0(或 P1 阻断项)→ 不可进入实施,不得含糊。
2. 不自动出 vN+1:把末轮三项修法写成「授权选项」(① 授权出 vN+1 + 重置轮次重启循环 / ② 按硬停交付并限制范围 / ③ 先解外部阻断再评),由用户拍板。
3. 同轮输出决策清单(一张表覆盖:授权路径 + 所有 unresolved.md 待拍板项 + 本轮新暴露的结构选择),每项给推荐值 + 影响 + 不决定的后果,让用户一次拍完 —— 避免"授权后才发现还有 N 项没定"。
4. 落盘 audit-rN.md(含停止登记表)+ review-state.json(round / stop_reason / history[])+ unresolved.md(新增末轮遗留段)三件套后再回话。

终检轮的特殊口径:若某轮仅剩「纯文本 / 渲染层」P2(措辞、悬垂引用、加粗嵌套),可声明本轮判据为「无 P0/P1 且前述已指明 P2 闭合即 PASS」,并在 verdict_reason 说明 —— 避免为格式问题多跑一轮。
趋势观察(判断何时该收紧口径):把每轮 P0/P1/P2 计数记进 review-state.json.history[],看趋势而非单轮绝对值。实战样本(spec,7 轮收敛):

轮次  1   2   3   4   5   6   7
P0    0   1   2   2   1   0   0
P1    8   9   4   3   0   1   0
P2    1   0   0   0   1   1   0

读法:P0 归零是分水岭 —— 此后残留的 P1 通常是"摘要/措辞与强契约不同步"的一致性类问题,可安全地用"同类一次清干净 + 收敛提示"推进;反之若 P0 仍在 2~3 徘徊,说明契约设计本身未定型,不要急着在 prompt 里写"不要在边角问题上阻塞 PASS"。

8.4 收敛经验:plan 类文档的 P1 长尾(2026-09-24 实战校准):P0 归零后,plan 的 P1 长尾高度集中在命令级可执行性——执行 shell 未声明(Bash vs PowerShell)、路径形态(Windows D:/ 在 WSL/scp 里被当远端语法)、进程管理(宽泛 pkill -f 自匹配、无 PID 记录)、临时文件/样本的生命周期(失败分支不清理、目录权限)、样本/测试数据的格式与冻结契约的字节级一致性(尾部 LF/CR

这类 framing 问题连续两轮才抓干净)、凭据出现在命令行。预防性写法:plan 里的每条命令写死「在哪个 shell、绝对路径、精确 PID、失败即停 + 清理」,样本类操作先对齐字节级契约再校验——这五类一次写死,可省 3~5 轮。评审 prompt 也可在 B 类维度第 3 条(可执行性)里点名这几项。
判据层 / 执行层分层(2026-10-26 plan 24 轮实证):plan 把完整命令块内联时,评审轮次会分两段——
前半抓判据层缺陷(验收断言、触发条件、映射遗漏),后半抓执行层缺陷(bash 状态机、清理守卫、
证据链)。两层问题性质不同、可并行收敛。若 plan 只写「验收判据 + 流程编排 + 证据要求」、
单一案例(24 轮 plan)观察:约前 19 轮耗在判据/契约层、后 5 轮耗在执行层——若两者并行(判据写 plan、命令进受评审的独立脚本/附录),预计有可观节省,但比例未经对照实验验证,不作为普遍承诺。是否分层由方案作者权衡(内联的可读性优势 vs 分层的收敛速度)。

反模式(必避)

反模式 后果 对策
每轮新开 codex 会话(未 resume 且未注入历轮摘要) 重复提已修意见 必须 resume &lt;thread_id&gt;;resume 失败 → 调用纪律第 4 条 退出报用户,不做 fresh-exec 降级(用户拍板)
主请求替评审者辩护 评审独立性失真 先落盘意见再改,改完在 report 里逐条回应
无范围基线 范围无限扩张 第 1 轮冻结 scope-snapshot.md,超出项标 out_of_scope
死磕到上限 边角反复打磨 条件 2 早停;上限默认 10,复杂方案可在启动时调高(条件 3)
评审者放水(全 PASS) 评审失去对抗性 强制 strongest_objection
只改 P0 不记 P1/P2 低优先级意见丢失 全部落盘,P1/P2 挂 unresolved.md
codex 失败就偷偷改用同模型子代理 静默丢失独立性 报错停下 + 给出排查清单,不降级
codex 调用失败自动重试 / 降级续跑 / 换模型硬闯(2026-09-30 用户明令禁止) 故障被吞、结论不可信 非零退出即停止并原样汇报;网络刷新超时仅可按「失败处理」第 3 项重试一次,其他非零退出不重试;处置方案由用户拍板
借道 WSL 调 codex Windows 环境差异难排查 一律 Windows 原生(Git Bash / PowerShell)直接跑 exe
在 pwsh 会话照抄 Bash 模板 PowerShell 解析或执行错误 先判定执行器,pwsh 会话用§4.5的 pwsh 版模板;需要 bash 时写死 Git Bash 绝对路径
把文档全文 / 源码 grep 结果塞进 prompt prompt 超限且独立性下降 prompt 只给路径 + 维度 + 输出要求,材料让 codex 自己读(调用纪律第 2、3 条)
同类问题只修被点名的那几处 同类遗漏重复返工 收到某类意见后全文扫一遍同类表述(grep 关键词),一次清干净;在 变更记录 显式写"同类残留一次性清干净"
评审进行中改文档 评审版本不确定 起轮次后等结论落盘再改稿;若确实在窗口内改了,必须单独标记版本(如 v7 → v7.1)并在变更记录写明"与 vN 契约内容相同,仅版本标记",保证 PASS 归属可追溯
用 Python 脚本对 Markdown 做切片拼接式编辑 重复内容或字节损坏 优先使用 Edit / 小步替换;脚本写入前后均做标题唯一性、体积和重复段落检查;案例全文见 references/troubleshooting.md#历史坑
变更记录插行时把新行写在旧行"之前" 版本顺序失真 追加变更记录永远追加在表格末尾:Edit 的 old_string 取上一版那一行的行首作锚点,new_string = 该行首 + 换行 + 新行。写完立刻 grep -n &#x27;^\| v&#x27; 核对版本序
拿最新 spec 挑旧 plan 基线漂移导致误判 plan 评审锁定其声明的 spec 版本;漂移单独记 P1
plan 评审漏掉 spec 符合度 spec 冲突漏检 B 类维度第 1 条不得省,spec_conflicts 必填
复用上轮 prompt 模板未改版本号 版本噪声干扰评审 每轮 prompt 的「当前版本」现写;或统一声明「以目标路径当前内容为准,版本号仅参考」
声称已改、实际未改(正则替换静默不命中 / 变更记录漏追加 / 状态行未更新) 改稿声称与实际不符 每轮改稿后执行「改稿纪律」四步机械验证(本表"同类表述"行的操作化落地——把"全文扫一遍"升级为可断言的 grep 实测清单);以 grep 输出为准,不以记忆为准
bash 判据块只做语法自查 错误判据阻断正常路径 新增/修改的判据表达式逐条语义实测或内建替身推演;验收判据按生产代码标准对待

换成独立的外部模型,是本循环唯一的独立性来源。

汇报格式

每轮报告 verdict、三态、逐项改动、残留级别、未决项、触发条件、耗时与评审会话 ID。续评使用 codex exec resume &lt;thread_id&gt; …;Bash 与 pwsh 模板见 §4.5。
停止时使用固定格式报告 verdict、三态、改动文件、残留、停止原因、开销和 thread_id。thread_id 同时写入 review-state.json.codex_thread_id。

更新记录

完整记录见 references/update-log.md;本轮按 2026-10-27 Plan 执行。

版本 日期 变更
v12 2026-10-26 v1.7.0:改稿纪律、停止条件与失败矩阵。
v13 2026-10-26 v1.8.0:合并调用章节,拆分更新与失败记录,优化布局并同步 .pi。
v14 2026-10-27 v1.8.1:修复重试口径、Bash 探测、schema 对齐、工作区路径、err 日志与 state 语义;统一术语格式。
v15 2026-10-28 v1.8.2:发布可见性调整为公开。

```

常见问题

5 问
答案由本站依据条目字段整理
方案文档多轮评审循环怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_569675e9/spec-review-loop。安装方式为未标注。装完刷新技能列表或重开客户端。

方案文档多轮评审循环支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

方案文档多轮评审循环权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

方案文档多轮评审循环收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

方案文档多轮评审循环用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 2026-11-06。