mcpField
T
triage-pr

triage-pr

github.com/rheged-studio测试与质量046 次安装6 天前更新
代码仓库

关于 triage-pr

triage-pr 是用于将 GitHub PR 从草稿和 CI 失败推进到可供合并状态的技能,分阶段处理 CI 与代码审查反馈。适合需要按配置修复 PR 范围内问题、等待审查并报告阻塞项的团队。

主要功能

  1. 01检查失败的 GitHub Actions
  2. 02在 PR 范围内修复 CI 问题
  3. 03等待配置的审查机器人反馈
  4. 04核实并处理审查意见
  5. 05支持仅 CI、试运行和自动应用模式

适用场景

  1. 01排查草稿 PR 的失败检查
  2. 02等待 PR 就绪后的机器人审查
  3. 03在限制轮数内处理审查反馈

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheged-studio/agent-skills --skill triage-pr

安装后在 Claude Code 中输入/triage-pr确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

config.example.json
package.json
README.md
references/
follow-up-routing.md
phase-b-envelope.md
phase-b-unattended.md
review-discipline.md
scripts/
respond-threads.mjs
review-threads.mjs

详细介绍

triage-pr

分两个阶段,将一个 草稿状态且 CI 失败 的拉取请求推进到 可合并 状态,并根据 PR 的草稿状态选择阶段:

  • 阶段 A——PR 处于草稿状态时: 检查失败的检查项,拉取 GitHub Actions 日志,并且只在 PR 范围内修复失败项。持续循环,直到 CI 通过或报告阻碍因素。阶段 A 无人值守运行——除硬性阻碍因素外,无需人工把关。
  • 阶段 B——PR 已准备好接受评审后: 等待已配置的评审者,按“先验证,再提出处理方案”(步骤 9)处理评审意见,然后根据 humanEnvelope / --auto-apply 遵循 references/phase-b-envelope.md 或 references/phase-b-unattended.md。受 maxReviewRounds 限制。

从 send-it 0.8.0 起,/send-it 会打开或更新 拉取请求,然后在最后一步调用此技能(步骤 11,A-1151):它会等待至少一项检查注册,然后将任务移交给此处——原样转发 --dry-run、--ci-only、--no-promote 和 --auto-apply。默认的 /send-it 运行必须完成这次移交才算完成(A-1645)。当 humanEnvelope 为 true 时,进入阶段 B 的 send-it 流程仅会在此技能的人工审核关口暂停;当其为 false 时,流程会在步骤 13 的报告处结束(A-2014)。当 send-it 已打开 PR,或有意跳过 send-it 时,仍完全支持直接运行 /triage-pr,以便在流程中途重新进入;但这并非 send-it 流程通常的结束方式。

草稿→就绪状态的转换由单个选项控制——config.json 中的 promoteOnGreen——并且启用的配置本身就是授权:当 promoteOnGreen 为 true(默认值)时,授权转换的人工许可已通过仓库配置取得,因此阶段 A 的 CI 确认完全通过后,技能会将 PR 切换为就绪状态并继续进入阶段 B,无需停下来另行寻求批准(就绪状态转换是启用 AI 评审的关口;参见步骤 6)。转换仍受保护——必须确认 CI 通过,且不存在未解决的人工评审讨论串,同时不存在未解决的基线漂移。设置 promoteOnGreen: false(或传入 --no-promote)即可选择退出,并在 CI 通过时停止;明确的用户提示——或 --promote / --no-promote 标志——会覆盖本次运行的配置。合并到 main 始终不会自动执行;这仍是人工操作。有关阶段 B 所采用的完整评审意见接收和验证规则,请参阅 references/review-discipline.md。

配置

此文件旁的 config.json 中包含各项配置。运行开始时读取该文件,并在整个过程中使用其中的值。编辑复制的 config.json,使其与所用仓库的评审机器人以及(可选)Linear 工作区相匹配。

前十项控制 CI + 评审 循环:

