process-prs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Process PRs (one tick)

处理PR(单次周期)

One pass over the repo's open PRs per invocation, then stop. Compose with
/loop
for recurrence (
/loop /process-prs
,
/loop 1h /process-prs
);
/loop
owns pacing and is the new-PR discovery mechanism. Never schedule yourself.
State derives entirely from GitHub (labels, draft flag, commit/comment timestamps), so a tick is idempotent and resumable: an empty queue costs one
gh pr list
and exits.
每次调用会遍历仓库中所有开放的PR一次,然后停止。可与
/loop
组合实现周期性执行(
/loop /process-prs
/loop 1h /process-prs
);
/loop
负责控制执行节奏,是发现新PR的机制。请勿自行调度。
状态完全源自GitHub(标签、草稿标记、提交/评论时间戳),因此处理周期具有幂等性和可恢复性:空队列仅会执行一次
gh pr list
命令后退出。

Rails

核心约束

  • 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:
    > *This was generated by AI during PR processing.*
    . Issues:
    > *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评论:
    > *This was generated by AI during PR processing.*
    。Issue:
    > *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
    ,
    authorAssociation
    , pull requests). GitLab merge requests are a separate concern, not handled here.
  • git fetch
    . Identify the default branch, do not assume
    main
    :
    bash
    gh repo view --json defaultBranchRef -q .defaultBranchRef.name
  • Detect optional substrate; use what exists, skip what doesn't:
    • Verdict labels (
      recommend-merge
      /
      recommend-close
      /
      recommend-triage
      , plus the shared
      needs-info
      ). If absent, offer to run
      /setup-github-labels
      ; without them the tick can review but cannot record a verdict, so stop and say so.
    • Triage wiring (
      docs/agents/triage-labels.md
      , an issue
      type:
      axis,
      ready-for-agent
      /
      needs-triage
      ) and an
      issue-tracker.md
      . Used for spin-off issues. If absent, fall back to plain
      gh issue create
      and skip the triage-state labels. A repo with none of this is fine.
  • 如果当前不是Git仓库,或没有GitHub远程仓库,则终止执行。本技能仅支持GitHub(依赖
    gh
    命令、
    authorAssociation
    字段、拉取请求)。GitLab合并请求不在本技能的处理范围内。
  • 执行
    git fetch
    。识别默认分支,请勿默认假设为
    main
    bash
    gh repo view --json defaultBranchRef -q .defaultBranchRef.name
  • 检测可选的基础配置;使用已存在的配置,跳过不存在的:
    • 评审结果标签
      recommend-merge
      /
      recommend-close
      /
      recommend-triage
      ,以及通用的
      needs-info
      )。如果缺少这些标签,建议运行
      /setup-github-labels
      ;没有这些标签的话,处理周期可以进行评审,但无法记录评审结果,因此会终止执行并告知原因。
    • 分类配置
      docs/agents/triage-labels.md
      文档、Issue的
      type:
      分类维度、
      ready-for-agent
      /
      needs-triage
      标签)以及
      issue-tracker.md
      文档。用于创建衍生Issue。如果缺少这些配置,则退化为使用普通的
      gh issue create
      命令,并跳过分类状态标签。仓库没有这些配置也可以正常运行。

Labels

标签说明

The three PR verdicts are mutually exclusive; a PR carries exactly one once finalized:
  • recommend-merge
    : finalized and endorsed, for the maintainer to review and merge.
  • recommend-close
    : active reject (broken, abandoned, superseded, out of scope, or a technical blocker the agent can name).
  • recommend-triage
    : code is sound but the merge/close call is a product or scope judgment the agent can't make.
A PR parked on an outside human reuses the shared
needs-info
label. A PR still being iterated stays a draft (no verdict label).
PR的三种评审结果标签互斥;PR最终确定后只会带有其中一个标签:
  • recommend-merge
    :评审完成且认可,供维护者审核并合并。
  • recommend-close
    :主动拒绝(PR存在问题、已废弃、被替代、超出范围,或存在可明确说明的技术障碍)。
  • recommend-triage
    :代码本身没问题,但合并/关闭的决定属于产品或范围判断,超出Agent的能力范围。
