Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions skills/opening-a-pull-request/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Which keyword belongs depends on **which branch the PR targets**:

- **PR targets `main` (the default branch)** — use `Fixes` / `Closes` if the merge should close the issue; use `Towards` if the issue should stay open. This includes sub-PRs in the `sub_pr_target: main` model (see `feature-dev-workflow:fanning-out-with-worktrees`): each sub-PR targets main directly with the type-appropriate closing keyword (`Fixes #<sub-issue>` for a bug sub-issue, `Closes #<sub-issue>` otherwise); the epic is closed manually by the orchestrator after all sub-PRs merge.
- **PR targets a feature branch** (`feature/<slug>` in the multi-PR feature-branch model — see `feature-dev-workflow:developing-a-feature`) — use `Towards #<sub-issue>`. `Fixes` / `Closes` keywords only auto-trigger on merges to the default branch, so writing them on a feature-branch-bound PR creates a misleading promise that nothing will fulfill. The sub-issue is closed manually by the orchestrator after the self-merge. The integration PR (feature → main) gets `Closes #<epic>` because that PR does merge to main.
- **PR temporarily targets a sibling branch and will be retargeted to `main`** (stacked sub-PRs in the `sub_pr_target: main` model: each draft opens against its parent branch so its diff shows only its own commits, then retargets to `main` when the parent merges) — use the type-appropriate closing keyword (`Fixes #<sub-issue>` for a bug sub-issue, `Closes #<sub-issue>` otherwise) from the start. It describes the merge that will eventually happen on `main`, and it survives the retarget with no body edit; a `Towards` placed "because the base isn't main yet" has to be remembered and upgraded at every retarget, and a forgotten upgrade means the sub-issue never auto-closes. Know what the keyword does NOT do while the base is a sibling branch: GitHub only creates the issue's linked-PR association (and only auto-closes) for closing keywords on default-branch-base PRs, so until the retarget the sub-issue shows a plain timeline mention and **no linked PR** — deferred, not broken. At each retarget, verify the linkage materialized (`gh pr view <num> --json closingIssuesReferences` lists the sub-issue); if it stays empty, re-save the body so GitHub re-evaluates the keyword against the new base.

If there is no tracking issue, drop the line entirely and open the section with prose.

Expand Down Expand Up @@ -104,5 +105,6 @@ These thoughts mean the PR isn't actually ready to publish or flip:
| "The user said yes a turn ago, this is the same thing" | Bodies change between turns. Confirm the exact body about to land. |
| "I'll just append a note and they can edit later if needed" | They shouldn't have to clean up after the agent. Confirm first. |
| "The PR's already open/ready, the stale body isn't worth re-editing" | The body is what the reviewer reads first; once the diff moves past it, it misleads. Reconcile the body to match the diff — body only, no comment (§Reconciling an open PR's body with reality). |
| "The sub-issue shows no linked PR, the keyword must be wrong" | Closing-keyword linkage only materializes while the PR's base is the default branch. On a stacked draft it's deferred until retarget — verify with `gh pr view <num> --json closingIssuesReferences` then, not before. |
Comment thread
sourcehawk marked this conversation as resolved.

All of these mean: rewrite the body from the right template, paste it inline in chat, and wait for an explicit yes.