键含义默认值
reviewBots将其评论和讨论串视为一等 AI 评审反馈的 GitHub 登录名。根据 author.login 匹配;会规范化 [bot] 后缀,因此 claude 和 claude[bot] 都能匹配(GraphQL API 返回不带后缀的形式)。请根据你的安装情况进行编辑——各仓库的评审机器人登录名可能不同。默认特意排除 github-actions:它发布的是 CI 状态和发布 PR 评论,而非代码评审,否则 Phase B 会将其作为发现项处理;只有当你的安装确实通过 Actions 机器人发布评审类评论时,才将其添加。["claude", "coderabbitai"]
reviewBotChecks将 reviewBots 登录名映射到该机器人每次评审所发布的提交状态或检查运行。值可以是检查名称字符串(例如 {"coderabbitai": "CodeRabbit"}),也可以是用于指定发布者的 { "name": "…", "producer": "…" }。name 键会匹配状态 context、检查运行名称、检查运行名称开头的 <key> / … 片段,或 <workflow> / <check>。设置 producer 后,状态的 creator.login 或检查套件的 app.slug 也必须匹配(不区分大小写;会规范化 [bot] 后缀)。只有当该状态或检查在当前头部提交上已终结,且时间晚于 ready 状态切换时,映射的机器人才能视为已完成(步骤 7)——草稿期间的“Review skipped”成功不计入,而已取消或跳过的运行表示“不会报告”,而非“缺失”。未映射的机器人则根据 ready 状态切换后、当前头部上的评审或评论活动来判断。若仓库调用 estate 的 reusable-claude-code-review.yml,rheged-skills-setup 会将 claude 映射到 { "name": "claude-review", "producer": "github-actions" }(调用方作业 ID)。{}
maxCiRounds停止并报告阻塞项前,Phase A 的最大重新监视迭代次数。此设置限制草稿期间的修复并监视循环,避免其无限运行。Phase B 不会消耗此次数。5
maxReviewRoundsPhase B 的最大重新评审轮数:每次应用推送后,从步骤 12 返回步骤 7(无人值守时重新规划,humanEnvelope 为 true 时重新生成处置方案),包括对此次推送重新监视 CI。达到上限后,停止并将未处理的发现项报告为阻塞项。2
replyOnAccept接受某项发现时,是否在解决讨论串前发布一条说明事实、引用修复提交的线程回复(审计记录)。设为 false 时,会静默解决已接受的讨论串,适用于不喜欢机器人回复干扰的维护者——对于拒绝的发现项,无论如何都会附上理由回复。true
promoteOnGreen控制从草稿切换为 ready 的唯一选项。设为 true 时,Phase A 结束后,如果草稿 PR 的所有必需检查都确实通过,则运行 gh pr ready <pr>,将其切换为可供评审的状态(启用 AI 评审的门槛),然后继续进入 Phase B,而不是在检查通过后停止。默认开启,启用此配置_即表示_人类作者已授权切换:确认检查通过后直接继续,无需另行征求批准。设为 false(或传入 --no-promote)即可选择退出,并在检查通过后停止。除非检查通过已得到_证实_(步骤 6 中观察到的汇总结果,而非“尚无失败”),不存在未解决的人类评审讨论串,且 mergeStateStatus 显示不存在未解决的基础分支偏移(BEHIND / DIRTY),否则不会执行升为 ready 的操作。明确的用户提示——或 --promote / --no-promote——会覆盖本次运行的此设置;--ci-only 和 --dry-run 从不执行升为 ready 的操作。true
deferNonBlocking设为 true(默认值)时,只有依据 references/review-discipline.md 中的影响程度标准判定为高影响的有效范围内发现项,才会建议接受;否则建议列为后续处理(与范围外发现项采用相同路径)。设为 false 可恢复处置方案路径中仅按范围判断的行为(每项有效的范围内发现项都建议接受;只有范围外发现项会列为后续处理)。无人值守路径始终应用该标准。true
humanEnvelope设为 false(默认值)时,加载 references/phase-b-unattended.md;设为 true 时,加载 references/phase-b-envelope.md。deferNonBlocking 仅适用于处置方案路径。--auto-apply 会在单次运行中强制使用无人值守模式。旧版 CLI 别名 defer / defer-pending 仍然有效。明确的用户提示会覆盖本次运行的配置。false
reviewIdleMinutes混合评审的静默判定窗口:至少一个已配置的机器人已在当前头部提交上报告(且没有映射机器人的检查仍在等待)后,如果获取器的 activityFingerprint 在此分钟数内未发生变化,则视为评审已完成。10
reviewWaitMaxMinutes切换为 ready 后(或在 PR 已处于 ready 状态时进入 Phase B 后)的混合等待硬性上限。如果到期时仍有机器人未报告,则在处置方案生成前运行慢速机器人微型门控(继续 / 延长等待 / 中止)。20
后续跟进捕获(Linear)的键和路由配置位于
references/follow-up-routing.md。

Phase B 仅对已配置的 reviewBots 执行操作。人类的审查评论会显示在最终报告中,但绝不会自动执行操作、回复或解决——这些都留给人类处理。

使用模式

自动模式 — 检测当前分支的 PR 及其阶段,然后运行:

triage-pr

指定 PR — 按编号或 URL 操作特定 PR:

triage-pr 123

仅运行 CI — 运行 Phase A 后停止,即使 PR 已准备就绪也不例外:

triage-pr --ci-only

试运行 — 报告失败的检查和未解决的问题,并提出修复方案, 但不做任何更改(不提交、不推送、不回复讨论串):

triage-pr --dry-run

检查通过后转为就绪 — Phase A 检查全部通过后,将草稿切换为就绪状态(然后 继续进入 Phase B)。默认已启用此操作(promoteOnGreen: true); 如果配置将 promoteOnGreen: false,则 --promote 会强制本次运行执行此操作,而 --no-promote 会强制在检查通过后停止:

