关于 stack-pull-requests
指导开发团队如何把实现工作组织为独立 PR 或堆叠 PR 的技能,适用于需要规划审查与集成顺序的代码变更。它先区分故事、实现切片和 PR 边界,再依据依赖、审查收益及级联成本决定是否堆叠。
主要功能
- 01区分故事、实现切片与 PR 边界
- 02比较独立 PR 与堆叠 PR
- 03评估硬依赖和流式依赖
- 04按边界安排测试与验证
- 05追踪堆叠分支级联与合并风险
适用场景
- 01将有依赖的实现切片组织成 PR 堆栈
- 02判断并行开发是否值得采用流式堆叠
- 03拆分过大的单个切片以便审查
- 04为每层 PR 明确验证证据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ citypaul/ .dotfiles --skill stack-pull-requests安装后在 Claude Code 中输入/stack-pull-requests确认已加载。
附带文件agents/openai.yamlreferences/source-notes.md
详细介绍
堆叠式拉取请求
将堆叠式拉取请求用作可选的分支、审查和集成拓扑,而不是垂直拆分用户故事的替代方案。
默认将每个垂直实现切片作为一个针对主干的 PR。只有在有序分支能实质性提升审查质量,或能让工作在下层审查合并前继续沿用同一不断演进的基线,同时又不削弱测试、可部署性或可理解性时,才使用堆叠。
GitHub 原生堆叠式 PR 支持和官方 gh-stack 扩展目前仅限预览,仓库可能尚未启用。若需要确认 GitHub 的具体行为、命令来源或这些规则背后的理由,请加载 references/source-notes.md。依赖预览专属命令前,请核实当前官方文档、仓库访问权限以及 gh stack --help。
区分三个单位
| 单位 | 问题 | 负责人 | 规则 |
|---|---|---|---|
| 待办用户故事 | 哪项范围明确的能力能够带来价值或学习成果? | story-splitting | 保持垂直拆分,并在交付规划前确定其验收范围 |
| 实现切片 | 哪个最小垂直增量能够推进该用户故事,并留下已知良好的状态? | planning | 声明的前置条件满足后,安全地合并并发布;默认使用一个 PR |
| PR 边界 | 应如何打包已规划的实现工作以供审查? | 本技能 | 通常包含一个完整切片;也可以是一个切片中的依赖层 |
顺序描述工作次序;堆叠描述分支依赖关系。堆叠中的下层 PR 可以独立合并,而每个上层 PR 都以其下方的分支为目标。因此,多个垂直切片并不自动意味着它们是相互独立的 PR,也不自动意味着它们应当堆叠。
如果每个切片都可以针对主干,并且能以任意安全顺序合并而不会阻塞或重复工作,或者下一个分支只会在其前置分支合并后才开始,请使用独立 PR。出现以下任一情况时,可跨切片堆叠:硬性沿袭(上层切片依赖下层切片),或流动沿袭(切片仍分别完整,但上层工作在下层审查和合并前就已基于同一不断演进的基线启动,且可以接受固定的先合并下层顺序)。如果一个固定切片过大,无法通过一次有效审查,请在切片内部堆叠。
回退是堆叠的实际优势:下层分支上的修正会保留在所属 PR 中,堆叠工具会将其向上传递。这并非免费的保险。每个发生变更的上层分支都必须重新变基、推送并重新检查,也可能产生冲突或导致旧批准失效。若依赖中的上层工作已在进行,且下层边界很可能需要迭代,则应将其视为一种优势;不要仅仅因为早前的决策将来或许会改变,就人为制造分支依赖。
切片内部的 PR 层既不是子用户故事,也不是实现切片,不得扩大验收范围。跨切片堆叠中的成员可以负责一个完整的已规划切片及其验收标准;不得在已批准的切片之外擅自增加范围。
按以下顺序操作:
- 如果请求仍包含多个客户成果、路径、角色或质量级别,请加载
story-splitting。 - 选择一个垂直子用户故事。
- 加载
planning,定义其垂直实现切片、依赖关系、类别、证据和终结义务。 - 当一个切片需要分层审查,或一组连续的硬性沿袭或流动沿袭切片需要同时推进时,使用本技能。
- 如果没有审查、提前交付或修正路由方面的收益足以抵消固定顺序和级联成本,请将切片保留为彼此独立、基于主干的 PR。
- 如果验收标准、发布约束或中间状态的安全性仍不明确,请使用
find-gaps。
不要将 database → API → UI → tests 拆成待办用户故事。如果这些边界有助于审查选定的某个实现切片,请将它们描述为相互依赖的 PR 层,并明确说明其发布状态。
决定:使用独立 PR 还是堆叠 PR
仅当以下条件全部满足时,才选择堆叠 PR:
- 范围仅限于一个固定切片,或一组连续且有意按顺序排列、已规划好的垂直切片或缩减过渡。
- 至少有一项具体收益:组合变更需要聚焦的差异,或后续有序工作应在较低层 PR 完成评审和合并之前推进。
- 分支具有有意设计的单向沿袭关系:存在硬依赖,或存在刻意安排的流转沿袭关系,即上层工作确实在下层合并前基于同一不断演进的基线启动,并且可以接受固定的自下而上合并顺序。
- 每个 PR 都应在可行的情况下负责一个完整切片,或一个连贯的切片内层;只要结合自身差异和下层各层内容,就能理解该 PR。
- 每个 PR 边界都能让其累积分支保持已知良好状态:可构建、已验证,并且可以安全部署或明确处于休眠状态。
- 如果所有上层工作都被放弃,每个下层切片仍然有用且可以安全合并。
- 预期的级联/变基成本低于聚焦评审、缩短前置时间以及明确修正责任所带来的收益。
- 仓库和团队能够支持依赖分支、级联变基,以及原生的前缀/分组合并或手动自下而上合并。
- 预期采用的堆叠机制能够为每个 PR 应用所需的 CI 和仓库规则。
出现以下任一情况时,优先选择独立的基于主干的 PR:
- 整个变更本身已经是一次快速且连贯的评审。
- 拆分后的 PR 可以针对主干,并且能够独立合并、调整顺序或放弃,不会阻塞其他工作或造成重复。
- 后续依赖切片可以等到前置条件合并后再开始,而不会阻塞有用的工作或反馈。
- 拆分会将测试或证据与其要保护的行为或契约分开。
- 评审者必须理解整个堆叠才能判断每一层。
- 中间合并会暴露不安全的架构、契约、桥接层或半成品功能。
- 变更涉及的范围过广,以致每一层都会反复修改同一段代码。
- 唯一建议的边界是文件、架构层级、工作阶段或团队归属。
- 唯一建议的收益只是早期决策发生变化时可能带来的便利。
- 变基和 CI 反复运行的成本高于小差异所节省的成本。
进行两种反事实检验
- **主干反事实:**每个拟议 PR 都能否从当前主干开始,并且无需纳入同级 PR,就能合并、调整顺序或放弃?如果不能,并且其他门槛均满足,则使用硬沿袭堆叠。
- **流转反事实:**如果可以,那么上层工作是否会在下层 PR 合并前,确实沿着同一条演进路径启动?能否接受固定的自下而上合并顺序?节省的等待时间或由下层负责的修正转交,是否足以抵消重新堆叠和重新评审的成本?如果是,则流转沿袭堆叠有效。否则使用独立 PR。
不要习惯性地使用堆叠 PR。用一句话记录决定:
Delivery: single PR — the end-to-end change is already one focused review.
或:
Delivery: 3-PR stack — the dormant migration, tested repository adapter, and
fixed sign-in slice form one-way dependencies with meaningful verification.
或:
Delivery: 3-PR flow-lineage stack — each vertical slice is known-good in order,
upper work starts now on the same evolving path, and lower-first landing is acceptable.
编写代码前设计堆叠方案
1. 确定故事和堆叠范围
写明所选故事中的参与者和结果,然后记录:
- 堆叠是在一个切片内,还是横跨一组连续切片
- 纳入的每个切片、其触发条件、可观察结果或守恒契约、生产路径、验收证据、类别和发布约束
- 堆叠覆盖的已批准范围并集,且该范围固定不变
如果故事仍描述多个客户功能,请返回 story-splitting。在 planning 中,将每个垂直结果或缩减过渡保留为独立切片,即使多个切片共用一个堆叠也不例外。对于跨切片堆叠,每个 PR 都可以按依赖顺序添加各自已批准的验收用例。对于切片内堆叠,在划分 PR 层之前,先冻结所选切片的范围。
对于缩减工作,堆叠成员关系不能替代台账或门槛。如果已被取代的机制仍然存在,或新增了桥接层,那么某个过渡就不能宣称实现了净缩减;只有终端缩减切片才能满足机制门槛并声明固定的终端状态。
2. 绘制谱系图
识别硬依赖和有意设计的流程谱系。将两者与习惯性的构建顺序区分开来。“我们通常先构建后端”并非证据;“在审查仍进行时,下一个获批切片从当前演进中的基线开始”则可以作为证据。
优先按以下顺序划定边界:
- 完整的纵向切片 — 每个 PR 负责一个已获批且已知良好的切片;上层工作与下层工作存在硬依赖或有意设计的流程谱系,并与下层审查并行进行。
- 可测试的路径增量 — 每个 PR 都推进同一个固定切片,不添加属于其他切片的验收用例。
- 保持行为的准备工作 — 进行聚焦的重构或安全特征化,以便后续变更可供审查。
- 向后兼容的启用工作 — 进行迁移、契约或基础设施变更,并确保其经过验证、处于休眠状态,且由下一个 PR 直接使用。
- 风险隔离 — 对值得专家集中审查的安全、数据或性能敏感变更进行隔离。
- 审查者的专业知识 — 只有当 PR 无需长篇解释技术栈其他部分也说得通时,才按子系统划定边界。
避免:
- 将所有测试都放在最上层 PR 中
- 臆测性的基础工作或抽象
- 唯一依据是“文件在同一个文件夹里”的边界
- 下层边界必须依赖上层边界才能编译、安全迁移、通过 CI,或履行尚未分配责任人的桥接工作
- 在上层边界中重复修复,而不是修复所属的下层边界
- 级联和审查开销占主导的长链 PR
边界数量或行数没有通用限制。只保留最精简的 PR 链,确保每个 PR 都能快速审阅且只涉及一个概念。如果相邻的两个边界需要相同的说明或证据,就将它们合并。
3. 按边界类型安排验证
GitHub 的教程将测试作为最后一层;不要把这种顺序照搬到此工作流中。
对于会改变行为的生产边界:
- 在更改代码前加载
tdd、testing和适用的refactoring指南。 - 对该边界负责的行为,遵循快速的 RED-GREEN-REFACTOR 增量流程。
- 在最早负责该行为的边界中加入契约、迁移、单元、集成或 UI 测试。
- 边界达到 PR 就绪状态后,加载
mutation-testing,在适用情况下针对其父级运行一次累积范围门禁;或者记录适度的替代证据N/A。
对于保持行为的生产边界:
- 加载适用的 testing 和
refactoring指南;如果保护不足,则加载finding-seams和characterisation-tests。 - 为受影响的使用方路径建立通过的行为保持证据。
- 在不改变行为的前提下进行重构,并确保适用的聚焦测试和受影响测试保持通过。
- PR 就绪时,运行同样的每个边界仅一次的变异测试或替代证据门禁;不要编造结构性变异体。
对于缩减过渡或最终缩减边界,还要保留所选切片的 reduce-system-complexity 台账、守恒契约、桥接工作的责任归属与移除义务,以及行为/机制门禁状态。
对于文档、发布元数据、配置或非生产性的机械变更,使用最小的可执行验证,确保边界错误时验证会失败;适用时记录变异测试 N/A。
对于每个 PR 边界,都要运行仓库要求的构建、lint、类型、安全和完整的非监视模式测试检查,并验证累积后的分支,因为上层 PR 包含所有下层边界。
最上层边界必须证明每个包含的切片都满足累积验收示例或最终门禁。它可以添加栈级测试,但某项行为的首次测试应放在引入该行为的 PR 中,而不是后续的栈成员中。
4. 堆叠 PR 前验证 CI 拓扑
创建任何 PR 前,记录这些 PR 将作为 GitHub 原生堆叠关联,还是仅构成未关联的依赖分支链。若目标是堆叠,且 GitHub 和仓库策略支持原生机制,则默认使用该机制;只有在用户或仓库明确选择未关联分支链,或原生支持不可用时,才使用未关联分支链。随后检查工作流、规则集、必需状态上下文和合并队列:
- 对于 GitHub 原生关联堆叠,GitHub 会针对堆叠主干评估 Actions、分支保护、必需检查、评审、CODEOWNERS 和代码扫描。筛选该主干的
pull_request工作流会对每个堆叠 PR 运行;不要仅因为上层 PR 直接以某个功能分支为目标,就要求修改工作流。 - 对于未关联的依赖 PR,或不具备等效堆叠元数据的工具,适用普通的直接基准语义。确认以功能分支为基准的 PR 会触发必需工作流,再依赖这些工作流。
- 确认每个需要检查的 PR 边界都会生成所有必需状态。
- 如果仓库使用合并队列,确认必需工作流能够处理
merge_group。 - 决定哪些聚焦检查在每个边界运行,哪些累积检查或端到端检查在顶部运行;不要为了方便堆叠而削弱必需的合并检查。
- 考虑变基触发的重新运行,以及现有的受影响测试或缓存行为。
无论采用哪种机制,都需要依赖分支和以功能分支为基准的 PR,但这并不能证明 GitHub 上存在远程堆叠对象。不要将未关联的分支链描述为 GitHub 原生堆叠。
如果所选堆叠机制无法在不进行有风险的 CI 修改的情况下,为每个边界提供可信的必需检查,则优先创建一个 PR。
5. 确保中间状态安全
每个较低层级的 PR 都必须满足以下一项:
- 可独立部署且有用
- 保持行为不变
- 向后兼容且默认不启用
- 隐藏在标志之后
- 是可独立验证的缩减过渡,具有责任明确、范围受限的桥接措施,且不提前宣称净缩减
- 明确规定只能作为连续获批组的一部分合并,并说明原因
绝不要合并会破坏调用方、需要当前不可用的架构、削弱安全性或暴露不完整行为的中间状态。向后兼容的扩展/收缩变更通常应放在不同的堆叠中,因为只有所有使用方都完成迁移后才能进行清理。
编写交付计划
对于切片内堆叠,在选定的实现切片下添加此部分。对于跨切片堆叠,在第一个包含的切片之前放置一张共享映射表,并在每个包含的切片中引用它:
#### Delivery Shape
**Mode**: Single PR | Stacked PRs
**Stack scope**: Intra-slice | Cross-slice
**Reason**: [Why this shape improves review without weakening delivery]
**Story scope**: [Fixed parent story; PR boundaries must not expand it]
**Included slices**: [One fixed slice, or the exact contiguous slice sequence]
**Done when**: [Acceptance criteria or terminal gates for all included slices]
| # | Ownership unit | PR boundary | Base | Owns | Depends on | Verification | Release state |
|---|---|---|---|---|---|---|---|
| 1 | [whole slice or intra-slice layer] | [focused title] | [repository default branch] | [one coherent change] | — | [tests/evidence/checks] | [deployable/dormant/etc.] |
| 2 | [whole slice or intra-slice layer] | [focused title] | [boundary 1 branch] | [one coherent change] | [specific contract or deliberate flow lineage] | [tests/evidence/checks] | [...] |
### Whole-stack gate
- [ ] Every included slice's acceptance examples, conserved contract, and applicable terminal gates pass cumulatively at the top
- [ ] Every PR boundary's focused and cumulative checks pass
- [ ] No behavior waits beyond its owning PR for its first test
- [ ] Every PR-ready boundary has current mutation or alternate evidence for its focused review scope
- [ ] Intermediate merge and release states are explicit and safe
- [ ] Reduction ledger, bridge, and mechanism-gate obligations remain accurate when applicable
- [ ] Native stack-trunk or unlinked immediate-base CI semantics are identified; required statuses and `merge_group` run where applicable
- [ ] When native stacking was selected, GitHub's remote stack object exists and its trunk and bottom-to-top entries match this plan; PR base refs alone are not proof
- [ ] Review sequence is bottom-up for lineage-sensitive boundaries; independent specialist reviews may run in parallel
- [ ] Merge includes every required lower PR: native all-or-nothing prefix/group, or manual bottom-up order
对于每个 PR 边界,还要记录:
- 聚焦的评审问题
- 纳入和排除的范围
- 可能涉及的文件或子系统,但不要规定不必要的实现方式
- 所需的专业评审人员(如有)
- 该边界负责的行为、保留的契约或机械性变更的验收标准和验证路径
遵循仓库的分支命名约定。除非用户已授权,否则不要创建分支、提交、推送、提交 PR、变基共享分支或合并。
自底向上构建
对于每个 PR 边界:
- 从最顶层已提交且已知良好的分支开始。
- 编写代码前,先与用户确认该边界的验收标准或需保持不变的契约。
- 完成适用的实现路径,并确保范围内及受影响的检查通过。
- 当该边界已满足其他 PR 就绪条件时,完成其变更或替代证据关卡以及仓库检查。
- 对照父分支(而非 trunk)自行审查差异。
- 移除属于上层分支的工作。
- 展示聚焦的差异和验证证据。
- 只有在用户和仓库工作流授权后才提交。
- 只有当前边界已提交且已知良好后,才创建下一分支;扩展堆栈不需要审查批准。
仅当仓库有预览权限、扩展已安装或已获准安装,且符合仓库策略时,才优先使用官方 gh stack 命令。使用当前帮助信息,而不要依赖记忆中的语法。使用 gh stack submit 提交本地跟踪的原生堆栈。如果分支或 PR 是通过其他工具创建的,请使用当前文档所述的关联命令。否则,使用现有 Git/GitHub 工具管理明确未关联的依赖链。
在报告已创建原生堆栈或已满足 PR 就绪条件前,验证远程对象:PullRequest.stack 必须非空,且其 trunk 和有序条目必须与交付计划一致。PR 基础分支引用链正确并不足够。如果无法进行远程验证,请将这些 PR 报告为未经验证的依赖链,而非原生堆栈。
将尚未完成的上层边界作为草稿 PR 打开。为每个 PR 提供聚焦的标题和简洁说明,包含:
- 所选故事、包含的实现切片以及此 PR 的目的
- 已知时的父级/基础 PR 和下一边界
- 此差异中需要审查的内容
- 已执行的验证
- 发布状态
- 有意延后的事项
审查与修订
请求审查前,自行审查每个 PR 边界。检查功能、意图、代码质量、依赖项、AI 特有错误以及测试完整性。
如果后续边界强烈依赖较早边界的决策,则从底层向上请求审查。如果每个聚焦差异都易于理解,不同专家可以并行审查并批准各个边界。合并就绪状态和合并顺序仍须自底向上推进。
当反馈导致较低边界发生变化时:
- 切换到负责该变更的分支。
- 在该分支上修复并测试。
- 对其上方的每个分支执行 rebase 或 restack。
- 根据仓库策略重新评估现有变更或替代证据是否仍然有效,并按要求重新运行受影响的聚焦检查和累积检查。
- 重新审查上层差异,检查是否意外重复或出现语义偏移。
- 仅在有安全租约保护且获得授权的情况下推送。
不要在上层添加变通方案来掩盖下层缺陷。
将发现放在负责该内容的边界中:
- 如果发现修复的是较低切片承诺的行为或契约,请修复较低分支并重新整理堆栈。
- 如果发现增加的验收范围仅由上层切片负责,请将其保留在上层。
- 如果负责该内容的较低 PR 已合并,请采用聚焦的 trunk 基础修复;修复落地后,在继续之前同步或 rebase,并重新检查其余上层堆栈。
- 如果发现使计划中的边界失效,请调整堆栈和计划,而不要暗中将范围塞入下层。
证据发生变化时,调整堆栈。无法单独审查的相邻 PR 应合并;获得第二个概念的边界应拆分;只有依赖关系允许时才调整顺序。进行结构性变更的前提是工作树干净且存在可恢复的 rebase 路径。
合并并完成
合并前:
- 要求边界及其下方的每个边界都通过检查并获得所需审批
- 要求堆栈历史保持线性
- 验证顶部分支满足完整的声明堆栈范围和累计验收标准或终结门槛
- 验证任何部分合并状态仍然安全
- 由于原生堆叠 PR 行为仍处于预览阶段,请依据 GitHub 当前指南解决文档冲突
对于 GitHub 原生关联堆栈,使用 gh stack merge 合并已获批准的前缀或整个堆栈;所选 PR 及其下方的所有 PR 会作为一个全有或全无的操作合并,除非合并队列将处理拆分为多个组。对于未关联的依赖链或其他工具,应从底部向上合并,并在较低层合并后重新堆叠。若某个上层 PR 的任一依赖尚未合并,切勿合并该 PR。
较低边界合并后,同步或变基剩余堆栈,重新运行受影响的检查,并确认每个 PR 仍只显示其预期的聚焦差异。跨切片堆栈中,所属 PR 合并后即标记该切片为已完成;切片内堆栈中,仅当顶部合并后才标记该切片为已完成。顶部合并后,整个堆栈即完成。然后遵循仓库计划负责人的关闭/归档/删除流程(见 planning);仅在正常授权范围内删除备用临时计划文件。
示例
在一个垂直切片内使用分层
选定的用户故事和固定的实现切片:
A registered customer can sign in with valid credentials and reach their account.
如果端到端差异已经便于评审,则使用一个 PR,包含存储、身份验证行为、入口点、响应和测试。
如果范围太大,可以采用负责任的堆栈:
- 添加向后兼容且默认不启用的凭据存储迁移,并验证迁移和回滚。
- 在现有边界后添加凭据仓库适配器,并配备契约测试。
- 通过真实入口点实现有效凭据路径,涵盖领域行为、存储、响应和可观测性,并配备行为测试。
用户故事和切片仍保持垂直,范围不得扩大。第 1 层和第 2 层是启用任务,不是用户故事或实现切片。只有在具体仓库约束使之更安全,且每一层仍满足此技能的门槛时,才使用单独的“所有端点”或“所有中间件”PR。切勿将所有测试都推迟到最后一个 PR。
堆叠多个垂直切片
计划也可以定义以下已批准的切片:
- 已注册的客户可以使用有效凭据登录。
- 凭据无效的客户会看到安全的拒绝提示。
- 多次无效尝试会暂时锁定账户。
将它们保留为三个实现切片。如果每个切片都可以面向主干,并以任意顺序合并,且不会阻塞或重复工作,则使用独立 PR。如果切片 2 和 3 依赖较低层的行为,或者它们在同一不断演进的基线上、较低层评审尚未合并时就开始开发,且固定按从低到高的顺序合并所带来的收益值得承担级联成本,则使用三 PR 跨切片堆栈。在较低切片中修复由较低层负责的反馈,并向上传递;新的上层切片范围则保留在堆栈上方。