通过拉取请求将分支合并到 master 上。/commit 是个人直接通往 master 的路径;而这条路径适用于 Claude Code 会话处理分支上的任务卡片,CLAUDE.md 将其分配给机器人和代理(代理工作规则;ADR 0004)。拉取请求由 docs/how-to/ask-the-agent.md 中的循环进行审查,该页面从问题的角度描述了这个循环。此技能是作者端的内容:要运行什么、等待什么,以及在每个停滞点需要做的一件事。循环自动完成的所有事情都留给它自己处理;在错误时机的人为干预正是此技能要防止的。
参数是:$ARGUMENTS。卡片编号会打开拉取请求(第 1 节)并监控它(第 2 节)。watch <number> 监控一个已打开的拉取请求。空参数:在分支上有提交领先于 origin/master 且没有拉取请求时,打开一个;有打开的拉取请求时,监控它;在 master 上时,停止并说明 /commit 是从 master 出发的路径。
仅合并。绝不使用 rebase,绝不使用 --force。如果冲突出现在下面命名的追加文件之外,则停止并将问题交回。
1. 打开拉取请求
-
读取状态。
git fetch --quiet origin,然后git status(绝不使用-uall)、git log --oneline origin/master..HEAD、git diff和git diff --cached。分支名称为<card>-<slug>;如果更改位于master上,则首先使用git switch -c <card>-<slug>将其移动到新分支。像/commit一样检查差异是否符合 CLAUDE.md(每个提交一个 crate,文档在同一个提交中,数据平面更改的直方图,依赖项的理由,spec/的 ADR),并扫描每一行新增代码以查找密钥。如果差异大约超过一千行变更(排除生成和记录的文件),则不是一个拉取请求能处理的:按照docs/how-to/implement-a-feature.md步骤 3.8 中的说明,按 crate 和平面拆分,以便第一次审查的阻塞点能在一次修复运行中解决,并在当前拉取请求合并后从各自的分支打开其余部分。 -
运行门控,每条命令单独运行。 在下一个命令之前读取每个退出码:
just lint; echo "lint exit $?" just test; echo "test exit $?" just docs; echo "docs exit $?" just lint-docs; echo "lint-docs exit $?"绝不要通过管道或管道后面的
&&链接门控:just lint 2>&1 | tail -1 && git commit会报告tail的退出码,导致失败的门控被忽略。2026 年 10 月 26 日,有两个提交因此进入了拉取请求 57 的分支,一个未通过just lint,另一个未构建成功,每个都浪费了一个审查周期。非零退出码会停止执行序列;修复后,重新开始此步骤。笔记本的门控仅编译笔记本的平台。如果更改添加或修改了
cfg(target_os = "linux")块或它的not对等块,则在推送前需要针对 Linux 进行类型检查,因为 Linux 门控和两个基准测试主机都会构建它:cargo check --workspace --all-targets --target x86_64-unknown-linux-gnu; echo "check exit $?"一次性
rustup target add x86_64-unknown-linux-gnu即可安装目标;检查不需要链接器。2026 年 11 月 1 日,拉取请求 94 的第一次审查中,CI 在一个文件上报告了三个 Linux 错误,而所有 macOS 门控都已通过。 如果cfg(target_os)阶梯有两个以上的分支,则需要在第三个目标上进行检查,即--target x86_64-unknown-freebsd(一次性rustup target add后):在 CI 运行的两个目标上,只有一个分支是活跃的,因此第三个分支在那里是死代码,或者与其他分支重叠的分支,只会在其他平台上暴露。2026 年 11 月 1 日,拉取请求 95 的第二次审查中,有两个常量在每个目标上都定义了两次,除了 Linux 和 macOS。 -
提交。 消息是审查记录,如同
/commit所写的那样:主题<card>: <祈使句主语>(不超过 72 个字符);正文包含更改内容、涉及的不可变规则编号以及证据(门控结果、ADR 编号、数据平面 crate 下更改的两个直方图、just conformance和just replay-check的结果,当更改声称正确时)。分支上有多个提交是可以的;压缩合并会将拉取请求的标题和正文作为master上的提交(auto-merge.yml),因此分支上的消息只是该提交的草稿。 -
合并
master。git merge --no-edit origin/master。如果冲突出现在每个人都会追加的文件(CHANGELOG.md、docs/SUMMARY.md、docs/glossary.md、spec/README.md、counters.toml、crate 的lib.rs)中,则通过保留双方内容并让master的行排在前面来解决(CLAUDE.md,代理工作规则);任何其他冲突则交回处理。合并提交后,再次运行步骤 2。 -
检查 CI 将要检查的内容。 CI 的
lint-docs针对origin/master...HEAD(整个分支)运行,而笔记本只检查工作树或最后一个提交(scripts/lint-docs.py,头部)。在推送前运行 CI 的范围:LINT_DOCS_RANGE=origin/master...HEAD just lint-docs; echo "lint-docs exit $?"这也是为什么在一个分支的一个提交中接受、在后续提交中编辑的 ADR,会通过 CI 但笔记本的
HEAD~1..HEAD检查却会失败,提示“在 HEAD 处接受并已更改”:在分支的范围内,ADR 是新的。请信任 CI 运行的范围。 -
推送并打开。
git push -u origin <branch>。将正文写入文件,绝不要内联写入:它是master上的提交消息,因此是完整的审查记录,根据分支的提交消息构建,就像循环的open-pr作业根据代理的提交消息构建一样:更改内容、涉及的不可变规则编号、证据以及 CI 未检查的内容(数据平面更改的主机基准测试数据、解析器更改后的just fuzz结果)。当存在相关问题时,以Closes #<issue>结尾。然后:gh pr create --title "<card>: <祈使句主语>" --body-file <file> --label auto-merge在创建时添加
auto-merge:审查者对当前 head 的批准随后会启动一个压缩合并,在所需检查通过时自动完成,无需任何人介入(auto-merge.yml)。仅当用户要求先阅读拉取请求时才不添加该标签。 -
确认审查已开始。 在一分钟内,
gh run list --workflow "dispatch review" --limit 3会显示一个以拉取请求命名的pull_request_target运行,一分钟后gh run list --workflow "review pr" --limit 3会显示review pr <number>, attempt 1。审查者在master上运行(ADR 0005),因此它位于 Actions 选项卡中,而不是拉取请求的检查列表中。两分钟后仍未出现:gh pr edit <number> --add-label review并再次检查。
2. 监控拉取请求
一次性读取状态,然后等待。一次推送后,审查大约需要十分钟;修复运行最多需要三十分钟;bench (linux) 和 bench (grip) 作业各自拥有自己的主机 bench 和 grip。轮询频率不超过每五分钟一次,并且不要触及以下规则未提及的任何内容。每次等待都是循环自身正在进行的工作;停滞点由规则说明。
gh pr view <number> --json state,mergeable,headRefOid,labels,reviewDecision
gh api repos/{owner}/{repo}/pulls/<number>/reviews --jq '.[] | "\(.submitted_at) \(.state) \(.commit_id[0:7]) \(.user.login)"'
gh run list --workflow claude --limit 5
gh run list --workflow "dispatch review" --limit 5
gh run list --workflow "review pr" --limit 5
gh pr checks <number>
-
claude[bot]请求更改。claude运行(事件pull_request_review)在一分钟内启动并应用分支上的阻塞点。在其运行或等待期间,不要推送任何内容:每个周期只能有一个写入者。它的运行在每个拉取请求的队列中一次处理一个,并且 GitHub 每个队列保留一个待处理运行,因此你现在的推送会获得自己的审查,并且该审查启动的修复运行会取消已在等待的那个;在拉取请求 57 中,两次审查因此丢失了它们的修复运行,而实际执行工作的运行响应的是两个 head 之前的审查。修复者会在每个阻塞点通过测试后提交,并在过程中推送,因此在一个运行期间 head 可能会移动多次;审查是针对它离开时的 head。当运行完成时,它的最后一个作业会取消 GitHub 在修复者最后一次推送之前的 head 上保留的ci运行(claude.yml,“取消修复者遗留的 head 上保留的运行”:如果分支在合并时被删除,保留的运行如果单独留下会以失败告终并发送邮件;auto merge运行会在合并前清理这些保留的运行),批准最后一次推送上的ci运行,如果 head 还没有dispatch review运行,或者修复仅是对拉取请求正文的编辑(claude.yml,“请求审查代理的推送”),则添加review标签,以便在运行结束一分钟后出现dispatch review运行。仅当一分钟过去且仍未出现时,才自行添加review。 -
“自主修复上限已达到”。 第四次请求更改的审查会结束修复者的部分(
claude.yml,MAX_ATTEMPTS: 3)。现在轮到作者处理拉取请求:修复、步骤 2、步骤 4、推送。人的推送会触发其自己的dispatch review运行。 -
修复者无法应用的阻塞点。 修复者的运行拒绝写入
.github/workflows/**、.claude/**、spec/**和bench/baseline.json(claude.yml,settings.deny),因此如果审查的所有阻塞点都在这些文件中,其运行会以“修复会话在没有推送的情况下结束……并且未对拉取请求正文进行更改”而结束。这些从第一次审查开始就需要作者处理:应用更改,推送。仅涉及拉取请求正文的阻塞点,修复者会自行使用gh pr edit应用,并且其运行会请求审查未更改的 head(问题 11);当你自己编辑正文时,使用gh pr edit <number> --body-file <file>,然后使用gh pr edit <number> --add-label review,因为对正文的编辑不会触发新的审查。 -
一个 head 十五分钟后仍无审查。
gh run list --workflow "review pr":一个审查者会话未得出裁决的运行会由循环本身重试为attempt 2;失败的attempt 2是第二次错过,gh pr edit <number> --add-label review会启动第三次。在你推送后,如果 head 根本没有dispatch review运行,则使用相同的标签。 -
CONFLICTING。 分支下的master发生了移动;GitHub 不会对有冲突的拉取请求启动任何运行。执行步骤 4、步骤 2、推送。 -
红色检查。
gh run view <run id> --log-failed。bench (linux)在主机bench上运行,bench (grip)在grip上运行:绝不要在作业可能正在运行时(gh run list显示为in_progress或queued;主机上的pgrep -a cavalry-bench)在任一主机上运行基准测试,并且那里的门控失败应在更改任何内容之前从bench-compare自身的日志行中读取。 -
已批准。
auto-merge.yml在批准时启动合并,但要求批准的commit_id是当前 head;对旧 head 的批准不会启动任何操作,较新的 head 会获得自己的审查。合并会在所需检查通过时完成:gh pr checks <number> --required。批准后发生移动的分支会被 GitHub 拒绝,auto merge运行会说明原因:如果 GitHub 为新 tip 启动了运行,则发送通知且运行显示绿色(循环会自行审查);如果一分钟后未启动任何运行,且拉取请求对象仍指向已批准的提交,则标记为失败,此时只有推送才能继续:步骤 4、步骤 2、推送(auto-merge.yml的头部;2026 年 11 月 4 日的拉取请求 106)。 -
已合并。
git fetch --quiet origin和git log --oneline -1 origin/master显示包含拉取请求标题的压缩提交;gh run list --branch master --workflow ci --limit 1是其 CI 运行,并且拉取请求的完成需要等待该运行变为绿色。然后在卡片上评论提交哈希并归档它,然后运行just tidy:它会在本地清理分支及其工作树,而 GitHub 已在远程删除该分支。
3. 报告
提供拉取请求编号和 URL;每次审查的裁决,谁响应的以及使用了哪个推送;master 上的压缩提交及其 CI 运行;以及 just tidy 已执行。如果应用了上述规则,请说明是哪条以及原因。如果拉取请求正在等待修复运行或审查,请说明并告知下一个要检查的内容;不要添加标签来催促进程。