需要外部人员补充信息的PR会使用通用的
needs-info
标签。仍在迭代中的PR保持草稿状态(无评审结果标签)。

Tick algorithm

处理周期算法

  1. Build the queue. Open, non-draft PRs with no
    recommend-*
    verdict, minus branches owned by another active loop:
    bash
    gh 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).
  2. Re-queue stale verdicts. For each PR wearing a
    recommend-*
    label, 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.
  3. Classify each queued PR by author:
    • Own:
      authorAssociation
      is
      OWNER
      or
      MEMBER
      . Full finalize.
    • Bot: author is a bot (Dependabot et al.). Mechanical review.
    • Community: everyone else. Review-only.
  4. 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.
  5. 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.
  6. 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.
    /loop
    reads this to pace the next run.
  1. 构建处理队列。 筛选出所有开放、非草稿状态且未带有
    recommend-*
    评审标签的PR,排除由其他活跃循环处理的分支:
    bash
    gh pr list --state open --json number,headRefName,isDraft,author,authorAssociation,labels \
      --jq '[.[] | select(.isDraft|not)]'
    同时拉取已带有评审标签的PR,用于检查评审结果是否过期(下一步操作)。
  2. 重新调度过期的评审结果。 对于每个带有
    recommend-*
    标签的PR,将其最新提交时间与Agent上次评审评论的时间进行对比。如果提交时间更新,则评审结果已过期:移除该标签并将PR重新加入本次处理周期的队列。
  3. 按作者类型分类队列中的PR:
    • 内部成员
      authorAssociation
      OWNER
      MEMBER
      。执行完整的终处理流程。
    • Bot账号:作者为Bot(如Dependabot等)。执行机械性评审。
    • 社区贡献者:其他所有作者。仅执行评审流程。
  4. 处理时考虑吞吐量限制。 评审所有队列中的社区贡献者和Bot提交的PR(成本较低)。单次处理周期中最多对一个内部成员PR执行完整终处理,避免两个变基链产生冲突。按照以下分层流水线进行处理。
  5. 处理进行中的PR。 未带有评审标签、CI检查仍在进行中且Agent已推送/评论过的PR属于"等待CI"状态,因此跳过;下一次处理周期会重新检查。该状态直接从GitHub获取,无需本地存储。
  6. 生成报告。 处理结束后生成简短的仪表盘:列出每个队列中的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:
  1. Rebase only if a fresh CI run against current
    main
    is 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
    pull_request
    with a bare
    actions/checkout
    (the common case; confirm in the workflow), a green check already tested the PR merged into
    main
    , but only as
    main
    stood when CI last ran, since GitHub does not re-run CI when
    main
    advances. 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 literal
    main
    ):
    bash
    gh 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 base
    Rebase (then let the pipeline force-push, re-triggering CI) iff any holds:
    • merge state is
      DIRTY
      /conflicting (a textual conflict to resolve), or
      BEHIND
      (branch protection requires up-to-date before merge);
    • main
      '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.
    Otherwise skip the rebase entirely.
    main
    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 is
    UNKNOWN
    , GitHub is still computing mergeability; re-check next tick rather than guessing.)
  2. Gate
    /review-fix
    behind a cheap
    /code-review
    pass. Don't pay the full loop reflexively.
    An own PR that is already non-draft has, by convention, been through
    /review-fix
    before 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
    /code-review
    at medium effort (no
    --fix
    ) over the diff as a safety net (the same cheap gate the community tier uses, and one of the six reviewers
    /review-fix
    would run), then branch on what it finds:
    • No meaningful findings (clean, or only nits already matching repo conventions) → skip
      /review-fix
      entirely; the PR is already settled. Go to step 3.
    • Meaningful findings (a real correctness or design fix, or several concerns at once) → escalate to
      /review-fix
      , which runs the bundled reviewers, applies the meaningful fixes, folds them into clean commits, and force-pushes with lease.
  3. /recommit
    : reshape into a clean, logical commit sequence.
  4. /verify
    : only if the PR changes runtime behavior and a smoke is practical.
    /verify
    picks the method per project type (CLI invocation, server boot, library import, GUI launch); skip for docs/refactor/test-only PRs.
  5. Resolve CI non-blocking. If no push happened this tick (no rebase per step 1, and
    /review-fix
    and
    /recommit
    each 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:
    • 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 →
      recommend-close
      (a red build is a nameable technical blocker, not a sound-code scope call) with the failure quoted.
    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.
  6. Emit the verdict with a disclaimer-prefixed comment.
如果PR已处于等待CI状态(来自上一次处理周期的步骤5),则本次处理周期跳过该PR——CI检查进行中时请勿重新执行终处理。否则:
  1. 仅在确实需要针对当前默认分支运行全新CI时才执行变基。 变基会触发推送操作,进而重新触发CI,且需要额外等待一个处理周期,因此请勿盲目执行。当CI在
    pull_request
    事件中使用裸
    actions/checkout
    (常见情况;需在工作流中确认)时,绿色检查标记已测试过PR合并到默认分支后的状态,但仅基于CI上次运行时默认分支的状态,因为GitHub不会在默认分支更新时重新运行CI。因此核心问题是:该绿色标记是否在关键方面已过期。计算分支差异(使用默认分支和PR的头部分支,而非字面意义上的
    main
    ):
    bash
    gh 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)。(如果合并状态为
    UNKNOWN
    ,说明GitHub仍在计算可合并性;下次处理周期再重新检查,请勿猜测。)
  2. 在低成本的
    /code-review
    检查后再触发
    /review-fix
    。请勿盲目执行完整循环。
    已转为非草稿状态的内部成员PR,按照惯例在转为非草稿前已通过
    /review-fix
    处理,因此重新运行完整循环(六位评审者、最多五轮迭代,加上会触发CI并额外等待一个处理周期的强制推送)通常是浪费资源。因此首先对差异内容执行一次中等强度的仅报告式
    /code-review
    (不使用
    --fix
    参数)作为安全检查(与社区贡献者层级使用的低成本检查相同,也是
    /review-fix
    会调用的六位评审者之一),然后根据检查结果分支处理:
    • 无实质性问题(代码干净,或仅存在符合仓库规范的小问题)→ 完全跳过
      /review-fix
      ;PR已就绪。进入步骤3。
    • 存在实质性问题(需要修复正确性或设计问题,或同时存在多个问题)→ 升级为执行
      /review-fix
      ,该命令会调用内置评审者、应用实质性修复、将修复整理为清晰的提交,并通过lease机制强制推送。
  3. /recommit
    :将提交重构为清晰、逻辑连贯的提交序列。
  4. /verify
    :仅当PR修改了运行时行为且可执行冒烟测试时才执行。
    /verify
    会根据项目类型选择测试方法(CLI调用、服务器启动、库导入、GUI启动);文档/重构/仅测试代码的PR可跳过此步骤。
  5. 非阻塞式处理CI结果。 如果本次处理周期未执行推送操作(步骤1未变基,且
    /review-fix
    /recommit
    均未修改分支),则现有CI检查结果是权威的:直接读取结果并立即给出评审结果,遵循以下规则。仅当本次处理周期执行了推送操作时,PR才会进入等待CI状态;当CI检查进行中时,将PR标记为等待CI并继续处理其他PR,后续处理周期会应用相同规则。结果规则:
    • 绿色→标记
      recommend-merge
    • 红色,且PR上无Agent之前的修复尝试→执行一次修复并重新推送,然后将PR标记为等待CI。
    • 红色,且PR上已有Agent之前的修复尝试→标记
      recommend-close
      (构建失败是可明确说明的技术障碍,而非代码质量合格但需范围判断的情况),并引用失败原因。
    一次修复尝试的限制基于PR的历史记录,无需本地存储:Agent之前的修复尝试指首次CI失败后,由git用户推送到分支的提交,且带有前缀为免责声明的评论。在应用限制前先检查当前CI结果——如果现在已变为绿色,则遵循绿色分支的规则。
  6. 发布带有免责声明前缀的评审结果评论。