triage-pr --promote

自动应用 Phase B — 强制本次运行走无人值守路径(发表评论计划 + 执行操作;不询问是/否;不显示仅限 Linear 的提示)。覆盖 humanEnvelope: true:

triage-pr --auto-apply

等待耗时较长的操作

Phase A 的 CI 监控和 Phase B 的审查等待通常需要 10–30 分钟。 等待时应使用主机能够持续运行的方式,并保持安静:

  • Claude Code。 前台命令最长运行时间为 10 分钟,且裸 sleep 会被阻止,因此绝不要串联前台 sleep,也不要依赖一次长时间的前台 --watch。 将等待作为后台命令运行(run_in_background):命令退出时,执行框架会重新调用你。对于 CI 监控,在后台运行 gh pr checks <pr> --watch --required。对于 Step 7 轮询,在后台 运行一个有界的 shell 循环,每 60 秒重新运行一次抓取器,满足稳定条件或达到最长等待时间后 退出(也可以使用 Monitor 工具,并在相同条件下运行 until 循环)。重新调用时重新读取结果; 不要通过反复进行短暂的前台调用来轮询。
  • Cursor。 每次等待都作为一个有界的 shell 命令运行,并确保在 终端超时前结束(例如 timeout 540 gh pr checks <pr> --watch --required,或运行最长约 9 分钟的循环),然后重复运行,直到满足 条件或预算用尽。
  • 任一主机。 不要发送“仍在等待”之类的中途消息;如果等待结束时 条件仍未满足(超时、预算用尽),则在下一个自然停止点报告。

流程

Step 1 — 定位 PR 并检测阶段
gh pr view <pr> --json number,isDraft,state,headRefName,baseRefName,mergeable,mergeStateStatus,statusCheckRollup
  • 根据参数解析 PR;如果未提供参数,则根据当前分支解析。如果 gh pr view 未找到 PR,停止并告知用户先使用 /send-it 创建 PR。
  • isDraft == true → Phase A。CI 检查通过后,步骤 6 会执行转为就绪操作(默认 启用 promoteOnGreen),将已通过全部检查的草稿切换为就绪状态,随后继续进入 Phase B。禁用此操作时(--no-promote / promoteOnGreen: false), 则报告结果并停止——AI 审查尚未运行,是否切换状态由人类决定。
  • isDraft == false → Phase A(确认/清理 CI),然后进入 Phase B。
  • 记录 baseRefName,用于漂移检查;记录 mergeStateStatus,用于冲突检测。
第 2 步 — 阶段 A:检查失败的检查项
gh api repos/<owner>/<repo>/rules/branches/<base> \
  --jq '.[] | select(.type=="required_status_checks") | .parameters.required_status_checks[].context'
gh pr checks <pr> --required

绿色仅表示必需检查项通过。 合并门槛是基分支的必需状态检查项,因此 CI 只根据这些检查项判定。查看分支规则中的必需上下文(上面的第一条命令;如果规则列表为空,则对旧版分支保护重复执行 gh api repos/<owner>/<repo>/branches/<base>/protection/required_status_checks --jq '.contexts[]')。只有当所有必需上下文都出现在最新提交上,并且已结束且成功(成功或已跳过)时,CI 才算绿色。gh pr checks <pr> --required(退出码:0 表示通过、8 表示待处理、1 表示失败)可以快速查看状态,但它只能看到已经注册的必需检查项:门控任务(例如“Detect Changes”步骤)可能还要稍后才会创建其余检查项,“推送后立即显示没有必需检查项报告”也是同样的情况。因此,汇总中缺失的必需上下文属于待处理,绝不算绿色。

非必需检查项——影子 CI 通道(例如 Buildkite 镜像)、AI 审核工作流(例如已取消的 claude-review),以及其他建议性状态——都只是参考信息:在第 13 步的报告中列出失败项,但绝不修复它们,绝不让它们阻止晋级,也绝不为它们消耗一个 maxCiRounds 轮次。只有当仓库确实没有必需检查项(两次查询结果都为空)时,才回退到完整汇总,但排除 reviewBotChecks 上下文,并在报告中说明这一点。

对于每个失败的必需 Actions 检查项,从该检查项的 detailsUrl(位于 statusCheckRollup 中)解析其运行 ID,并读取失败步骤的日志:

gh run view <run-id> --log-failed

记录实际失败的命令和错误行,而不只是检查项名称。你要诊断根本原因,而不是根据标签匹配问题。

