| model | sonnet |
| name | gh-pr |
| description | Generate a pull request description from current-branch changes against main and create the draft PR via gh. Use when asked to create a PR, open a draft PR, or write a PR description. |
PR Description Generator
Generate a pull request description from the current branch's changes compared to main.
Prerequisites
- Must be in a git repository with a local
main branch
- Must have commits on the current branch ahead of main
Workflow
Step 1: Gather Context
- Run
git diff main...HEAD to get the full diff.
- Run
git log main..HEAD --oneline to understand the commit history.
- Check if
.github/pull_request_template.md exists in the project root. If it does, read it as the template.
- If no changes are found, report "No changes detected" and stop.
The diff is the ground truth; commit messages and ticket text are hints only. Base every claim in the body on what the diff actually implements, and when they disagree, trust the diff.
Step 2: Generate the PR Description
Output exactly this structure: no wrapping code fences, no preamble, no commentary.
type(scope): Description
----
[body content here]
Line 1: Title
Write a conventional commit title: type(scope): Description
Valid types: feat, fix, refactor, test, chore, docs, style, perf, build, ci
- Use sentence case (capitalise first word only)
- Use imperative mood ("Add feature" not "Added feature")
- Keep under 72 characters
- Issue code prefix: Extract the issue code from the current branch name (e.g.,
feature/cad-1438-... yields CAD-1438, fix/PAY-3080-... yields PAY-3080). Always prefix the PR title with it in brackets: [CAD-1438] type(scope): Description. PR titles should always have the issue code prefix. If the branch name contains no issue code, ask the user for the ticket ID; never invent one.
Line 2: Separator
Write exactly four dashes: ----
Line 3+: Body
If a PR template was found:
- Fill in every section of the template with specific details from the diff
- Keep all original markdown formatting, checkboxes, and HTML elements intact. Never remove or reword the template's checkboxes; edit content around them, not the structure.
- Tick a checkbox only for something actually done and verifiable from the diff or this session; leave the rest unticked rather than optimistically ticking.
- Replace all placeholder text, leave nothing unfilled
- Be specific: reference actual file names, function names, and changes
If no template was found (personal projects):
- Open with 1–2 sentences stating what the PR does (not the problem). Use footnotes to provide supplementary context such as root cause or technical detail.
- Follow with bullet points describing what the user/developer can now do, not what code changed.
- End each bullet point with a full stop (period).
- End with any relevant notes (breaking changes, migration steps, follow-up work, etc.).
- Do NOT add section headings (no
## Summary, etc.) or a Risk section.
Risk Classification
Only include risk classification when the PR template has a "Risks" section. Do not add risk for personal projects or when no template exists.
When the template has a "Risks" section, classify using these levels:
- None: Pure logging, documentation, or test-only changes with zero runtime impact.
- Low: Removing dead code, removing feature-flagged code paths, config changes, or UI-only changes with no data/payment impact. Even if the code being removed is unused or superseded, if it could affect a user's experience (e.g., a venue still on an old flag), classify as Low, not None.
- Medium: Changes to request handling, API behaviour, data queries, or performance-sensitive paths.
- High: Changes to payment flows, order totals, financial calculations, or data integrity.
When in doubt, round up. "None" should only be used when there is truly zero possibility of user-visible impact.
Writing Rules
- Feature overview, not changelog. Ask "what capability does this add?" not "what files did I touch?". Avoid implementation details like file paths or function names unless essential.
- Claim only what ships. If the diff implements something partially or behind a flag, say so ("initial", "behind
flag-name, off by default") rather than describing the finished capability.
- Inline code for technical references: key names, environment variables, config values, keyboard shortcuts, CLI commands, symbols.
- Australian spelling throughout (e.g., "colour", "organisation", "behaviour", "authorise").
Bad (too granular):
- Add
handleOAuth function to auth module.
- Update login component to render new button.
Good (feature-focused):
- Users can now sign in with their GitHub account.
- GitHub profile data is automatically linked to user profiles.
Context framing: state scope modestly, name no colleagues
The "what this is / why" preamble is where PR bodies oversell. Keep it accurate to what the branch actually does:
- No unverified specifics. Drop lead-time and impact claims you cannot back from the diff ("roughly two weeks ahead of the full UI"); state the scope plainly without the number.
- No defensive justifications. Cut value-defending closers ("built for real so it is not throwaway work", "this is not wasted effort"); let the change speak. Same principle as ending at the last real point.
- Match the verb to the actual maturity. A prototype "helps explore requirements"; it is not "the interim slice" or "the full answer". Prefer plain words ("prototype", "step") over coined slicing jargon ("slice").
- Don't name individual colleagues or their separate workstreams. Refer neutrally ("a separate design task"), not "Chloe's design track". Same family as never quoting persona names below: keep internal-people specifics out of the PR body.
Never expose review-round internals
PR reviewers don't have access to the adversarial / persona-lens / Codex / Claude-pane rounds that ran before the PR opened, and don't need to. The PR description is the final artifact: roll every accepted finding into the relevant section (What's new, Acceptance criteria, Risks, Local verification) as if the author thought of it. Do not include:
- A "Review consensus" / "Review findings" / "Adversarial review" / "Codex review" section.
- Phrases like "cxd-3 suggestion", "BT-2 blocker", "addresses adversarial review on PR #...", or any other reference to a review round, finding ID, or reviewing agent.
- Severity tables, consensus tables, or "Applied / Deferred" lists framed as review output.
Persona names are never quoted. Persona-lens reviews are a focus reshuffle, not a real reviewer's signoff. Naming the persona (Ben Thompson, Yofamb, any real or invented person used as a lens) in the PR body misrepresents simulated review as actual representation or approval. Drop the name and keep the substance.
If a "what was considered but not implemented" rollup is genuinely useful (e.g., reviewers might wonder why X wasn't done), add it as a plain "Scope" or "Considered, not implemented" section written in the author's voice, framed as the author's own design decisions. Each line states the choice and the reason, with no reference to which review round raised it. Default: no such section; most deferrals belong in follow-up tickets, not PR bodies.
Bad:
## Review consensus (cxd adversarial + Ben Thompson lens)
Addresses adversarial review on PR #2391: ...
Deferred per BT-1: shared AlertDialog helper extraction.
Good (when a scope rollup is warranted):
## Considered, not implemented
- Shared AlertDialog page-object helper: would only have one other call site today; revisit when the third lands.
- Stronger testName uniqueness: changing only the new tests creates intra-file inconsistency; whole-file refactor is out of scope for this ticket.
Stacked PRs
If this PR is part of a stacked series (its base is another PR's branch, not main), read references/stacked-prs.md for the required body prepend, --base flag, and numbering workflow. Skip it for ordinary PRs targeting main.
Step 3: Create the Draft PR
- Push the current branch to the remote if it hasn't been pushed yet:
git push -u origin HEAD
- Create the PR using
gh:
gh pr create --draft --title "<title from Step 2>" --body "$(cat <<'EOF'
<body from Step 2>
EOF
)"
- Output the PR URL returned by
gh. No preamble, no commentary, just the URL.
Step 4: Post-Creation (when user wants it merged)
If the user indicates they want the PR merged (e.g., "merge it", "get it merged", "make sure it's merged"):
- Apply a label: List the available labels with
gh label list and ask the user which label to apply. Apply with gh pr edit <number> --add-label "<label>".
- Enable auto-merge:
gh pr merge <number> --auto --squash
- Check status: run
gh pr checks <number> to verify all checks are passing. If any checks are failing, investigate and fix the issues.
- Monitor: ask the user how often to check merge status (default 6 minutes). Set up a
/loop at that interval to poll gh pr view <number> --json state,mergedAt until merged, then cancel the loop.