关于 rubber-duck-review
该代码评审 Skill 让当前 Agent 保留任务主导权,同时通过其他模型获取只读的第二意见,并指导评审选择、范围划分和结果整理。
主要功能
- 01选择不同于当前模型的评审者
- 02以只读方式执行评审
- 03对大型变更并行分段评审
- 04围绕相关变更编写评审提示词
- 05输出按优先级整理的发现
- 06通过 CLI 脚本启动评审
适用场景
- 01提交前获取独立代码评审
- 02按逻辑区块评审大型差异
- 03修复后重新检查变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vivswan/ skills --skill rubber-duck-review安装后在 Claude Code 中输入/rubber-duck-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.mdREADME.md.codex-plugin/plugin.jsonagents/openai.yamlreferences/reviewer-prompt.mdscripts/run-review.mtsverdict-schema.jsonverdict.mts详细介绍
Rubber Duck Review
在保留任务所有权的同时,让另一个模型对代码更改提供第二意见。
适用时机
当有人提出以下请求时,使用此技能:
/rubber-duck-review- “帮我像橡皮鸭一样审查这些更改”
- “对此再征求一个意见”
- “用另一个模型审查一下”
工作流
1. 选择审查者
- 如果有专用审查工具,优先使用。
- 尽可能使用与当前模型不同的审查者。
- 如果没有专用工具,则通过此技能的
scripts/run-review.mts(第 4 步)使用只读 CLI 调用作为后备方案。根据你当前使用的模型选择审查者:- 如果你当前使用 Claude →
codex,后备选择copilot。 - 如果你当前使用 Codex 或 GitHub Copilot →
claude,后备选择copilot。
- 如果你当前使用 Claude →
- 绝不要让审查者写入文件、编辑代码或运行不受限制的 shell 命令。
- 脚本会强制启用只读标志:
--sandbox read-only(codex)/--permission-mode plan(claude)/ 只读工具允许列表(copilot)。 - 只读模式仍允许审查者自行核验:它可以运行只读命令(grep、
git diff、类型检查),但会阻止写入。copilot 只能读取和 grep 文件。这样的自行核验能让发现的问题更具体。 - 注意:只读沙箱可能会阻止创建临时目录,因此审查者可能会跳过需要写入的测试。
- 如果 codex 自身的沙箱无法启动,脚本会改为审查一个未沙箱化的快照副本(第 4 步)。这是对此规则的例外,没有强制的文件系统隔离:唯一的保障是提示词中的仅审查指示;副本则仅凭路径确保被禁止的写入不会落入正在审查的检出目录。
- 脚本会强制启用只读标志:
2. 大型变更集:按章节分派审查
- 对大型差异进行一次全面审查,不如进行多次有重点的审查。将更改拆分为逻辑上的章节(每个新命令/模块、每个脚本、CI/发布配置、每组对应实现),并行地针对每个章节运行一次审查,每次限定到相关文件。
- 一次运行的审查数量不得超过机器和审查后端能够稳定处理的范围。 从大约 3 个开始比较稳妥。许多
codex exec进程同时运行可能会使后端饱和并挂起。遇到批次卡住时,应减少数量,绝不要增加。 - 检测并恢复挂起。 使用 JSON 流时,比较每次审查在约 30–60 秒内的事件数量。如果某个审查的事件数没有变化,而其他审查仍在增加,则说明它已挂起。停止它(使用任务运行器的停止功能,或运行
kill <the pid the launch printed>,绝不要按模式批量终止),然后只重新启动这一个审查。
3. 编写提示词
- 只要求审查相关更改及其周边上下文。
- 始终包含:
This is a review-only task. Do not edit, write, or modify any files. Only read and report findings. - 告知它如何查看更改,并指定与收敛门控所限定范围相同的目标,而不是直接粘贴差异。这样它能更好地追踪导入关系和跨文件行为。
提交之前,也就是“运行
git --no-pager diff --cached并阅读新增文件”。对于分支或 PR,则是“运行git --no-pager diff <base>...HEAD”,其中<base>是该分支实际使用的基准分支。git diff HEAD两种情况都不适用:分支提交后会显示空结果,提交前则会混入尚未暂存的修改。 - 请评审者检查以下内容:
-
正确性问题
-
可证实的缺陷:正确性问题只有在指出具体输入或状态,以及受审查修改会因此产生的错误输出、崩溃或数据丢失时,才值得投入精力。可维护性问题只有在指出本次修改中的具体问题时,才值得投入精力,具体见下一条。
-
本次修改中已有的不妥命名或设计选择:名称会误导人们对代码当前行为的理解,或本次修改引入了重复代码和不合理结构
-
靠冗长辩解性注释支撑的变通方案:如果需要用一整段注释来论证变通方案没问题,那代码就有问题。应同时标记注释和代码,要求修正。
-
固定提出以下库相关问题,原文如下:“Does any code this change adds, moves, touches, reuses, or depends on do what a good library or a tool already in the repository does? Name it and what it covers.”被移动或复用的辅助代码应按新增代码审查。确认存在此类问题时,应作为
blocking问题(这是/code-standards技能的规则)。对于大型库或适配性不明确的库,应将其作为
blocking条目,问题描述以Ask the owner:开头并指出该库;负责流程会将问题提交给用户,在用户回答前不会构建任何内容。若某库需要的运行时或 API 已从代码库中移除,则该库不适用,也不构成问题。 -
固定提出以下测试相关问题:对于修改中每个新增测试,指出该测试锁定了什么事实,而该事实并未由源代码本身说明。评审者绝不能在未指出具体事实的情况下要求添加测试。
- 如果测试只是复述它所读取的源内容,就应作为问题提出,修复方式是删除测试:例如,工作流测试断言
needs与 YAML 中的列表相同、将常量固定为其自身字面值,以及解析代码库自带的配置文件后再断言其原内容。 - 模板中已有相关措辞。
/code-standards技能的测试参考内容规定了这项规则、三种有效答案,以及应在何处固定常量值。
- 如果测试只是复述它所读取的源内容,就应作为问题提出,修复方式是删除测试:例如,工作流测试断言
-
修改发布的任何内容中包含的 PII:任何能让读者识别作者身份、了解其工作方式或机器配置的信息,包括从作者真实环境中测量或复制的值。所有测试样例都必须手工编写。提及真实数据来源的注释属于问题。
模板中已有相关措辞。
/pr-and-issue-discipline技能规定了该规则及其替代方案。请将 PR 标题、正文和评论粘贴到提示词中,因为沙盒中的评审者可能无法访问 GitHub。 -
推测性加固(无法接触代码的恶意调用方、单用户工具中的竞争条件、已受外层超时限制的截止时间,以及针对代码永远不会接收的输入所做的防御性检查)应列在
Recorded, not built标题下,绝不能作为问题提出。除非用户提出要求,否则不要实现这些内容。 在存在外部用户或恶意输入入口的代码库中(例如已发布的软件包、公共服务),或者用户提出要求时,应将其告知用户,并且仅在用户确认后才进行构建(步骤 6)。随审查中的更改一同加入的小型、显而易见的加固措施(例如在版本检查旁增加退出码检查)可以保留。审查者不得提议更大范围的加固来取代它。
-
- 纳入配套技能的标准:对于每项已安装且在其 SKILL.md 中声明了
## Review Criteria部分的技能,都将该部分扩展到审查者提示词中。根据该技能自身的工作流对由此产生的发现进行分流。一个例外是:审查他人的 PR 时,/reply-and-review-discipline技能的视角选择会指定要扩展哪些部分。- 没有注册表。声明该部分即表示该技能参与审查。在此技能集合中,
/no-invalid-states、/code-standards、/never-twice和/verify-with-controls声明了该部分。 - 通过搜索已安装的技能来列出参与者,例如:
grep -rlE '^## Review Criteria' ~/.claude/skills/*/SKILL.md .claude/skills/*/SKILL.md 2>/dev/null(请根据你的运行环境安装技能的位置调整路径)。 - 仅适用于特定情境的技能会使用不同的标题来命名其标准(例如
## <Context> Review Criteria),并在其自身发起的审查中纳入这些标准。
- 没有注册表。声明该部分即表示该技能参与审查。在此技能集合中,
- 要求提供分优先级的发现(阻塞与非阻塞),并要求在代码正确时明确说明。这样可以让复审有明确的终点。
- 报告必须是一个 JSON 对象,包含
blocking和non_blocking数组,每项格式为{where, claim, evidence},还包含一个recorded_not_built字符串数组,以及summary。请粘贴模板中的报告格式代码块。脚本通过scripts/verdict-schema.json为 codex 和 claude 强制执行格式;copilot 则只能依据提示词。 - 如果用户在当前对话中已拒绝或撤回某项内容,请添加一个简短的
Already decided / out of scope部分,避免审查者反复提出该项。 - 进行复审时,说明哪些修复已应用,以便审查集中于剩余问题。
可复用的提示词模板请参阅 references/reviewer-prompt.md。
4. 运行审查者
此技能提供 scripts/run-review.mts(路径相对于已安装的技能文件夹,而不是受审查的代码库)。它封装了启动时容易遇到的问题:
- 使用 argv 数组启动审查者,中间不经过 shell(提示词中的反引号和
$(...)会按原样保留) - 关闭 stdin(
codex exec和claude -p都会因等待 stdin 关闭而无限期阻塞) - 将完整输出流捕获到操作系统 tmp 目录下的临时文件中(绝不会写入工作树)
- 传入每个审查者所需的标志,包括为 codex 和 claude 指定判定模式 schema(
scripts/verdict-schema.json),确保最终消息不会是自由文本 - 提取判定结果,并拒绝没有工具调用的结果。codex 也会将叙述内容填入 schema,因此以“I will review now”结束的轮次看起来也可能像一份有效的空判定结果。缺少的读取操作才是暴露问题的依据
- 输出一份 JSON 报告,其中包含判定结果、工具调用次数、保留的捕获文件路径,以及精简的执行轨迹(审查者每一步一行),让你无需打开输出流即可了解审查者做了什么
bun "<skill-dir>/scripts/run-review.mts" --help:
usage: run-review.mts <codex|claude|copilot> <prompt-file> [--background] [--stdin-prompt]
run-review.mts <codex|claude|copilot> --extract <output-file>
run-review.mts <codex|claude|copilot> --extract --wait <output-file> [--timeout <seconds>] (polls every 2 s; default timeout 3600)
run-review.mts <codex|claude|copilot> <prompt-file> --capture <dir> (internal)
run-review.mts prepare <section>
scratch (rubber-duck-*) lives under the OS tmp dir for 24 hours; prepare and a launch purge older ones
codex whose bubblewrap sandbox cannot start reviews an unsandboxed snapshot copy of the repository inside its scratch dir
prints: the JSON report (verdict, tool_calls, capture, trajectory, and sandbox only when codex fell back to copy mode); --background prints output-file: <path> and pid: <n>
exits: 0 verdict printed, or a --background launch started (its verdict comes via --extract);
1 review FAILED - relaunch: no usable verdict, whatever the cause, or --wait timed out; never a clean pass;
2 usage error, the reviewer binary not installed, or codex's sandbox unavailable outside a git repository
将步骤 3 的提示词写入临时文件,并将审查者名称和该文件传入脚本。同一台机器上可以同时运行多个 Agent(或一个扇出任务中的多个部分)进行审查。像 /tmp/rubber-duck-prompt-<section>.md 这样可预测的名称,可能会让一个写入者在脚本读取前覆盖另一个写入者的提示词,因此脚本会自行生成路径:
prepare <section>使用mkdtemp创建一个私有目录(该操作是原子的,因此两个调用者永远不会收到同一个目录),在其中保留标记,并输出该目录中该部分的提示词文件。- 启动时会拒绝任何不在此类目录中的提示词文件,以及其中的任何符号链接或硬链接。标记才是凭证,而非位置,因此两个 shell 无需共享
TMPDIR。
如果执行环境的沙箱拒绝包含 git 命令的 Bash heredoc(某些 Agent 工作树设置会这样做,因为无法验证该命令是否始终在工作树内执行),请使用执行环境的文件写入工具来写入提示词文件:
# 1. Mint the prompt path, one call per review section. Shell state does not survive
# between tool calls, so copy the printed path by hand:
bun "<skill-dir>/scripts/run-review.mts" prepare api-gateway # prints e.g. /tmp/rubber-duck-prompt-Kq3mZp/api-gateway.md
# 2. Write the step-3 prompt to that path with the harness's file-writing tool (a heredoc
# with a quoted delimiter serves where the sandbox allows it).
# 3. Then, in one shell call:
prompt_file="/tmp/rubber-duck-prompt-Kq3mZp/api-gateway.md"
bun "<skill-dir>/scripts/run-review.mts" codex "$prompt_file" # codex|claude|copilot per step 1
- Reviewer 参数:
codex:运行codex exec --json --sandbox read-only --output-schema <schema>。- 启动时会先通过
codex sandbox -- true探测沙盒。codex 会在 bubblewrap 下运行每条沙盒命令,而 AppArmor 配置文件禁止挂载传播的容器会在启动时拒绝运行:bwrap: Failed to make / slave: Permission denied。 - 仅此拒绝就会切换启动方式。脚本会通过 git 将仓库快照保存到本次审查的临时目录中,并在该副本中以
--sandbox danger-full-access运行 codex,工作目录对应副本中的当前工作目录(如果当前目录没有任何受跟踪文件,则使用副本的根目录)。 - 快照包含 git 已提交或将要提交的内容:以分支名称命名的 HEAD、每个引用(包括
ORIG_HEAD和FETCH_HEAD),以及作为工作树检出的索引;快照与检出目录共用对象存储。部分克隆的 promisor 远程也会随之保留,因此检出目录从未获取的 blob 会在首次读取时获取。所以,git diff --cached和git diff <base>...HEAD在副本中显示相同的更改。 - 其他内容都不会随之复制:未暂存的编辑、未跟踪文件、被忽略的目录(已安装的依赖项、嵌套工作树)、子模块内容,以及检出目录的配置都会留在原处;Git LFS 文件仍是指针,稀疏检出也会保持稀疏状态。若检出目录有数 GB,快照的大小仍相当于其受跟踪文件的大小;依赖已安装内容才能运行的类型检查或测试无法在副本中执行。
- Reviewer 退出时会删除副本(如果无法删除,会在
review.err中报告为not removed),报告和启动记录中都会包含sandbox: "copy"。标准错误输出会注明拒绝原因和副本路径。 - Reviewer 会在临时
CODEX_HOME下运行,其中存放着用户的config.toml和auth.json副本。codex 会将启动目录标记为受信任项目,并通过写入配置文件来完成此操作;副本的路径在每次审查时都会变化,因此该写入会落在临时主目录中,并随之删除。 - 用户自己的配置文件绝不会被写入。codex 写入临时
auth.json的令牌刷新信息会同步回用户文件,因为 codex 需要将其持久化。 - 临时主目录的
sessions目录是指向用户自身目录的链接,因此审查的转录记录(codex 的会话记录)会像只读启动时一样保存在用户主目录中,并在清理后保留。 - 如果当前目录不在 git 仓库中,则无法创建快照:退出码为 2。其他探测失败(例如 codex 版本太旧,不支持该子命令)则会继续使用只读启动方式。
- 启动时会先通过
claude:运行claude -p --permission-mode plan --verbose --output-format stream-json --json-schema <schema>(使用stream-json时必须指定--verbose)。copilot:运行copilot -p <prompt> -s --available-tools=view,rg,glob --deny-tool=write --deny-tool=shell --disable-builtin-mcps。这是最后的备用方案,因此优先使用 codex/claude。其限制如下:- 只读工具允许列表使其能够读取和搜索文件,但无法调用 shell、写入文件、连接 MCP 服务或启动子 Agent。
- 无法调用 shell,就无法运行
git diff和类型检查,因此需要明确指出要读取的文件。 - 它不会流式输出 JSON,因此报告中没有存活信号或执行轨迹,也无法检查其结论是否调用过工具。它没有 schema 标志,因此只有提示词会要求它输出 JSON 对象。
--stdin-prompt(仅适用于 codex/claude):如果环境拒绝将提示词作为命令参数,或提示词非常长,请添加此参数。提示词文件本身会作为 Reviewer 的标准输入提供。 文件描述符是以 EOF 结束的,因此不会卡住。标准输入卡住的陷阱是打开的管道,而不是已被使用的标准输入。- 前台模式(默认)会一直阻塞,直到审查器退出,因此请为工具调用设置充足的显式超时。子 Agent(工作树构建器、派生的工作进程)要么在一个前台调用中运行启动命令,要么使用
--background,然后在有界前台调用中等待(步骤 5):如果工作进程结束当前轮次时仍在等待后台审查器的完成通知,就永远收不到通知。 --background会严格打印两行:output-file: <path>和pid: <n>。output-file是捕获的输出流。一个脱离终端运行的监视进程会将审查器的退出状态记录在该文件旁边。- 负责人可借此在审查运行期间继续工作,并通过
--extract --wait(步骤 5)收集判定;子 Agent 可用它启动可能超过一次前台调用时长的审查,并按步骤 5 进行有界等待。 - 终止该 PID 会取消审查(信号会转发给审查器)。
- 进度:前台运行最多会向 stderr 打印两行进度信息:一行在输出流首次显示活动时打印,另一行在审查器退出时打印(失败时还会额外打印一行
review FAILED;codex 复制模式会先打印其通知)。期间没有输出很正常。一次真正的审查可能需要一些时间。 - 运行时:
bun。node24+ 也可用(node "<skill-dir>/scripts/run-review.mts" ...)。 - 退出代码:参见上方用法区块中的
exits:行。步骤 5 说明了每种情况的处理方式。 - 已发布的脚本与这些引用(审查器调用、标志、失败判定)会在上游保持同步;用法区块也通过上游测试确保与脚本一致。如有不一致,请以脚本为准并报告偏差。
5. 根据打印出的判定采取行动
-
前台运行或
--extract的 退出代码 0:stdout 是一份 JSON 报告。(--background启动也会以代码 0 退出,但只打印输出路径和 PID。其判定需通过--extract获取。)verdict.blocking和verdict.non_blocking:审查发现项,每项格式为{where, claim, evidence}。按步骤 6-7 对它们进行分类处理:逐项采纳或驳回。verdict.recorded_not_built:审查器暂不处理的推测性加固建议。步骤 6 说明如何处理。verdict.summary:审查的内容和方式。将单纯的“代码正确”视为收敛过程的输入,而不是在修复后跳过重新审查的理由。tool_calls、trajectory:判定前进行了多少次读取和命令调用,以及审查器每个步骤的简要记录。如果判定的轨迹只显示了一次git diff,且没有读取改动文件的记录,则这次审查力度不足。请在提示词中明确指定文件,并重新启动审查。capture:完整的审查器输出流,保留 24 小时。如果某项发现或摘要看起来不对,且你想查看审查器的确切消息,请阅读此内容。
-
退出代码 1(
review FAILED - relaunch):这根本不算审查,绝不是通过。请重新启动。这表示输出流为空、在轮次中途被截断、末行不完整、轮次失败或出错后没有判定、最后一条消息不是判定对象、判定前没有工具调用(仅有开场白),或者审查器以非零状态退出。只要捕获的输出流仍存在,失败消息就会指出其路径。
-
退出代码 2:修正调用方式或安装缺少的审查器二进制文件。尚未进行任何审查。
-
--background启动后,等待判定有两种方式,每种适用于一个角色。两者的区别只有一个原因:子 Agent 在一次长时间调用后进入空闲状态,就不会再被唤醒;而后台命令结束时,负责人的会话会再次被调用。负责人(由运行框架重新调用的会话)在一个后台 shell 中等待,因此运行框架会交付完成信号。切勿手动轮询
review.status或输出路径:out=<the path from the output-file: line> bun "<skill-dir>/scripts/run-review.mts" <reviewer> --extract --wait "$out" --timeout 3600 > "${out%/*}/verdict.out" 2>&1子 Agent(工作树构建器、派生的工作进程)使用
--background启动一次,然后重复调用:每次运行都是独立的前台工具调用,并将 Bash 超时参数设为 300000 ms,直到出现判定、失败行或停滞行:out=<the path from the output-file: line>; record="${out%/*}/review.status" ! grep -q '"status"' "$record" && find "$record" -mmin +60 | grep -q . && { echo "review stalled: no verdict an hour after the launch; report it to the lead"; exit 3; } bun "<skill-dir>/scripts/run-review.mts" <reviewer> --extract --wait "$out" --timeout 240调用输出的内容决定下一步,不能只看退出代码,因为退出代码 1 同时表示等待超时和审查失败:
调用输出 含义 下一步 stdout 上的 JSON 报告,退出代码为 0 判定结果 按下文处理 stderr 上的 review FAILED - relaunch (--wait timed out: ...),退出代码为 1尚无判定结果 再次运行调用 stderr 上的 review FAILED - relaunch (<any other reason>),退出代码为 1审查失败 重新启动 review stalled: ...,退出代码为 3启动记录已有一小时,仍无 status:这是代码块自身的上限,不是启动器的向负责人报告停滞 每次等待都是一个较短的前台调用,并通过重复调用来完成,绝不能使用一次长调用:每次等待都必须是独立的前台工具调用,不能使用 shell 循环,因为那仍然是一次长调用。
/orchestrator-mode技能中的references/spawn-briefs.md,“The Stop-and-Wait Ban”条目包含简报侧的说明,并指向此处介绍代码块。对于这两种形式:
<reviewer>是启动审查时使用的参数。- 负责人的判定结果会写入该审查捕获目录中的
verdict.out,因此并行审查(步骤 2)不会相互覆盖。它会随目录一起移动和删除。子 Agent 的前台调用会将判定结果作为工具结果输出。 - 脚本每隔 2 s 轮询一次启动记录,直到监控器记录退出状态,然后输出相同的 JSON 报告。如果
--timeout <seconds>(默认值为 3600)先到期,脚本会以退出代码 1 退出,在 stderr 上输出原因--wait timed out,且不输出报告。 - 它会根据启动记录验证审查者和输出文件,因此,如果等待时指定了错误的审查者或文件,或者文件旁边没有启动记录,就会立即以退出代码 2 失败。
- 负责人的单次等待会读取与上表相同的行,但有一点不同:任何
review FAILED - relaunch行(包括超时)都意味着重新启动。
-
bun "<skill-dir>/scripts/run-review.mts" <reviewer> --extract <output-file>若不带--wait,只会读取一次已完成的运行:如果审查者仍在运行,它会以退出代码 1(no exit status recorded)退出,而不会阻塞。 -
每次已运行到审查者阶段的运行都会将其临时目录保留 24 小时(位于 OS 临时目录下,绝不在工作树中):即报告中包含
capture路径的目录,或失败信息中的output kept at路径(若对应流已不存在,则会省略)。脚本会将你的提示词快照保存到该目录,因此启动器写入的所有内容都会一起移动和清理。- 在所有启动模式下,审查者自身的转录记录都属于 codex,并保存在 codex 的主目录中。
prepare和每次启动都会先仅按目录年龄清除超过 24 小时的同级rubber-duck-*目录,因此你创建的提示词目录也会保留相同的 24 小时。较新的目录属于其他会话正在进行的审查,会原样保留;不会跟随符号链接;清理失败会在 stderr 上报告,但不会导致审查失败。- 若要提前清理自己的两个目录,只删除那两个目录,绝不要对共享临时目录使用通配符。清理其中所有
rubber-duck-*会终止其他会话正在进行的审查。 - 如需使用可清理的专属空间,会话应在启动前将自己的
TMPDIR设为其创建的目录。prepare和启动操作都会遵循该设置。 - 若前台启动时找不到审查者二进制文件(退出代码 2),则不会捕获任何内容,也不会留下任何文件。带
--background的启动会保留其目录,以便--extract报告二进制文件缺失,因此之后应将其删除。
6. 审慎处理审查结果
-
对于有效的“非阻塞”反馈,如果指出的是正确性或可维护性问题,且已证明该问题会对本次更改产生影响,就应将其视为实际工作。
- 在同一更改中顺手做一项小而明确的加固是可以的(例如,在版本检查旁加上退出码检查,或在只需一个参数的地方添加边界限制)。
- 一旦每轮审查都发现一个新的、假设性的绕过方式,问题就出现了:目标范围正在扩大。保留第一轮的最小实现,并将其余内容记录在
Recorded, not built下。后续轮次发现的可证明缺陷仍属于第一条所述的工作。 Recorded, not built下的事项不属于工作:保留在报告中,不要为其创建任务或 PR,除非用户提出要求。另一种例外是仓库有外部用户或面临恶意输入(例如已发布的程序包、公开服务):将这些事项及其具体风险告知用户,只实现用户确认的事项。
-
除阻塞性问题外,也要修复有效的非阻塞问题,包括有助于提升可维护性的修复(例如命名更清晰、删除重复内容、简化结构)。
- 如果某条
blocking条目的内容以Ask the owner:开头,那是一个问题,不是发现:将其连同库名一起提交给用户,在用户答复前不要据此实现任何内容。与其他阻塞性发现一样,它会暂缓此次更改。 - 只有在修复会与设计冲突、超出当前审查的更改范围,或违背用户的明确决定时,才跳过有效的发现。请记录原因。
- 对更改所依赖代码中已确认的库问题,绝不能以超出更改范围为由跳过:应将其列为后续任务、问题,或加入本次会话的任务列表(遵循
/code-standards技能的规则)。如果库改动较大,或是否适用尚不明确,应先等待所有者答复。 - 如果你认为某项发现不正确或不适用,不要直接跳过,而应按照下一条予以驳回。
- 如果某条
-
不要盲目接受所有发现。如果你有异议,请说明理由,并留意会与设计冲突的修复建议(例如会破坏合法流程的防护措施)。
-
如果“添加测试”的发现没有指出测试应验证的具体事实,且该事实超出了源代码已有的说明,无论是谁提出的,都应以此为由驳回。对于本身不改变行为的删除,应在 PR 正文或合并报告中通过清点证明,无需编写测试。
-
如果某项发现与用户的明确决定冲突,应遵从用户,并记录该问题是有意跳过的。
-
每批修复后、再次审查前,都要重新验证:运行类型检查(语言支持时),以及本次更改和验证所涉及的测试,切勿运行 CI 本来就会执行的全套测试。长时间运行的检查必须明确设置超时;停止进程时,只能使用你启动的 PID,绝不能按模式匹配终止进程。
如果 CI 运行时间需要计费或额度有限(例如使用计量套餐的私有仓库),则在推送前于本地运行一次完整检查。如果不确定属于哪种情况,请询问用户,或询问向你说明情况的负责人。
7. 反复复审,直到收敛
-
应用修复后,在更新后的状态上重新运行复审;每个部分分别复审,不要只做一次整体检查。
-
重复此过程,直到不再有有效的阻塞性问题,并且每项非阻塞问题都已按步骤 6 处理:已修复、已记录原因后跳过,或已判定为错误或不适用。
收敛就是门槛:在复审针对即将提交的更改的确切最终内容收敛之前,不得提交或合并。提交时,检查的是暂存的差异,因为 Git 提交的是索引,而不是工作树。合并时,检查的是分支或 PR 的差异。
这是复审收敛的唯一判定标准。以此为门槛的技能(例如
/pr-landing-discipline中的 Converged)应指向这里,而不是重复陈述这一标准。 -
收敛报告必须注明所依据的评审标准:提示词文件的路径,或一行概述其标准及其
Already decided列表的摘要。 指令可能在执行过程中发生变化,而负责人看到“已收敛”时,需要知道复审是依据哪个版本收敛的。示例:三位构建者报告称,他们依据某项评审标准“已收敛”,但负责人在他们进行复审期间已更新了该标准。报告中没有任何内容表明这一点。每份报告多写一行就能说明。
8. 如果这些指令不起作用,就修复技能
- 如果某个步骤在实际使用中失败,且根本原因在于指令本身(例如,文档中注明的标记已不存在、提取规则无法识别结论,或复制粘贴的代码块会以可复现的方式出错),就修复技能。
- 先绕过问题,完成当前复审,然后记录修复,避免下次运行时再次发现同一问题。
- 首先排除临时原因(后端中断、沙盒限制、本地工具配置)。这些不属于技能缺陷。
- 这也适用于你,也就是负责推进的 Agent。根据步骤 1,复审者应保持只读。
- 仅在能够编辑规范源文件的情况下修复技能:在作者仓库中直接编辑受影响技能的源文件(
SKILL.md、references/或scripts/)。 - 如果使用的是已安装或供应商提供的副本,或者你无权写入,请向用户报告缺陷并提出修复建议。
- 仅在能够编辑规范源文件的情况下修复技能:在作者仓库中直接编辑受影响技能的源文件(
- 将根本原因纳入相关步骤,而不是在末尾追加一次性说明,并确保复制粘贴的代码块按原样即可运行。
- 技能编辑与其他更改一样,都会影响工作树:应使用修正后的指令完成复审,并按照相同的验证、复审和收敛门槛处理该编辑(步骤 6 和 7)。