第 3 步 — 阶段 A:对每项失败进行分类(范围内、上游问题或受门控)
git fetch origin <base>
git diff --name-only origin/<base>...HEAD   # files this PR actually touches
  • 范围内 — 失败涉及此 PR 差异中的文件,或者是可在分支最新提交上复现的 lint/测试/构建失败。修复它(第 4 步)——除非唯一的补救方式是更改 lint/格式化/静态分析配置,或添加忽略或禁用指令;这种情况下,无论失败与此 PR 的关联有多明确,都应优先归入下文的Lint 范围受门控。
  • 上游问题/基线漂移 — 无论此差异如何,该任务在 origin/<base> 上也会失败,或者 mergeStateStatus == BEHIND,或者错误涉及 PR 从未修改的文件。补救方式是变基或合并基分支(第 5 步),而不是编辑失败的代码。
  • Lint 范围受门控 — 唯一可行的补救方式是更改 lint/格式化/静态分析配置,或添加新的忽略/禁用指令。这是开发者的决定,因此不属于处理范围,你不能擅自更改。记录一项受门控事项——文件、你原本会进行的更改、没有可用代码修复方案的原因,以及首选替代方案(修复违规代码,或在共享配置包中提出规则更改)——然后继续本轮的其余工作,并在下一个自然的停顿点(第 6 步/第 13 步)汇报。完整范围列表见 references/review-discipline.md。
  • 只能通过放宽门槛才能“修复”的失败绝不属于处理范围——这是重要规则中的硬性禁令;上述受门控类别则是需由人工决定的灰色地带。
步骤 4 — 阶段 A:逐一修复范围内的失败
  • 在 PR 的范围内,采用能解决根本原因的最小修复。
  • 修复代码,绝不修补 lint 表面问题。 对于 lint/格式/静态分析失败,优先顺序为:(1)修复有问题的代码;(2)如果规则本身确实有误,应修改共享配置包 (@rheged-studio/eslint-config、@rheged-studio/markdownlint-config 等), 并向开发者提出,而不是在这里提交;(3)只有获得开发者批准,才能使用本地配置覆盖或忽略/禁用指令。你绝不能自行采取(2)或(3)——应将其归类为受限事项(步骤 3),然后继续处理。 例外: 如果 PR 自身的差异中已经包含由开发者编写的 lint 配置或忽略项变更,你可以修复其中确实存在的错误(例如导致 lint 任务失败的语法或架构错误),但绝不能放宽规则或扩大忽略范围。
  • 在本地重新运行具体的失败命令,并读取其退出代码后,才能声称问题已修复(例如 pnpm lint、 npx --yes [email protected] validate ./skills/<name>、失败的测试)。固定版本,确保本地检查与 CI 完全一致,避免版本被悄然替换。先有证据,再做声明——绝不能仅凭“应该”或“可能”就断言已修复。
  • 使用 Conventional Commit 格式的主题提交,然后推送。一次修复 → 一次验证 → 再处理下一项。
步骤 5 — 阶段 A:处理基准分支变更

仅当步骤 3 将失败归类为上游变更/分支落后时:

git fetch origin <base>
git merge origin/<base>      # or rebase, per the repo's convention
  • 合并干净 → 推送并重新监控(步骤 6)。
  • 存在冲突 → 转到下文的合并冲突。
步骤 6 — 阶段 A:持续重新监控 CI,直到全部通过或预算耗尽
gh pr checks <pr> --watch --required

