process-prs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseProcess PRs (one tick)
处理PR(单次周期)
One pass over the repo's open PRs per invocation, then stop. Compose with
for recurrence (, );
owns pacing and is the new-PR discovery mechanism. Never schedule yourself.
/loop/loop /process-prs/loop 1h /process-prs/loopState derives entirely from GitHub (labels, draft flag, commit/comment
timestamps), so a tick is idempotent and resumable: an empty queue costs one
and exits.
gh pr list每次调用会遍历仓库中所有开放的PR一次,然后停止。可与组合实现周期性执行(、);负责控制执行节奏,是发现新PR的机制。请勿自行调度。
/loop/loop /process-prs/loop 1h /process-prs/loop状态完全源自GitHub(标签、草稿标记、提交/评论时间戳),因此处理周期具有幂等性和可恢复性:空队列仅会执行一次命令后退出。
gh pr listRails
核心约束
- Never merge, never close. The verdict is a recommendation; merging and closing stay the maintainer's hand.
- Never push to a fork. Only branches in the repo itself are editable.
- Every PR comment and every issue starts with a disclaimer. PR comments:
. Issues:
> *This was generated by AI during PR processing.*.> *This was generated by AI during triage.* - Skip PRs owned by another active loop. If another dispatcher already drives a PR (its branch is in that loop's queue), leave it untouched. This pass handles everything else.
- 绝不合并,绝不关闭。 评审结果仅为建议;合并与关闭操作仍由维护者决定。
- 绝不推送到分支仓库。 仅可编辑仓库自身的分支。
- 所有PR评论和Issue均以免责声明开头。 PR评论:。Issue:
> *This was generated by AI during PR processing.*。> *This was generated by AI during triage.* - 跳过由其他活跃循环处理的PR。 如果已有其他调度器在处理某个PR(其分支在该循环的队列中),则不对其进行任何操作。本次处理周期负责处理所有其他PR。
0. Preflight
0. 预检步骤
-
Abort if not a git repo, or if there is no GitHub remote. This skill is GitHub-only (,
gh, pull requests). GitLab merge requests are a separate concern, not handled here.authorAssociation -
. Identify the default branch, do not assume
git fetch:mainbashgh repo view --json defaultBranchRef -q .defaultBranchRef.name -
Detect optional substrate; use what exists, skip what doesn't:
- Verdict labels (/
recommend-merge/recommend-close, plus the sharedrecommend-triage). If absent, offer to runneeds-info; without them the tick can review but cannot record a verdict, so stop and say so./setup-github-labels - Triage wiring (, an issue
docs/agents/triage-labels.mdaxis,type:/ready-for-agent) and anneeds-triage. Used for spin-off issues. If absent, fall back to plainissue-tracker.mdand skip the triage-state labels. A repo with none of this is fine.gh issue create
- Verdict labels (
-
如果当前不是Git仓库,或没有GitHub远程仓库,则终止执行。本技能仅支持GitHub(依赖命令、
gh字段、拉取请求)。GitLab合并请求不在本技能的处理范围内。authorAssociation -
执行。识别默认分支,请勿默认假设为
git fetch:mainbashgh repo view --json defaultBranchRef -q .defaultBranchRef.name -
检测可选的基础配置;使用已存在的配置,跳过不存在的:
- 评审结果标签(/
recommend-merge/recommend-close,以及通用的recommend-triage)。如果缺少这些标签,建议运行needs-info;没有这些标签的话,处理周期可以进行评审,但无法记录评审结果,因此会终止执行并告知原因。/setup-github-labels - 分类配置(文档、Issue的
docs/agents/triage-labels.md分类维度、type:/ready-for-agent标签)以及needs-triage文档。用于创建衍生Issue。如果缺少这些配置,则退化为使用普通的issue-tracker.md命令,并跳过分类状态标签。仓库没有这些配置也可以正常运行。gh issue create
- 评审结果标签(
Labels
标签说明
The three PR verdicts are mutually exclusive; a PR carries exactly one once
finalized:
- : finalized and endorsed, for the maintainer to review and merge.
recommend-merge - : active reject (broken, abandoned, superseded, out of scope, or a technical blocker the agent can name).
recommend-close - : code is sound but the merge/close call is a product or scope judgment the agent can't make.
recommend-triage
A PR parked on an outside human reuses the shared label. A PR still
being iterated stays a draft (no verdict label).
needs-infoPR的三种评审结果标签互斥;PR最终确定后只会带有其中一个标签:
- :评审完成且认可,供维护者审核并合并。
recommend-merge - :主动拒绝(PR存在问题、已废弃、被替代、超出范围,或存在可明确说明的技术障碍)。
recommend-close - :代码本身没问题,但合并/关闭的决定属于产品或范围判断,超出Agent的能力范围。
recommend-triage
需要外部人员补充信息的PR会使用通用的标签。仍在迭代中的PR保持草稿状态(无评审结果标签)。
needs-infoTick algorithm
处理周期算法
-
Build the queue. Open, non-draft PRs with noverdict, minus branches owned by another active loop:
recommend-*bashgh pr list --state open --json number,headRefName,isDraft,author,authorAssociation,labels \ --jq '[.[] | select(.isDraft|not)]'Also pull verdicted PRs to check for staleness (next step). -
Re-queue stale verdicts. For each PR wearing alabel, compare its latest commit time to the agent's last verdict comment. If the commit is newer, the verdict is stale: remove the label and put the PR back in the queue for this tick.
recommend-* -
Classify each queued PR by author:
- Own: is
authorAssociationorOWNER. Full finalize.MEMBER - Bot: author is a bot (Dependabot et al.). Mechanical review.
- Community: everyone else. Review-only.
- Own:
-
Process, respecting throughput. Review all queued community and bot PRs (cheap). Full-finalize at most one own PR per tick, to avoid two rebase chains conflicting. Apply the per-tier pipeline below.
-
Handle in-flight PRs. A PR with no verdict whose checks are still pending and which the agent already pushed/commented on is "awaiting CI", so skip it; the next tick re-checks. This state is derived from GitHub, not stored.
-
Report. End with a short dashboard: each queued PR and the action taken, verdicts emitted, PRs awaiting CI, spin-off issues filed, anything needing the maintainer.reads this to pace the next run.
/loop
-
构建处理队列。 筛选出所有开放、非草稿状态且未带有评审标签的PR,排除由其他活跃循环处理的分支:
recommend-*bashgh pr list --state open --json number,headRefName,isDraft,author,authorAssociation,labels \ --jq '[.[] | select(.isDraft|not)]'同时拉取已带有评审标签的PR,用于检查评审结果是否过期(下一步操作)。 -
重新调度过期的评审结果。 对于每个带有标签的PR,将其最新提交时间与Agent上次评审评论的时间进行对比。如果提交时间更新,则评审结果已过期:移除该标签并将PR重新加入本次处理周期的队列。
recommend-* -
按作者类型分类队列中的PR:
- 内部成员:为
authorAssociation或OWNER。执行完整的终处理流程。MEMBER - Bot账号:作者为Bot(如Dependabot等)。执行机械性评审。
- 社区贡献者:其他所有作者。仅执行评审流程。
- 内部成员:
-
处理时考虑吞吐量限制。 评审所有队列中的社区贡献者和Bot提交的PR(成本较低)。单次处理周期中最多对一个内部成员PR执行完整终处理,避免两个变基链产生冲突。按照以下分层流水线进行处理。
-
处理进行中的PR。 未带有评审标签、CI检查仍在进行中且Agent已推送/评论过的PR属于"等待CI"状态,因此跳过;下一次处理周期会重新检查。该状态直接从GitHub获取,无需本地存储。
-
生成报告。 处理结束后生成简短的仪表盘:列出每个队列中的PR及执行的操作、发出的评审结果、等待CI的PR、创建的衍生Issue以及需要维护者处理的事项。会读取该报告来控制下一次执行的节奏。
/loop
Per-tier pipeline
分层处理流水线
Own PRs: full finalize
内部成员PR:完整终处理
Skip the PR this tick if it is already awaiting CI from a prior tick (step 5) —
do not re-finalize while checks are pending. Otherwise:
-
Rebase only if a fresh CI run against currentis actually needed. A rebase forces a push, which re-triggers CI and costs a whole extra tick of waiting, so don't pay it reflexively. When CI runs on
mainwith a barepull_request(the common case; confirm in the workflow), a green check already tested the PR merged intoactions/checkout, but only asmainstood when CI last ran, since GitHub does not re-run CI whenmainadvances. So the real question is whether that green has gone stale in a way that matters. Compute the divergence (use the default branch and the PR's head ref, not literalmain):mainbashgh pr view <N> --json mergeStateStatus,files \ -q '{state: .mergeStateStatus, files: [.files[].path]}' base=$(git merge-base origin/<defaultBranch> origin/<headRef>) git diff --name-only "$base"..origin/<defaultBranch> # files main changed since base git rev-list --count "$base"..origin/<defaultBranch> # commits main gained since baseRebase (then let the pipeline force-push, re-triggering CI) iff any holds:- merge state is /conflicting (a textual conflict to resolve), or
DIRTY(branch protection requires up-to-date before merge);BEHIND - 's post-base files intersect the PR's changed files, a direct overlap, so the merged result the PR's tests cover may actually differ;
main - gained more than 20 commits since the merge-base, a catch-all: a large disjoint advance can still carry a transitive/semantic break (a renamed or deleted symbol the PR calls from another file) that the stale green never exercised.
main
Otherwise skip the rebase entirely.moved only in files disjoint from the PR and within the cap, so the existing green still reflects the merged result; leave the branch untouched and let the PR be verdicted this same tick (step 5). (If merge state ismain, GitHub is still computing mergeability; re-check next tick rather than guessing.)UNKNOWN - merge state is
-
Gatebehind a cheap
/review-fixpass. Don't pay the full loop reflexively. An own PR that is already non-draft has, by convention, been through/code-reviewbefore it was un-drafted, so re-running the full loop (six reviewers, up to five rounds, plus a force-push that re-triggers CI and costs another whole tick) is usually wasted motion. So first run a single report-only/review-fixat medium effort (no/code-review) over the diff as a safety net (the same cheap gate the community tier uses, and one of the six reviewers--fixwould run), then branch on what it finds:/review-fix- No meaningful findings (clean, or only nits already matching repo
conventions) → skip entirely; the PR is already settled. Go to step 3.
/review-fix - Meaningful findings (a real correctness or design fix, or several
concerns at once) → escalate to , which runs the bundled reviewers, applies the meaningful fixes, folds them into clean commits, and force-pushes with lease.
/review-fix
- No meaningful findings (clean, or only nits already matching repo
conventions) → skip
-
: reshape into a clean, logical commit sequence.
/recommit -
: only if the PR changes runtime behavior and a smoke is practical.
/verifypicks the method per project type (CLI invocation, server boot, library import, GUI launch); skip for docs/refactor/test-only PRs./verify -
Resolve CI non-blocking. If no push happened this tick (no rebase per step 1, andand
/review-fixeach left the branch untouched), the existing checks are authoritative: read them directly and verdict now without waiting, applying the outcome rules below. Only a push made this tick puts the PR into the awaiting-CI state; when its checks are pending, leave the PR awaiting CI and move on, and a later tick applies the same rules. The outcome rules:/recommit- green → .
recommend-merge - red, no prior agent fix-attempt on the PR → one fix-and-repush attempt, then leave it awaiting CI again.
- red, a prior agent fix-attempt already exists → (a red build is a nameable technical blocker, not a sound-code scope call) with the failure quoted.
recommend-close
The one-attempt cap is derived from the PR's history, not stored: a prior agent fix-attempt = a commit the git user pushed to the branch after the first red CI, paired with its disclaimer-prefixed comment. Check the current CI outcome before the cap — a now-green PR takes the green branch regardless. - green →
-
Emit the verdict with a disclaimer-prefixed comment.
如果PR已处于等待CI状态(来自上一次处理周期的步骤5),则本次处理周期跳过该PR——CI检查进行中时请勿重新执行终处理。否则:
-
仅在确实需要针对当前默认分支运行全新CI时才执行变基。 变基会触发推送操作,进而重新触发CI,且需要额外等待一个处理周期,因此请勿盲目执行。当CI在事件中使用裸
pull_request(常见情况;需在工作流中确认)时,绿色检查标记已测试过PR合并到默认分支后的状态,但仅基于CI上次运行时默认分支的状态,因为GitHub不会在默认分支更新时重新运行CI。因此核心问题是:该绿色标记是否在关键方面已过期。计算分支差异(使用默认分支和PR的头部分支,而非字面意义上的actions/checkout):mainbashgh pr view <N> --json mergeStateStatus,files \ -q '{state: .mergeStateStatus, files: [.files[].path]}' base=$(git merge-base origin/<defaultBranch> origin/<headRef>) git diff --name-only "$base"..origin/<defaultBranch> # 默认分支自基准点以来修改的文件 git rev-list --count "$base"..origin/<defaultBranch> # 默认分支自基准点以来新增的提交数满足以下任一条件时执行变基(然后由流水线强制推送,重新触发CI):- 合并状态为(存在文本冲突需解决)或
DIRTY(分支保护要求合并前必须与默认分支同步);BEHIND - 默认分支自基准点以来修改的文件与PR修改的文件存在直接重叠,因此PR测试覆盖的合并结果可能已发生变化;
- 默认分支自基准点以来新增超过20个提交,这是一个兜底条件:大量不相关的更新仍可能导致传递性/语义性破坏(如PR调用的符号被重命名或删除),而过期的绿色标记无法检测到此类问题。
否则完全跳过变基。 默认分支仅在与PR不相关的文件中发生了少量更新,因此现有的绿色标记仍能反映合并后的结果;保持分支不变,且在本次处理周期中直接给出评审结果(步骤5)。(如果合并状态为,说明GitHub仍在计算可合并性;下次处理周期再重新检查,请勿猜测。)UNKNOWN - 合并状态为
-
在低成本的检查后再触发
/code-review。请勿盲目执行完整循环。 已转为非草稿状态的内部成员PR,按照惯例在转为非草稿前已通过/review-fix处理,因此重新运行完整循环(六位评审者、最多五轮迭代,加上会触发CI并额外等待一个处理周期的强制推送)通常是浪费资源。因此首先对差异内容执行一次中等强度的仅报告式/review-fix(不使用/code-review参数)作为安全检查(与社区贡献者层级使用的低成本检查相同,也是--fix会调用的六位评审者之一),然后根据检查结果分支处理:/review-fix- 无实质性问题(代码干净,或仅存在符合仓库规范的小问题)→ 完全跳过;PR已就绪。进入步骤3。
/review-fix - 存在实质性问题(需要修复正确性或设计问题,或同时存在多个问题)→ 升级为执行,该命令会调用内置评审者、应用实质性修复、将修复整理为清晰的提交,并通过lease机制强制推送。
/review-fix
- 无实质性问题(代码干净,或仅存在符合仓库规范的小问题)→ 完全跳过
-
:将提交重构为清晰、逻辑连贯的提交序列。
/recommit -
:仅当PR修改了运行时行为且可执行冒烟测试时才执行。
/verify会根据项目类型选择测试方法(CLI调用、服务器启动、库导入、GUI启动);文档/重构/仅测试代码的PR可跳过此步骤。/verify -
非阻塞式处理CI结果。 如果本次处理周期未执行推送操作(步骤1未变基,且和
/review-fix均未修改分支),则现有CI检查结果是权威的:直接读取结果并立即给出评审结果,遵循以下规则。仅当本次处理周期执行了推送操作时,PR才会进入等待CI状态;当CI检查进行中时,将PR标记为等待CI并继续处理其他PR,后续处理周期会应用相同规则。结果规则:/recommit- 绿色→标记。
recommend-merge - 红色,且PR上无Agent之前的修复尝试→执行一次修复并重新推送,然后将PR标记为等待CI。
- 红色,且PR上已有Agent之前的修复尝试→标记(构建失败是可明确说明的技术障碍,而非代码质量合格但需范围判断的情况),并引用失败原因。
recommend-close
一次修复尝试的限制基于PR的历史记录,无需本地存储:Agent之前的修复尝试指首次CI失败后,由git用户推送到分支的提交,且带有前缀为免责声明的评论。在应用限制前先检查当前CI结果——如果现在已变为绿色,则遵循绿色分支的规则。 - 绿色→标记
-
发布带有免责声明前缀的评审结果评论。
Community PRs: review-only, no pushing
社区贡献者PR:仅评审,不推送
- at medium effort, without
/code-review.--fix - Post one consolidated, disclaimer-prefixed review comment (never inline spam).
- Verdict:
- mergeable as-is, CI green → .
recommend-merge - sound but a product/scope call → .
recommend-triage - broken, abandoned, superseded, out of scope, or red CI with a technical
blocker → , reason quoted.
recommend-close - needs changes the author must make (incl. a trivial CI fix, or checks not
yet authorized) → leave the review comment and park on .
needs-info
- mergeable as-is, CI green →
- 执行中等强度的,不使用
/code-review参数。--fix - 发布一条整合后的、前缀为免责声明的评审评论(绝不发布零散的内联评论)。
- 评审结果:
- 可直接合并,CI绿色→标记。
recommend-merge - 代码质量合格但需产品/范围判断→标记。
recommend-triage - 存在问题、已废弃、被替代、超出范围,或CI红色且存在技术障碍→标记,并引用原因。
recommend-close - 需要作者进行修改(包括 trivial 的CI修复,或检查尚未授权)→发布评审评论并标记。
needs-info
- 可直接合并,CI绿色→标记
Bot PRs: mechanical
Bot PR:机械性处理
Review-only; the verdict is mechanical and never applies:
needs-info- patch/minor bump, CI green → .
recommend-merge - red CI → (a failing bump is a nameable technical blocker), failure quoted.
recommend-close - major version or breaking changelog, CI green → (a sound bump, but taking it is a scope call).
recommend-triage
仅执行评审;评审结果为机械性判断,且绝不使用标签:
needs-info- 补丁/小版本更新,CI绿色→标记。
recommend-merge - CI红色→标记(失败的版本更新是可明确说明的技术障碍),并引用失败原因。
recommend-close - 大版本更新或破坏性变更日志,CI绿色→标记(版本更新本身没问题,但是否接受属于范围判断)。
recommend-triage
Spin-off issues
衍生Issue
While processing a PR, this pass captures two kinds of work as GitHub issues,
autonomously but guarded:
- Follow-up: a loose end from this PR that should not block its merge (a
TODO left behind, a test-coverage gap, a deferred refactor). The PR still gets
its verdict; note the filed issues in the verdict comment
(). A follow-up never blocks the parent's merge.
follow-ups: #N, #M - Idea: a standalone improvement noticed while reading the code.
For every spin-off issue:
- Dedup-search open issues first; skip if one already covers it.
- Create it with (or the repo's
gh issue createconventions), including the triage disclaimer and a link back to the originating PR. Add aissue-tracker.mdlabel if the substrate exists, but leave the triage state totype:: file it without a triage-state label so the next/process-issuestick picks it up and routes it./process-issues - List it in the tick report.
在处理PR的过程中,本次处理周期会自动将两类工作转化为GitHub Issue,但会进行防护:
- 后续任务:PR中不应阻碍合并的遗留问题(遗留的TODO、测试覆盖率缺口、延迟的重构)。PR仍会获得评审结果;在评审结果评论中提及已创建的Issue()。后续任务绝不阻碍父PR的合并。
follow-ups: #N, #M - 改进想法:阅读代码时发现的独立改进点。
对于每个衍生Issue:
- 先搜索开放的Issue进行去重;如果已有相关Issue则跳过。
- 使用(或仓库的
gh issue create规范)创建Issue,包含分类免责声明和指向源PR的链接。如果基础配置存在,则添加issue-tracker.md标签,但将分类状态留给type:处理:创建时不添加分类状态标签,以便下一次/process-issues处理周期能识别并路由该Issue。/process-issues - 在处理周期报告中列出该Issue。
Composition
流程协作
The spin-off issues filed here land unlabeled, so picks them up
and triages them. An issue that becomes is implemented by
, whose resulting PR flows back into this pass. Three
single-purpose passes, each -paced, none ever merging: triage, implement,
finalize.
/process-issuesready-for-agent/implement-issues/loop此处创建的衍生Issue无标签,因此会识别并分类它们。变为状态的Issue会由实现,其生成的PR会重新进入本次处理流程。三个单一用途的处理周期,均由控制节奏,均不执行合并:分类、实现、终处理。
/process-issuesready-for-agent/implement-issues/loop