Community PRs: review-only, no pushing

社区贡献者PR:仅评审,不推送

  1. /code-review
    at medium effort, without
    --fix
    .
  2. Post one consolidated, disclaimer-prefixed review comment (never inline spam).
  3. 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 →
      recommend-close
      , reason quoted.
    • 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
      .
  1. 执行中等强度的
    /code-review
    不使用
    --fix
    参数
  2. 发布一条整合后的、前缀为免责声明的评审评论(绝不发布零散的内联评论)。
  3. 评审结果:
    • 可直接合并,CI绿色→标记
      recommend-merge
    • 代码质量合格但需产品/范围判断→标记
      recommend-triage
    • 存在问题、已废弃、被替代、超出范围,或CI红色且存在技术障碍→标记
      recommend-close
      ,并引用原因。
    • 需要作者进行修改(包括 trivial 的CI修复,或检查尚未授权)→发布评审评论并标记
      needs-info

Bot PRs: mechanical

Bot PR:机械性处理

Review-only; the verdict is mechanical and
needs-info
never applies:
  • patch/minor bump, CI green →
    recommend-merge
    .
  • red CI →
    recommend-close
    (a failing bump is a nameable technical blocker), failure quoted.
  • major version or breaking changelog, CI green →
    recommend-triage
    (a sound bump, but taking it is a scope call).