使用等待长时间运行的操作中的主机模式运行监控——它可能会超出前台命令的时限。

  • 每次推送后,都要等待必需检查完成。仍为红色 → 回到步骤 2,除非所有剩余的红色检查都是步骤 3 中的门控项;此时应立即结束阶段 A(见下文的门控退出规则)。
  • 不得提前宣告“完成”。 在 gh pr checks --watch --required(或等效的新鲜必需检查汇总)退出且每项必需检查都已进入终态(成功或失败)之前,不要告诉用户运行已完成、检查全绿或已准备好供其处理。仍在运行或为红色的非必需检查不影响此要求。排队中、待处理或进行中的检查都不属于终态——“尚无失败”、空汇总或待处理与通过混杂,都不能证明检查全绿,也不能作为完成信号(每次宣告运行结束时,都要遵守下方推广门控的同等要求)。监视退出后要重新检查: 同一提交上启动的第二次工作流运行(再次推送,或 edited / ready_for_review 事件)可能会取消第一次运行;--watch 可能会在两次运行之间,或在门控作业创建剩余必需检查之前,以状态码 0 退出。宣告全绿之前,要重新应用步骤 2 的判定:该提交上的每项必需检查都已出现且成功;若某项必需检查因其运行被取消并被后续运行取代而显示失败,则不算失败——等待取代它的运行完成。
  • 监视期间保持安静。 优先静默等待或在后台监视,不要用打断其他工作的“仍在等待”之类消息频繁更新。仅在自然停顿点通知用户:人工处理项(步骤 10——需要审批的可执行处置方案)、步骤 13 报告(循环收敛时)、本步骤中记录的阶段 A 提前停止(禁用推广 / 推广门控未通过 / 仍有门控的 lint 表面项 / --ci-only / --dry-run)、慢速机器人微型门控(步骤 7),或需要作出决定的硬阻塞项 / maxCiRounds 或 maxReviewRounds 耗尽。人工处理项本身就是可执行事项——不要把 A-1178 的“不要引起注意”规则当成跳过它的理由。
  • 门控的 lint 表面项会终止循环。 如果所有剩余的红色检查都是步骤 3 中的门控项,应立即停止——不要耗尽 maxCiRounds,反复监视一个你已决定不修复的失败项。逐项报告门控项(文件、你原本会做的修改、首选替代方案),将其作为阶段 A 提前停止的事项,并把决定权交给开发者。CI 未全绿,因此下方的推广门控也无法通过;要明确指出这些门控项是未能推广的具体原因。
  • 循环次数受 maxCiRounds 限制。达到上限后停止,并将剩余失败项报告为阻塞项,不要无限循环。
  • 检查全绿且已准备好 → 继续阶段 B。
  • 检查全绿且为草稿、推广已禁用(--no-promote / promoteOnGreen: false)→ 报告检查全绿并停止。
  • 检查全绿且为草稿、推广已启用(默认,或使用 --promote)→ 翻转状态前运行推广门控。以下三项必须全部满足:
    1. 已证明全绿——全绿状态必须来自_本步骤_监视到的必需检查结果(步骤 2 的判定:该提交上的每项必需检查都已出现且成功;不能处于待处理状态,也不能只是“尚无失败”); 遵守阶段 A 已执行的退出码规则,绝不能为了翻转状态而粉饰成全绿。红色的非必需检查不会导致此门控失败。
    2. 没有未解决的人工讨论线程——运行 node scripts/review-threads.mjs <pr> --bots "<config.reviewBots joined by commas>" 并要求 humanThreads 为空。(草稿的 unresolvedThreads 本来就是空的——AI 审查尚未运行——因此此门控专门针对审查草稿的人工用户。)
    3. 没有未解决的基准分支偏移——翻转状态前立即重新获取最新的 mergeStateStatus(gh pr view <pr> --json mergeStateStatus),而不是使用步骤 1 的快照:阶段 A 期间的推送可能已改变该状态。要求其不是 BEHIND / DIRTY(阶段 A 的步骤 5 会解决范围内的偏移;若问题仍存在,不要推广——将其报告为阻塞项)。 三项全部通过 → 执行 gh pr ready <pr>,报告状态变更,然后继续执行阶段 B (步骤 7)。标记为就绪后以及阶段 B 中的推送都会重新触发 CI 和 AI 审查;阶段 A 受 maxCiRounds 限制,阶段 B 受 maxReviewRounds 限制。任何门禁未通过 → 不要标记为就绪;报告通过的检查以及未提升状态的具体原因,然后停止。在 --dry-run 模式下,报告将会提升状态(或说明原因),但不做任何状态变更。在 --ci-only 模式下,绝不提升状态——无论相关开关设置如何,只要通过检查就停止。
步骤 7 — 阶段 B:混合等待 AI 审查者

留在同一会话中。标记为就绪后(或进入阶段 B 时 PR 已处于就绪状态),轮询获取器,直到审查结果稳定——或者达到硬上限,触发慢速机器人微型门禁。按步骤 8 中的方法解析技能目录。

node scripts/review-threads.mjs <pr> --bots "<config.reviewBots joined by commas>" --bot-checks '<config.reviewBotChecks as JSON>'

