关于 finish-branch
finish-branch 用于决定并执行分支工作完成后的处理方式。它通过验证和验收检查控制合并与 PR,并要求终结性操作先记录决定,同时安全处理分支和工作树。
主要功能
- 01验证、追踪与验收门槛
- 02检测环境和基准分支
- 03提供固定的分支处理选项
- 04终结操作前记录决定
- 05设有防护的合并、PR 与丢弃流程
- 06按来源检查清理工作树
适用场景
- 01决定实现完成后的处理方式
- 02检查未通过时阻止合并或 PR
- 03根据已批准的内容包创建 PR
- 04经明确确认后丢弃分支
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jayden-dang/ skills --skill finish-branch安装后在 Claude Code 中输入/finish-branch确认已加载。
详细介绍
完成分支
决定如何处理已完成的工作:通过验证设卡,检测环境,提供固定菜单,执行所选操作,并安全清理。跨越终点时,使用 record-decision 先记录再跨越。
1. 设卡:验证、追踪和验收
必需子技能:使用 verify,全新运行 docs/agents/project.md 中的每条验证命令(类型检查、lint、单元测试、端到端测试),并确认 trace 检查通过——分支不得在需求未追踪的情况下合并;release 也会执行同一关卡。如果找不到测试命令,请向用户询问,并建议使用 setup-repo。
如果分支包含尚未在运行中的系统中实际验证过的用户可见行为,在提供合并或 PR 选项之前,必需子技能:使用 acceptance-check——单元测试通过只能证明断言通过,不能证明功能正常。
失败时:显示失败项。只要任何验证、追踪或必需的验收检查失败:不得提供合并和 PR;仍应提供终止选项阻止和丢弃(针对未通过的证据生成决策记录)。仅有机械性失败,或暂停/延期,而没有明确的终止性阻止/丢弃操作 → 不生成决策记录。
**完成条件:**通过时可提供完整菜单;未通过时只提供阻止/丢弃(或用户已暂停)。
2. 检测环境
GIT_DIR=$(cd "$(git rev-parse --git-dir)" && pwd -P)
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" && pwd -P)
| 状态 | 含义 |
|---|---|
GIT_DIR == GIT_COMMON | 普通检出——无需清理 worktree |
| 不同,且有命名分支 | 关联的 worktree——适用来源校验清理 |
| 不同,且为分离的 HEAD | 外部管理的工作区——无合并选项,无需清理 |
确定基础分支——运行 git symbolic-ref --quiet --short refs/remotes/origin/HEAD(去掉开头的 origin/);如果失败,则依次尝试 git rev-parse --verify --quiet main || git rev-parse --verify --quiet master。如果仍不明确,请向用户确认。(git merge-base 返回提交 SHA,而不是分支名——此处不要使用它。)
3. 展示菜单
(关卡通过时)原样展示以下五个选项,不添加任何说明:
Implementation complete. What would you like to do?
1. Merge back to <base-branch> locally
2. Push and create a Pull Request
3. Keep the branch as-is (I'll handle it later)
4. Discard this work
5. Block: reject this work at this boundary (records a terminal block verdict)
Which option?
关卡未通过时,只展示选项 4 和 5(丢弃/阻止),重新编号,并说明检查通过前不提供合并和 PR 选项。
分离的 HEAD 且关卡通过时,删除选项 1(无法合并),展示剩余四个选项并重新编号。分离的 HEAD 且关卡未通过时,仍然只提供丢弃/阻止选项。
**完成条件:**用户已选择一个菜单选项。
4. 执行
4a. 工单和内容检查点(仅选项 1 和 2)
在 record-decision 运行之前,若选择选项 1(合并)或选项 2(PR):展示已解析的工单集合(prepare-change 的工单解析结果,即 [{ id, title, classification, linkage_syntax }] 列表),并询问是否需要创建或补充任何缺失的工单。即使未配置问题跟踪工具,也要提出此问题——检查点仍需询问。如果用户要求创建工单,请在此暂停跨越步骤,并请用户自行运行 /file-issues:提及它,但绝不调用它——/file-issues 由用户调用,而 finish-branch 由模型调用(ARCH-5)。
仅在选项 2(PR)时,还要展示从 .skills/pr-packages/<stable-id>/manifest.md、title.txt 和 body.md 读取的准确软件包内容——标题、基础分支、头部分支、正文、工单关联、提交、建议性提交映射、约定检查结果、验证结果——并且仅提供以下三种回复:批准、请求修改或取消。若用户请求修改:重新撰写受影响内容、重新验证、再次展示完整软件包,并要求用户重新明确批准——任何修改都不能沿用之前的批准;此循环持续到用户明确批准或取消。将已批准的 Content-digest: 作为内联决策证据传递给下文的 record-decision;绝不要引用 .skills/pr-packages/<stable-id>/ 路径作为其定位符。
此检查点会运行,并且(在选项 2 下)会到达审批环节,早于
record-decision 发布,且早于实际跨越边界——顺序始终是菜单选择 → 此检查点 → record-decision → git/gh 副作用,绝不可颠倒。
对于选项 1(合并)、2(PR)、4(丢弃)和 5(阻止)——在任何 git/gh 副作用发生之前——必需的子技能:使用 record-decision,并填写:
| 选项 | 判定 | 边界类型 |
|---|---|---|
| 1 合并 | merge | integration |
| 2 PR | pr | publication |
| 4 丢弃 | discard | disposal |
| 5 阻止 | block | 被阻止的跨越类型(如果原本打算合并,则为 integration;否则填写被阻止的路径) |
将层级/谓词事实和持久证据以内联文本形式传递。只有 record-decision 发布了通过验证的记录后,才能执行跨越。如果发布失败:不得执行跨越;报告该判定未落实。对于阻止操作,不会发生跨越副作用,但记录失败仍意味着问责工作流未完成——绝不可声称已记录阻止操作。
选项 1——本地合并。 先解析 <base-branch>:如果本次会话存在 PR 包,路径为
.skills/pr-packages/<stable-id>/manifest.md,则使用其中记录的 Base: 值——即 prepare-change 实际解析并据此编写提交和说明的分支——而不是步骤 2 的拓扑检测结果。只有在不存在 PR 包时(即本次会话未运行 prepare-change),才回退使用步骤 2 的检测结果。记录成功后:从主仓库根目录操作,绝不可在工作树内操作:
MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
cd "$MAIN_ROOT"
git checkout "<base-branch>" && git pull && git merge <feature-branch>
<base-branch> 必须加引号,因为它由人工提供(来自拓扑检测或 Default PR base: 配置值),而不是从差异中得出;git check-ref-format --branch 仍会接受分支名称中的 ;、$(…)、反引号和圆括号——不加引号的插值会让 shell 重新解析一个合法引用。理由与下方的提交命令相同;不得省略引号。
在合并结果上重新运行验证套件,且必须在移除任何工作树之前。只有验证通过后,才能清理工作树(步骤 5),然后运行 git branch -d <feature-branch>。
选项 2——推送 + PR。 记录成功后:
git push -u origin <feature-branch>。- 提交之前立即重新解析 base 和 head SHA,并严格按照
package-contract.md中的原样步骤重新计算Content-digest:,不得转述——可读性检查会先运行,并在管道执行前中止。(此代码块必须与package-contract.md中Content-digest:的步骤逐字节一致——漂移检查依赖两者计算出相同字节。)
test -r ".skills/pr-packages/<stable-id>/title.txt" || {
echo "Error: title.txt missing or unreadable at .skills/pr-packages/<stable-id>/title.txt" >&2
exit 1
}
test -r ".skills/pr-packages/<stable-id>/body.md" || {
echo "Error: body.md missing or unreadable at .skills/pr-packages/<stable-id>/body.md" >&2
exit 1
}
{ cat ".skills/pr-packages/<stable-id>/title.txt"; cat ".skills/pr-packages/<stable-id>/body.md"; } | git hash-object --stdin
- 不匹配分支。 如果解析出的任一 SHA 或重新计算的摘要与已批准的值不同,该不匹配就会使审批失效:不得提交——返回 4a 检查点,重新编写、重新验证、重新展示并重新审批,然后再试。由于
record-decision已针对现已失效的摘要发布记录,因此这次重新审批要求先使用重新审批后的值重新发布record-decision,之后才能重试提交,从而确保已发布的记录始终描述实际发生的跨越。 - 匹配分支。 只有在两个 SHA 和摘要仍然一致后,才能提交已批准的标题、base、head 和正文,不得重新编写;从
title.txt读取标题,而不是将其插入命令中:
gh pr create --base "<base>" --title "$(cat ".skills/pr-packages/<stable-id>/title.txt")" --body-file ".skills/pr-packages/<stable-id>/body.md"
Both <base> and the title are quoted here. The title is diff/commit 派生的被动数据——其中的 ", 反引号或 $(…) 会破坏引号或触发执行,因此它是通过 $(cat "…") 从 title.txt 读取,而不是直接插值。<base> 来自人工输入,而非 diff 派生,因此这种情况的可能性较低,但机制完全相同:git check-ref-format --branch 仍接受分支名中的 ;、$(…)、反引号和括号,因此不加引号的 <base> 会让 shell 重新解析一个合法引用。不要省略任何一处引号。
— 使用该包自身的 Base:,而不是重新计算。
- 保留工作树 — 用户需要它来根据评审反馈进行迭代。
团队打包: 当 docs/agents/project.md 中有 ## Team,且包含非空的成员名单或级别覆盖时,从该部分读取级别/打包方式——Solo:不要在 PR 正文中凭空编造评审者名单;Small/Multi:在 PR 正文中根据成员名单/所有权说明建议评审者。不要新增菜单项。缺少 Team → 使用功能推出前的默认设置。
选项 3 — 保留。 报告分支名和工作树路径。不做任何更改。不要调用 record-decision。
选项 4 — 丢弃。 成功记录后:准确列出将被永久删除的内容(分支、提交、工作树路径),并要求用户逐字输入 discard。任何其他内容——包括“yes”、“confirm”、“do it”——都不算确认。确认后:从主仓库根目录清理工作树(步骤 5),然后运行 git branch -D <feature-branch>。
选项 5 — 阻止。 成功记录后:报告终止阻止状态;不要合并、创建 PR 或丢弃。保留分支,除非用户另行要求。
完成条件: 已执行所选选项(或因发布失败而如实说明未执行),包括任何必需的 record-decision 发布。
5. 清理工作树(仅适用于选项 1 和 4)
- 只移除路径位于
.worktrees/或worktrees/下的工作树——此来源证明它是由这套技能创建的。任何其他工作树(包括由运行环境拥有的工作区)都不应由你移除;保留它,或使用平台自身的退出工作区机制。 - 绝不要在待移除的工作树内部执行移除操作——先
cd到主仓库根目录。 - 移除后,运行
git worktree prune清除过期元数据。
6. 完成闭环
6a. 规格状态
合并或创建 PR 后,提醒用户(或在任务完成时执行):必需
子技能:使用 sync-spec 更新该功能的 Status: 和追踪状态。
6b. 指明可选的人工技能(风险 = diff 路径)
首要词:风险 glob——将实际 diff 路径(而不是计划标签或任务数量)与
skills/review/allocate-attention/references/signals.md 中的默认 B1 集合匹配;如果 docs/agents/project.md 中存在 Risk globs,则在默认集合上扩展(绝不替换)。
操作方法——每次完成闭环时都执行(合并、PR、保留):
- 统计计划中的任务数(没有计划时统计提交数):
multi_task = (count > 1)。 - 列出分支相对于 base 的 diff 路径。
risk_hit = any path matches a risk glob。 - 如果更改重写了公共契约/持久化/身份验证边界(或用户/计划已说明这一点),则记录
architecture_affecting。 - 如果
multi_task OR risk_hit→ 指明/comprehend-change(由用户调用——绝不自动运行,也绝不软性阻止菜单操作)。 - 如果
multi_task OR risk_hit OR architecture_affecting→ 指明/explain-change(由用户调用——绝不自动运行,也绝不阻止合并/创建 PR)。 - 如果
.skills/implementation-notes.md中有偏差 → 提及该路径一次。
示例: 一个任务,diff 仅涉及 skills/auth/session.ts → risk_hit 为 true →
指明两项。保留仍须执行步骤 4–5(仅指明技能;不合并/创建 PR)。
“可选”意味着用户可以跳过运行该技能——但你仍须指明它。
完成条件: 已执行步骤 1–6;满足条件时,闭环总结中应出现相应技能名称。
红线
绝不要:
- 在任何验证命令失败时提出合并或 PR
- 在合并结果通过测试之前移除工作树
- 对于丢弃确认,接受
discard以外的任何输入 - 移除
.worktrees//worktrees/之外的工作树,或从工作树内部移除工作树 - 擅自强推——只有用户明确要求时才会强推,绝不能把它当作你提出的修复方案
- 在
record-decision成功发布之前执行合并/PR/丢弃 - 仅因选择保留、暂停/延期,或发生机械性故障就生成决策记录
- 因分支只涉及单项任务、单个文件、仅选择保留,或负责人说“别走形式”,就省略
/comprehend-change或/explain-change名称,只要差异仍命中风险 glob - 因未配置跟踪器,就跳过选项 1 或 2 中关于缺少工单的问题
- 自己运行
/file-issues,而不是提及它并暂停等待用户 - 在获批后重新编写 PR 标题或正文,却不返回 4a 检查点重新确认
- 跳过提交前的 SHA/摘要复查,或在复查发现不匹配后仍然提交
- 发现不匹配后,使用过期记录重试提交,而不是先发布新的
record-decision - 将
.skills/pr-packages/<stable-id>/路径作为决策证据引用,而不是直接引用摘要
| 想法 | 实际情况 |
|---|---|
| “一小时前测试通过了,跳过检查吧” | 证据已过期。基于过期的通过结果合并,就意味着未经验证。 |
| “用户显然想要 PR,跳过选项菜单吧” | 决定权在用户手中。通过时有五个选项;失败时仍可阻止/丢弃。 |
| “先清理,再合并——更整洁” | 工作树被移除后合并失败,工作就会丢失。先合并、验证,再清理。 |
| “跳过记录吧;合并才是正事” | 先记录,再跨越:没有已发布的记录,就不能合并/PR/丢弃。 |
| “资深同事说别写文书——直接合并” | 权限高不代表可以豁免检查;要么发布记录,要么不执行跨越操作。 |
| “现在合并,明天再记录” | 延后记录仍属于未记录的跨越——同样是红线。 |
| “单项任务/单个文件——跳过可选技能名称” | 风险取决于差异路径,而不是任务数量。鉴权(或任何风险 glob)仍要求同时提及两者 |
| “负责人说别走形式” | 权限高不代表可以豁免检查。提及它们;人类可以选择忽略 |
| “没配置跟踪器,所以跳过工单问题” | 无论如何都要提问;跟踪器未配置是正常状态,不是跳过的理由 |
| “用户显然想要提交工单,直接运行 /file-issues 吧” | /file-issues 必须由用户调用;提及它并暂停,绝不要自行调用(ARCH-5) |
| “只对正文做了一处小修改,不需要重新确认” | 任何修改都会重新编写内容;必须重新展示并再次征求批准 |
| “撰写时摘要匹配了,提交时不用复查” | 每次都要在提交前立即重新解析 SHA 并重新计算摘要 |
| “旧记录仍然有效,直接用它重试提交吧” | 它描述的是从未执行过跨越操作的值;重试前先发布一份包含重新批准值的新记录——旧记录原样保留,没有任何标记说明它已被取代 |
| “引用 .skills/ 路径没问题,证据就在那里” | 存储位置不是可引用的定位信息;应直接附上摘要 |
| “风险提示只适用于多项任务计划” | 错。多项任务、风险 glob 或影响架构,任一条件成立即可 |
| “选择保留就不需要审查提示” | 选择保留仍需提及可选的自检/说明工具;它只会跳过合并/PR |