Responding to review across a stacked PR chain

Review comments may target several PRs in a dependent stack (A ← B ← C …). Keep that chain linked through GitHub's official stacked-PR feature. This guide owns review-fix placement and propagation; the dsh-merging-stacked-prs skill owns linkage checks and landing.

Ground rules

  1. One worktree per PR branch. Each PR's fixes happen in that PR's own worktree; parallel fixes never share a checkout.
  2. GitHub's stack object is authoritative. Base branches establish the expected dependency order, while PullRequest.stack and stackEntry.position prove that GitHub recognizes it. Do not treat a matching branch chain as an official stack without checking those fields.
  3. A fix lands on the PR that INTRODUCED the issue, then flows up-stack. When a comment on PR B points at code B introduced, fix it on B and propagate B into C — even if C also carries the file. Originating the fix downstream leaves B shipping the unfixed code and hides the fix from B's reviewer.
  4. Each review fix remains a distinct commit. A later rebase may change its OID, but do not amend a reviewed fix out of the branch history. Amend only your own not-yet-pushed, not-yet-reviewed work.
  5. Choose merge-forward or rebase deliberately. Both histories are allowed after review. A rewritten push must be lease-protected and must abort rather than overwrite a concurrently advanced remote head; raw --force is forbidden.

Resolve comments through the stack

  1. Triage every comment on the merits before acting: verify the claim against the code — a reviewer flagging the right symptom can still misdiagnose the cause.
  2. Map each accepted finding to its originating PR and fix it there.
  3. Propagate the fixed layer through every affected child in order:
    • Merge-forward: merge the fixed parent branch into its child, validate the child, and continue upward. Preserve each in-progress checkpoint under the incremental-retargeting decision.
    • Native cascading rebase: use gh stack rebase, validate the rewritten layers, then publish with gh stack push; or use gh stack sync, which may publish first and therefore requires immediate post-sync validation under dsh-pre-push-checks.
  4. Treat delegated fixes as trust-but-verify: a sub-agent's report describes intent, not necessarily what landed. Re-run the gates yourself on the actual tree, and for a regression guard, prove it FAILS on the unfixed code (introduce the regression, watch red, revert) — a guard that passes both ways guards nothing. A sub-agent that reframes a problem as already handled is a signal to dig in personally.
  5. Reply in the review thread (gh api repos/{owner}/{repo}/pulls/{pr}/comments/{id}/replies), not as a top-level comment, stating the fix and the current commit or head that carries it.
  6. After any rewritten push, re-read unresolved threads, approvals, mergeability, and checks. A force-pushed commit OID or outdated inline anchor is not current evidence that the finding remains resolved.
  7. Land only through the official stack procedure. If the PRs are not yet linked, the landing skill automatically links a same-author chain, asks before linking mixed authors, and hard-stops when native stack support is unavailable.

Verify

  • Every fixed PR's current diff contains the intended correction at the layer that introduced the issue.
  • GraphQL reports one official stack in the expected order, and each child diff against its parent shows only that child's changes.
  • Unresolved threads, approvals, mergeability, and checks were re-audited after every rewritten push.
  • The relevant gates pass on every affected PR in the stack, not just the top.

在堆叠 PR 链中回应评审意见

评审意见可能同时针对一条依赖堆叠(A ← B ← C …)中的多个 PR(Pull Request)。请通过 GitHub 官方的堆叠 PR 功能保持这条链的关联。本指南负责评审修复的归属与传播;dsh-merging-stacked-prs skill(技能)负责检查关联关系和落地。

基本规则

  1. 每个 PR 分支一个 worktree。 每个 PR 的修复在该 PR 自己的 worktree 中进行;并行修复绝不共享同一个 checkout。
  2. GitHub 的 stack 对象是权威依据。 base 分支确定预期的依赖顺序,PullRequest.stackstackEntry.position 则证明 GitHub 已识别该堆叠。未经检查这些字段,不得仅凭分支链吻合就将其视为官方堆叠。
  3. 修复落在引入问题的那个 PR 上,然后沿堆叠向上流动。 当 PR B 上的评论指向 B 引入的代码时,在 B 上修复,再将 B 的变更传播到 C,即使 C 也包含该文件。把修复发起在下游会导致 B 带着未修复的代码交付,并对 B 的评审者隐藏修复。
  4. 每项评审修复都保留为独立 commit。 后续 rebase 可能改变其 OID,但不得通过 amend 把已经评审的修复从分支历史中抹去。只有你自己尚未推送且尚未评审的工作才可以 amend。
  5. 明确选择 merge-forward 或 rebase。 评审后允许采用这两种历史更新方式。改写历史的推送必须受 lease 保护;如果远端 head 在此期间前移,操作必须中止,不得将其覆盖。禁止直接使用 --force

沿堆叠解决评审意见

  1. 在行动之前先就事论事地审视每条评论:对照代码验证其论断——评审者指出了正确的症状,但仍可能误诊原因。
  2. 将每个被接受的发现映射到引入该问题的 PR,并在那里修复。
  3. 将修复后的层按顺序传播到每个受影响的子 PR:
    • Merge-forward: 将修复后的父分支合并到其子分支,验证子分支,然后继续沿堆叠向上传播。依照增量更新 base 的决策,保留每个正在处理的检查点。
    • 原生级联 rebase: 使用 gh stack rebase,验证所有已改写的层,然后通过 gh stack push 发布;也可以使用 gh stack sync,该命令可能先发布,因此必须按照 dsh-pre-push-checks 在同步后立即验证。
  4. 委派的修复需要信任但验证:subagent 的报告描述的是意图,不一定是实际落地的内容。请亲自在实际代码树上重新运行门禁;对于回归守卫,要证明它在未修复的代码上失败(引入回归、观察变红、再还原)——两种情况都通过的守卫什么也守不住。subagent 将问题重新定性为「已处理」时,这是一个需要亲自深入的信号。
  5. 在评审线程中回复(gh api repos/{owner}/{repo}/pulls/{pr}/comments/{id}/replies),而非发顶层评论;说明修复内容及当前承载修复的 commit 或 head。
  6. 每次改写推送后,都要重新读取未解决线程、批准状态、可合并性和检查结果。经 force-push 改写的 commit OID 或已过时的内联锚点,都不足以证明该发现当前仍处于已解决状态。
  7. 仅可通过官方堆叠流程落地。如果这些 PR 尚未关联,落地 skill 会自动关联作者相同的链;如果作者不同,则先询问用户;如果原生堆叠支持不可用,则硬性停止流程。

验证

  • 每个已修复 PR 的当前 diff 都在引入问题的那一层包含预期修正。
  • GraphQL 报告的官方堆叠只有一个且顺序符合预期;每个子 PR 相对于父 PR 的 diff 只显示该子 PR 自身的变更。
  • 每次改写推送后,均重新审计了未解决线程、批准状态、可合并性和检查结果。
  • 相关门禁在堆叠中的每个受影响 PR 上都通过,而不仅仅是顶部。