所有稳定性字段都以当前头部提交(headRefOid)为范围,并且只统计标记为就绪后(readyAt)的活动。PR 处于草稿状态时发布的内容均不计入——尤其是 CodeRabbit 在草稿期间的演练和它的“Review skipped: draft pull request”状态;针对已被取代的头部提交发布的内容也不计入。

  • botStatus — 每个已配置的机器人对应一条记录:state 为 reported、pending、skipped 或 missing,并包含 via(check 或 activity)和 evidence。
    • 在 reviewBotChecks 中配置了映射的机器人(via: check),如果其状态或检查运行在头部提交上已终止成功,且时间晚于标记为就绪的时间,则为 reported;如果该运行处于排队或进行中,则为 pending;如果运行已取消、跳过、中立、失败,或描述中包含“Review skipped”,则为 skipped(它不会报告结果——绝不要等待它);如果尚无此类运行,则为 missing。
    • 未配置映射的机器人(via: activity),如果在标记为就绪后且针对头部提交执行了以下任一操作,则为 reported:提交审查、在审查讨论串中发表评论,或创建或就地编辑已完成的摘要——包括带有粘性标记的摘要,或 claude-code-action 的跟踪评论(当其内容变为“Claude finished @…'s task”时)(一次干净的 Claude 审查不会留下其他内容)。
      • 只有确认信息——即既不含粘性标记,也不含上述完成标头的评论,例如“Claude Code is working…”——不计入。
  • botsReported / botsSkipped / botsMissing — 按状态对 botStatus 分组; botsMissing 包含 pending 和 missing。
  • activityFingerprint — 头部、未关闭的机器人讨论串或机器人摘要(包括就地编辑)发生变化时,该值也会变化。

满足以下任一条件即视为稳定:

  1. 全部稳定 — botsMissing 为空(每个 reviewBots 条目均为 reported 或 skipped),或
  2. 空闲 — 至少一个机器人为 reported,没有映射的机器人处于 pending(待处理的检查意味着审查仍在运行),且 activityFingerprint 在 reviewIdleMinutes 内未发生变化,或
  3. 最长等待时间 — 阶段 B 等待开始后经过了 reviewWaitMaxMinutes。

使用等待长时间运行的操作中的主机模式安静地轮询(例如每 60 秒一次);等待期间不要联系用户,除非触发慢速机器人门禁。在步骤 13 的报告中列出 skipped 机器人,确保被取消的审查清晰可见,而非无声略过。

慢速机器人微型门禁——仅当 humanEnvelope 为 true 且最长等待时间已到、botsMissing 非空时触发。无人值守时(humanEnvelope: false / --auto-apply),跳过此门禁:带着当前发现继续执行步骤 8,并在步骤 13 中列出缺失的机器人。在 humanEnvelope 路径下,列出已完成与仍待处理的机器人,并在此会话中使用与步骤 10 相同的双主机结构化提问模式询问一次:

  1. 将超时情况放入聊天消息中(已报告的机器人与尚未响应的机器人)。
  2. 如有可用的结构化提问工具,优先使用:
    • **Cursor AskQuestion:**选项为 Proceed / Wait / Abort。
    • Claude Code AskUserQuestion:header 示例:Review wait(≤12 个字符); 选项为 Proceed / Wait / Abort(描述:使用目前的发现继续 / 延长等待时间 / 停止且不创建信封)。
  3. 备用方案(两种工具都不可用):使用文字说明
Review wait timed out after <N> minutes.
  Reported: claude
  Still outstanding: coderabbitai
Proceed with what we have / wait longer / abort? [proceed|wait|abort]
  • Proceed → 使用目前的发现继续执行步骤 8(在信封报告中注明缺失的机器人)。
  • Wait → 重置最大等待计时器(或再延长 reviewWaitMaxMinutes),并返回轮询循环。
  • Abort → 停止;保持线程不变;不创建处置信封。

在此关卡得到答复(或通过标题/空闲状态确认评审已结束)之前,不要打开处置信封。

步骤 8 — 阶段 B:获取未解决的评审反馈

运行随附的获取脚本(路径相对于此技能自身目录):

node scripts/review-threads.mjs <pr> --bots "<config.reviewBots joined by commas>"

此获取脚本为只读。写入操作由 respond-threads.mjs 执行(步骤 11)。

它会输出简洁的 JSON,包括:

  • unresolvedThreads — 由已配置的 reviewBot 提出的内联评审线程(isResolved == false),精简为 {threadId, path, line, isOutdated, author, url, comments}。GitHub 提供链接时,url 为第一个评审评论的永久链接(在步骤 10 的详情块中使用)。这是需要处理的集合。
  • deferredThreads — 已带有我们非解决型待跟进标记的机器人线程(来自之前的处理轮次)。在步骤 9 中不要重新分类;重新发现待处理捕获时,将其加入信封的跟进集合。
  • otherBotThreads — 由不在 reviewBots 中的 GitHub 机器人账号(如代码检查工具或监控应用)提出的未解决线程。在步骤 9 中像处理评审机器人发现的问题一样核实并处置(接受 / 拒绝 / 跟进 / 已过时),以免遗漏,但这些内容仅供参考:它们不会阻止晋升,不会触发无人值守情况下的人类线程停止,也不会延迟步骤 13。
  • humanThreads — 由人类提出的未解决线程。在报告中列出;不要自动处理。
  • aiSummaryComments — 每个评审机器人的标题摘要(固定问题评论和/或评审提交正文)。每个机器人最多一条。
  • botStatus、botsReported / botsSkipped / botsMissing、activityFingerprint、headRefOid、readyAt — 用于确认结束状态的辅助信息(步骤 7)。

已解决的线程会被过滤掉。若 unresolvedThreads 为空、otherBotThreads 为空、没有 AI 摘要,且没有 deferredThreads,则报告“没有可处理的 AI 评审反馈”,并跳至步骤 13。如果只剩下 deferredThreads,且 humanEnvelope: true,则将其并入信封计划;如果是无人值守模式(humanEnvelope: false / --auto-apply),则前往步骤 11 进行 Linear 捕获——不要提示仅处理 Linear 的内容。

步骤 9 — 阶段 B:先验证,再提出处置方案

对每项可执行的发现应用 READ → UNDERSTAND → VERIFY → EVALUATE — unresolvedThreads、摘要条目,以及 otherBotThreads(完整规则见 references/review-discipline.md)。在计划中将 otherBotThreads 条目标记为信息项;其处置方式与其他条目相同,但未解决的条目不会阻止本次运行。 暂勿 IMPLEMENT、创建 Linear 问题或解决讨论串——仅制定带编号的处置计划:

对每项发现记录:

  • 来源机器人 + 路径:行号(或问题级摘要条目)
  • 有则记录讨论串 / 评论的永久链接(成形后的讨论串中的 url,或摘要条目的问题评论 / 评审 URL)——没有可靠链接时省略,不要编造
  • 简短概述发现(1–3 句——无需打开 GitHub 即足以做出判断)
  • 验证概要(是否属实?是否在范围内?影响是否重大?)
  • 拟议处置:accept | decline | follow-up | outdated | gated
  • 对于 accept:具体的修复概要
  • 对于 decline:技术理由
  • 对于 follow-up:Linear 标题草稿 + 理由,以及下方路由步骤中的目标位置行 (→ file under …)
  • 对于 outdated:遵循 references/review-discipline.md(验证问题已消失,而非仅被移走)
  • 对于 gated:受影响的范围 + 首选替代方案——先分类,再评估影响; 完整的 lint 范围规则见 references/review-discipline.md

使用 references/review-discipline.md 中的标准分类影响(在 envelope 路径中,deferNonBlocking: false 会将每项有效且在范围内的发现都提议为 accept)。

当计划中包含后续事项(或无人值守的 [gated] 条目)时,只读解析目标位置,遵循 references/follow-up-routing.md。

根据 humanEnvelope 分支:

步骤 10 — 阶段 B:人工确认信封

当 humanEnvelope 为 true 时,执行 references/phase-b-envelope.md 中的步骤 10。当其为 false 或 --auto-apply 时,跳过——无人值守流程从上方的步骤 9 开始。

步骤 11 — 阶段 B:应用处置方案

按照 references/phase-b-envelope.md 或 references/phase-b-unattended.md,执行已批准的计划(envelope)或已发布的计划(无人值守)。按照 references/follow-up-routing.md 创建 Linear 后续事项。

node scripts/respond-threads.mjs thread --thread <PRRT_id> --decision accept --sha <sha> --bots "<config.reviewBots joined by commas>"
node scripts/respond-threads.mjs thread --thread <PRRT_id> --decision decline --reason "<technical reasoning>" --bots "<config.reviewBots joined by commas>"
node scripts/respond-threads.mjs thread --thread <PRRT_id> --decision follow-up-pending --bots "<config.reviewBots joined by commas>"
node scripts/respond-threads.mjs thread --thread <PRRT_id> --decision follow-up --reference <issue-id> --bots "<config.reviewBots joined by commas>"

respond-threads.mjs 只会处理作者属于 --bots 的讨论串。对于 otherBotThreads 条目,将该讨论串的作者追加到 --bots(--bots "<config.reviewBots>,<thread author>")。

步骤 12 — 阶段 B:问题级确认 + 重新封装

应用已批准的计划后,用一条汇总评论确认摘要中的重点发现:

node scripts/respond-threads.mjs summary --pr <pr> --findings '[{"title":"…","status":"accepted","reference":"<sha>"}]'

然后重新获取(步骤 8)。阶段 B 中的任何推送都会改变 head——记录新的 headRefOid,重置步骤 7 的等待计时,并返回步骤 7,之后才能判定没有新发现。如果出现新的机器人发现,继续执行步骤 7 → 步骤 9,并遵循路径文件的步骤 12 部分(重新封装或重新制定计划)。受 maxReviewRounds 限制。如果 CI 最终为绿色、机器人已针对当前 head 完成审查,且没有新的机器人发现,则继续执行步骤 13。

步骤 13 — 报告

这是完整运行结束时的完成提醒。只有在所有必需检查都已终结,或遇到硬性阻塞、预算耗尽、信封被拒绝或中止后,才发出提醒;检查仍在等待时绝不发出。Phase A 的提前停止应在步骤 6 退出时报告。

总结:

  • 已修复的检查,以及每项检查所针对的失败命令。
  • 信封结果(已批准/已拒绝)或已发布的无人值守计划;任何慢速机器人的决定(仅限信封路径)或缺失的机器人(无人值守);状态最终为 skipped 的机器人(已取消或已跳过的审查运行),并列出其证据。
  • otherBotThreads(非审查机器人)的处理结果,另行列出,仅供参考。
  • 已接受并修复的发现(注明解决该问题的提交)。
  • 已拒绝的发现,并逐项说明给出的技术理由。
  • 等待开发者决定的受门控 lint 范围事项——逐项列出文件、原本会进行的更改、没有可用代码修复方案的原因,以及首选替代方案(修复代码,或在共享配置包中提出)。此列表中的事项均未应用。
  • 已创建的后续问题(逐项注明其 Linear ID/URL、follow-up 标签,以及目标位置——继承的项目和里程碑、仅继承的项目,或兜底项目加仓库里程碑),或未跟踪的后续候选事项。
  • 已在合并评论中确认的问题级发现。
  • 已执行的基准合并/变基。
  • 剩余阻塞项(若 maxCiRounds 或 maxReviewRounds 已耗尽)。
  • 最终 CI 状态,并提供步骤 2 测试的最新证据——列出头部提交上的每个必需上下文及其终结状态;之后另行列出任何标红的非必需检查,仅供参考。
  • 任何人工审查评论,供人工处理。
  • PR 的草稿/就绪状态:若触发了晋升,报告状态切换(草稿 → 就绪),并说明之后运行了 Phase B;否则提醒状态未变——若已启用晋升但被某个门控条件阻止,则说明具体原因。

合并冲突

  • 只有在解决方式明确且属于 PR 范围内时才解决(例如双方修改了不同的代码块,或此分支的意图明显优先)。
  • 若意图不明确,则中止并询问人工:双方修改了同一逻辑内容、冲突涉及 PR 范围之外的文件,或解决冲突需要产品决策。运行 git merge --abort 并报告冲突文件。
  • 绝不要为了让代码编译而通过删除另一方的工作来解决冲突。

重要规则

  • 绝不粉饰。 绝不编辑 .github/workflows/*、禁用或放宽 lint 规则、删除或跳过测试,或放宽 CI 阈值来让检查通过。修复代码,或将失败报告为阻塞项。
  • Lint 检查范围由开发者决定。 将其归类为 受门控(Step 3 / Step 9);未经明确的 envelope 批准,绝不应用。完整政策和检查范围列表见: references/review-discipline.md。
  • 只处理范围内的问题。 仅修复本 PR 的差异所涉及的问题;不要修复无关的仓库问题。
  • 先验证,再实施。 未先针对代码库验证之前,绝不应用审查建议。
  • 仅处理 AI 机器人。 处理已配置的 reviewBots,并将 otherBotThreads 作为信息性、非阻塞发现;指出人工评论,但留给人工处理。
  • 不阿谀奉承。 以技术理由拒绝,不要恭维。
  • 先有证据,再作断言。 未重新运行验证命令并读取其退出代码前,绝不声称 CI 全绿或修复有效。CI 全绿意味着所有必需上下文都已出现,并且在最新提交上成功(Step 2)。只要仍有必需检查尚未进入终态(排队 / 待处理 / 进行中),就绝不声称运行已完成、已处理完毕或可供关注——“尚无失败”不等于全绿,也不等于完成。只在自然的停止点提醒人工:人工 envelope(Step 10,当 humanEnvelope 为 true 时)、Step 13、文档规定的 Step 6 Phase-A 提前停止条件(promotion 已禁用 / gate 失败 / 仍有受门控的 lint 检查项 / --ci-only / --dry-run)、慢速机器人的微型 gate,或硬性阻塞项 / 预算耗尽时——绝不要在监控过程中间发送“仍在等待”的提醒。
  • 两条 Phase B 路径。 加载 references/phase-b-envelope.md 或 references/phase-b-unattended.md;不要应用这些文件之外的处置方式。
  • Draft → ready 受保护,且默认开启。 promoteOnGreen 是切换状态的唯一控制项;启用的配置即为授权:开启时(默认值),skill 会在 Phase A 已验证全绿、没有未解决的人工讨论串且没有未解决的基准分支漂移后,才切换 PR 状态,然后继续进入 Phase B,无需另行征求人工批准。设置 promoteOnGreen: false / 传入 --no-promote 可在全绿时停止;显式的用户提示或 --promote / --no-promote 会在本次运行中覆盖配置。绝不为了切换状态而粉饰结果;--ci-only 绝不会执行 promotion。合并仍由人工操作。
  • 循环次数有上限。 Phase A 达到 maxCiRounds 或 Phase B 达到 maxReviewRounds 后停止并升级处理。

错误处理

  • gh auth status 失败 → 停止,并告知用户运行 gh auth login。
  • 当前分支没有 PR → 停止,并提示“先用 /send-it 创建一个”。
  • gh run view --log-failed 不可用(日志已过期或运行记录已清除)→ 按名称报告失败的检查,不要猜测原因;不要捏造修复方案。
  • 审查讨论串抓取器以非零状态退出(速率限制、权限或 GraphQL 错误)→ 报告该问题,并回退到 gh pr view <pr> --json reviews,comments。绝不要把“无法抓取”当成“没有发现”。
  • 过时的讨论串 → 按照 references/review-discipline.md 处理(--decision outdated)。
  • respond-threads.mjs 以非零状态退出(回复或解决讨论串的操作因权限失败)→ 回退到手动使用 gh api graphql 回复并说明理由,而不是中止;标记约定仍然适用,以便后续运行跳过该项。
  • 汇总评论的 summary upsert 找不到之前的评论(REST 分页上限约为 100 条)→ 它会发布新评论;这没有问题,只需避免手动删除标记,以便下一次运行能够找到并编辑该评论。

参数

$ARGUMENTS

评论

支持 Markdown