仅执行评审;评审结果为机械性判断,且绝不使用
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 (
    follow-ups: #N, #M
    ). A follow-up never blocks the parent's merge.
  • Idea: a standalone improvement noticed while reading the code.
For every spin-off issue:
  1. Dedup-search open issues first; skip if one already covers it.
  2. Create it with
    gh issue create
    (or the repo's
    issue-tracker.md
    conventions), including the triage disclaimer and a link back to the originating PR. Add a
    type:
    label if the substrate exists, but leave the triage state to
    /process-issues
    : file it without a triage-state label so the next
    /process-issues
    tick picks it up and routes it.
  3. List it in the tick report.
在处理PR的过程中,本次处理周期会自动将两类工作转化为GitHub Issue,但会进行防护:
  • 后续任务:PR中不应阻碍合并的遗留问题(遗留的TODO、测试覆盖率缺口、延迟的重构)。PR仍会获得评审结果;在评审结果评论中提及已创建的Issue(
    follow-ups: #N, #M
    )。后续任务绝不阻碍父PR的合并。
  • 改进想法:阅读代码时发现的独立改进点。
对于每个衍生Issue:
  1. 先搜索开放的Issue进行去重;如果已有相关Issue则跳过。
  2. 使用
    gh issue create
    (或仓库的
    issue-tracker.md
    规范)创建Issue,包含分类免责声明和指向源PR的链接。如果基础配置存在,则添加
    type:
    标签,但将分类状态留给
    /process-issues
    处理:创建时不添加分类状态标签,以便下一次
    /process-issues
    处理周期能识别并路由该Issue。
  3. 在处理周期报告中列出该Issue。

Composition

流程协作

The spin-off issues filed here land unlabeled, so
/process-issues
picks them up and triages them. An issue that becomes
ready-for-agent
is implemented by
/implement-issues
, whose resulting PR flows back into this pass. Three single-purpose passes, each
/loop
-paced, none ever merging: triage, implement, finalize.
此处创建的衍生Issue无标签,因此
/process-issues
会识别并分类它们。变为
ready-for-agent
状态的Issue会由
/implement-issues
实现,其生成的PR会重新进入本次处理流程。三个单一用途的处理周期,均由
/loop
控制节奏,均不执行合并:分类、实现、终处理。