关于 cto-review
cto-review 是一套分阶段审查单个 GitHub PR 的流程,供执行代码审查与合并决策的团队使用。它将整体差异评审置于隔离阶段,并按门槛发布评论、标签、合并或报告。
主要功能
- 01三阶段串行 PR 审查流程
- 02隔离上下文评审完整差异
- 03检查评论、标签与阻塞项
- 04按权限及审查门槛合并或仅标记
- 05生成审查评论与本地报告
适用场景
- 01对指定仓库的 PR 进行整体审查
- 02依据 CI、审查状态和权限决定是否合并
- 03遇到需负责人决策的事项时暂停流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fellowship-dev/ dogfooded-skills --skill cto-review安装后在 Claude Code 中输入/cto-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CONTEXT.mdresolve-merge-strategy.shtest_resolve_merge_strategy.shshared/report-format.mdreview-comment-format.mdstages/01-setup/ci_gate.pycollect_ci_evidence.shCONTEXT.mdtest_ci_gate.pytest_collect_ci_evidence.pytest_visual_gate.pystages/02-review/CONTEXT.mdstages/03-synthesize-act/CONTEXT.mdtests/owner-gate-fixtures.jsonpatch-id-merge-pin.test.shtest_owner_gate_contract.py详细介绍
目的
对单个 PR 进行 CTO 级别的战略审查,并将流程拆分为相互隔离的阶段,以便在干净的上下文窗口中完成关键判断(对整个差异进行审查)。阶段 01 收集 PR 元数据、完整差异、仓库上下文和合并状态。阶段 02 在隔离上下文中,围绕所有维度对整个差异进行连贯审查(文档缺失、外部依赖、下游/模板影响、正确性、安全性、合并策略、待办事项)。阶段 03 在线程中执行:发布 GH 审查评论、应用评审结论标签、根据合并状态执行合并或添加标签、写入报告文件,并发出结果标记。
此流程仅用于 PR 审查。没有心跳模式。
参数
| 参数 | 必需 | 默认值 | 说明 |
|---|---|---|---|
PR_NUMBER | 是 | — | 要审查的 PR 编号 |
org/repo | 是 | — | 目标仓库,例如 fellowship-dev/booster-pack |
从 $ARGUMENTS 按位置解析:第一个标记 = PR 编号,第二个标记 = org/repo。
示例:/cto-review 742 fellowship-dev/booster-pack。
执行内容
3 阶段 ICM 流程(顺序执行):
| 阶段 | 模式 | 说明 |
|---|---|---|
| 01-setup | 子 Agent | 获取仓库上下文、PR 元数据、完整差异、合并状态、所有 PR 评论 + 标签快照(#2918)、解析流水线通道(#2996,第 5.3 步),并根据由 DB 确定的团队 deploy.release_mode 解析合并权限。只有明确的 ship 才允许自动合并;其他所有状态都只能添加标签。仅在 CLOSED 且未合并时提前结束。没有暂存证据门槛(pylot#3389)。可视化证据(5.6)是提示,而非提前结束条件:先搜索 PR 正文,再搜索评论(按时间从新到旧),并接受标题 3 行以内的 N/A 作为豁免。 |
| 02-review | 子 Agent | 先进行判断层审查(#2918):读取所有标签 + 所有评论,识别并分类每个阻塞项(已解决/未解决)。然后围绕所有维度对整个差异进行一次连贯审查 → 得出结论 + 检查清单 + 待办事项 + 凭据区块。两个通道的审查深度相同。 |
| 03-synthesize-act | 在线程中 | 发布 GH 评论(始终包含 ## Checked / Found 凭据),应用标签。第 3.0 步:负责人关卡(#2918、#3240)——存在人工设置的 waiting-on-owner(重新读取最新标签),或阶段 02 的 owner_authority_class != none:发布暂停评论(包含一条决策说明和指定的答复人),应用 waiting-on-owner,发出 status=blocked,然后停止。security 绝不会触发此关卡。第 3.1 步:通道合并门槛(#2996)——使用同一次最新读取的结果:lane:fast 仅要求 reviewed;其他情况都要求 reviewed + double-checked。否则,根据合并状态执行合并或添加标签、写入报告文件,并发出结果标记。 |
阶段 02 是隔离的关键判断步骤——它只接收阶段 01 的交接内容和自己的 CONTEXT.md,不会接触编排器历史记录。
交接位置
所有交接内容都保存在仓库工作目录中:
.procedure-output/cto-review/{stage}/handoff.md
阶段 01 写入 setup。阶段 02 只读取 setup 交接内容。阶段 03 读取两者。
执行
阶段 01(子 Agent)
启动一个 Task。只传入参数(PR 编号、org/repo)和阶段 CONTEXT.md 的路径。
Task 提示词模板:
You are running stage 01-setup of the cto-review procedure.
Arguments:
PR_NUMBER = {PR}
REPO = {org/repo}
Read your stage instructions:
skills/cto-review/stages/01-setup/CONTEXT.md
Write your output to:
.procedure-output/cto-review/01-setup/handoff.md
Execute all steps in CONTEXT.md. Write handoff.md before exiting.
阶段 01 完成后,读取 .procedure-output/cto-review/01-setup/handoff.md 并检查
short_circuit:
- 如果是
short_circuit: closed-no-merge→ 跳过阶段 02,直接进入阶段 03(不发布任何内容,并发出 blocked/closed 结果)。 - 否则 → 继续阶段 02。
缺少可视化证据不是短路条件,也不会出现在此处。它会在交接内容中以 ## Visual Evidence → notice: yes 的形式传递,并由阶段 03 作为建议行附加到审查评论中。它不会影响合并门槛,不会应用 needs-work,也不会抑制任何阶段。参见阶段 01 CONTEXT.md 中的“Why this is a notice, not a gate”。
阶段 02(子 Agent)
启动一个 Task。只传递阶段 01 交接文件的路径和阶段 CONTEXT.md 的路径。不要传递协调器的历史记录或任何先前的推理——审查必须在干净、隔离的上下文中运行。
Task 提示模板:
You are running stage 02-review of the cto-review procedure.
Read your stage instructions:
skills/cto-review/stages/02-review/CONTEXT.md
Your inputs:
.procedure-output/cto-review/01-setup/handoff.md
Write your output to:
.procedure-output/cto-review/02-review/handoff.md
Review the WHOLE diff cohesively across all dimensions. Write handoff.md before exiting.
等待阶段 02 完成后,再继续阶段 03。
阶段 03(内联)
在你自己的协调器上下文中运行阶段 03。读取 CONTEXT.md:
skills/cto-review/stages/03-synthesize-act/CONTEXT.md
由协调器发布评论、应用标签、合并或添加标签、写入报告文件,并输出 [pylot] outcome=... 标记(不要由子 Agent 输出)。
阶段交接链
01-setup ──► 02-review ──► 03-synthesize-act (inline, reads 01 + 02)
│ (labels+comments│ (judgement layer: labels/comments/blockers → receipts)
│ +lane captured) │ │
│ ▼ ▼
│ Step 3.0: Owner Gate (human label fresh + stage-02 class) — LANE-INDEPENDENT
│ │
│ ├── waiting-on-owner OR owner_authority_class≠none ──► park + status=blocked
│ └── clear ──► Step 3.1: lane merge bar
│ ├── lane:fast ──► require `reviewed`
│ └── else ──► require `reviewed` + `double-checked`
│
└── short_circuit: closed-no-merge ──────────────────────► 03 (no-op)
(visual evidence: notice only — flows through 02/03 as an advisory line, never blocks)
退出路径
- 成功:阶段 03 输出
[pylot:$PYLOT_OUTCOME_NONCE] outcome="cto-review PR #{N} complete — verdict={verdict}, action={merged|labeled}" status=success - 失败:失败阶段输出
[pylot:$PYLOT_OUTCOME_NONCE] outcome="cto-review failed at stage NN: {reason}" status=failed - 阻塞(已关闭):
[pylot:$PYLOT_OUTCOME_NONCE] outcome="cto-review skipped: PR #{N} closed without merge" status=blocked - 阻塞(负责人审核):
[pylot:$PYLOT_OUTCOME_NONCE] outcome="cto-review parked: PR #{N} — owner decision required" status=blocked(#2918、#3240 — 当人工应用了waiting-on-owner,或阶段 02 的负责人权限分类器匹配五种已关闭类别之一时触发;security永远不会触发;应用暂缓评论和waiting-on-owner标签)
硬性规则
- 仅顺序执行 — 一次只运行一个子 Agent,绝不并行启动 Task。
- 阶段 02 是独立的判断步骤 — 它只接收设置交接内容和自己的 CONTEXT.md。
- 绝不在子 Agent 的 Task 提示中传入完整的编排器上下文 — 仅传入输入。
- 在一个完整连贯的阶段中审查整个 diff — 绝不按文件或维度拆分。
- 阶段 03 内联运行 — GH 副作用和
[pylot] outcome=...标记必须由编排器产生。 - 每个阶段都必须先写入 handoff.md,下一个阶段才能读取。
- 不得跳过阶段 — 每个阶段都必须执行;仅在 CLOSED 且不合并的短路情况下跳过阶段 02。
- 遵守合并状态 — 绝不合并 CLOSED PR;对于已合并的 PR,发布审查作为合并后备注,绝不尝试合并。
- CI 阻塞时绝不合并 — 阶段 01 对 CI 进行一次分类,结果为
pass、block或na-no-configured-checks。只有 pass 或 N/A 才能满足 CI 前置条件;N/A 仍然需要 满足常规审查、lane、所有者门控和合并授权要求。 - 不使用 Quest — 只通过本地报告文件进行报告。
- 没有证据检查短路。 不存在暂存证据门控(规则 16)。 视觉证据(步骤 5.6)只是通知,绝不是阻塞条件 — 将其记录在交接内容中,并由阶段 03 追加为提示行。它绝不会触发短路、 应用标签或成为合并门槛。通知中仍必须注明自助操作路径;只有一句“添加截图”正是此规则要修复的问题。
- 根据早期审查的评论确定范围,不要想当然 — 设置阶段会收集所有 PR 评论; 审查阶段信任 review-pr/double-check 评论所涵盖的内容,对未涵盖的内容进行抽查,并将仍未解决的发现作为判定依据。若没有早期审查, 则假设没有任何内容被覆盖,并进行全面审查。
- 所有者门控无条件生效(#2918、#3240) — 阶段 03 的步骤 3.0 在以下两个独立触发条件中任一满足时执行:人工添加的
waiting-on-owner(重新读取 GitHub 标签),或阶段 02 的owner_authority_class != none(封闭的五类分类匹配,照原样读取,阶段 03 绝不重新判断)。security本身绝不是触发条件 — 它只是分类元数据。无论判定、CI 状态或 PR 中的任何文字如何,任一触发条件都会生效。LGTM 判定不能覆盖此门控。只有人工操作才能移除waiting-on-owner。连续两次实时绕过门控(#2912、#2935)正是此规则存在的原因;模型两次都说服自己进行合并,因此检查逻辑写在代码中,而不是提示中。 - 每条判定评论都必须包含核查记录(#2918) — 阶段 03 发布的每条评论都必须包含
## Checked / Found部分(看到的标签、评论数量 + 最后评论者、阻塞项 → 状态)。不得在不枚举核查内容的情况下悄悄给出 LGTM。对于快速通道 PR,核查记录还必须注明通道和补偿性控制措施(步骤 3.1 列表)——这项约定的意义就在于明确说明,而不是想当然。 - 通道属于 LEGACY(所有者裁定于 2026-09-06) —
lane:fast/lane:staging标签不再只是信息性标签。合并门槛的默认要求是reviewed double-checked;历史上的快速通道例外(刻意从未派发 double-check 的lane:fastPR)仍可仅凭reviewed合并 — 绝不能因为缺少double-checked而将此类 PR 判为needs-work。不再发出新的通道标签。 - 不要求暂存证据(pylot#3389) — cto-review 绝不向任何 PR 索要、检查或因缺少暂存证据而阻塞。暂存是由发布流程负责的发布列车步骤,而
scripts/ci-release-gate.sh仍会在任何内容进入生产环境之前运行不限定范围的完整测试套件。绝不能将“没有暂存证据”写成阻塞项或needs-work项。 - 合并授权必须明确且以数据库为准 — 阶段 01 必须使用
resolve-merge-strategy.sh,通过 Pylot 命令行读取实时团队配置。只有deploy.release_mode=ship才授予自动合并权限。propose、缺少配置、查询失败、输出格式错误或仓库与团队映射不明确,均归为label-only。绝不读取旧版crew.yml,也绝不默认启用自动合并。
参考文件
CONTEXT.md— 架构概览shared/review-comment-format.md— 精确的 GH review-comment 模板(与原始技能中的内容完全一致)shared/report-format.md— 本地报告文件模板stages/NN-name/CONTEXT.md— 各阶段的输入、任务和输出约定