create-pr
Create a well-structured pull request with proper description, design decisions, and file changes. Use when asked to create a PR, open a PR, or submit changes for review.
create
SKILL.md.claude/skills/create-pr
GitHubCreate Pull Request
Self-review, write a dense verified description, open the PR, subscribe. Invoking this skill is the request for all of it.
Runtime profile
- Pi / OpenAI: run PR orchestration with GPT-5.6 Sol at effort
low. - Do not raise the orchestration effort for self-review. When Step 3 requires
/code-review, keep that skill's separate Sol/high reviewer profile.
Flow
- Context (parallel):
git branch --show-current·git status -sb·git log main..HEAD --oneline·git diff main...HEAD --stat·git diff main...HEAD(read it). Ticket:git branch --show-current | grep -oiE 'thr-[0-9]+' | tr '[:lower:]' '[:upper:]'— if found, in title + linked in body; else cite audit/design ids (E2EE-22,INV-62) in body. - Draft Problem + Solution before verifying — your claims become assertions step 3 holds against the code. A claim like "the prune is atomic" is description and correctness check; verifying catches prose drift and real bugs in one pass.
- Self-review + verify every claim. If
.tmp/build-feature-reviewed.diffand.tmp/build-feature-review-evidence.mdexist, read the recordedbase_ref, generate the current patch with the same{ git diff "$base_ref"...HEAD; git diff HEAD; }shape, and compare it byte-for-byte. A match means the broad adversarial review plus targeted post-fix recheck covers the final diff: verify PR prose and evidence only; do not repeat the invariant audit or/code-review. Without matching evidence, walk the diff for race-safe writes (INV-20), workspace scoping (INV-8), outbox-in-tx (INV-4/7), canonical access predicates (INV-62), no silent fallbacks (INV-11), Zod inputs (INV-55), and dead code (INV-38); substantial changes then run/code-review. In both paths, verify each draft claim literally. Findings → fix in branch and report them honestly. - Files table + test plan — after review, real run counts. Never check an unrun box; unchecked + honest reason beats a checkmark nobody can trust.
- Create. First, is this branch part of a stack? Run
gh stack view --json— if it succeeds and lists the current branch, this is a stacked branch and the flow differs (see "Stacked branches" below). Otherwise: body to.tmp/pr-body.md, thengh pr create --base main --title "…" --body-file .tmp/pr-body.md. Web/remote sessions (nogh):mcp__github__create_pull_request; fallbackgh api repos/{owner}/{repo}/pulls --method POST. Always return the PR URL. - Subscribe:
mcp__github__subscribe_pr_activityif available; say so. Skip if user declined watching.
Stacked branches
If step 5 found the branch in a gh stack, a plain gh pr create is the wrong tool — it opens a PR that is not linked into the GitHub Stack, so reviewers never see the stack navigation and gh stack merge/sync can't drive it. Do the per-branch work of steps 1–4 the same way (verified body to .tmp/pr-body.md), then:
gh pr create --base <parent-branch> --title "…" --body-file .tmp/pr-body.md— base is the branch below this one in the stack (gh stack viewshows it), nevermainfor anything but the bottom branch.gh stack submit --auto --open— this is the step that actually creates the GitHub Stack. It adopts the PRs you just made ("… is up to date"), links them, and adds the stack nav block. Creating the PRs is not enough; withoutsubmitthey are just chained-base PRs, not a Stack. Run it once from any branch in the stack — it links the whole stack.
Verify with gh stack view --json (a Stack #NNNN now exists). See the gh-stack skill for the full contract.
Description template
Reader model: Problem/Solution get read, file table gets skimmed, below that only tooling looks. Keep the top dense, the bottom minimal and collapsed.
**Linear:** [THR-XX](https://linear.app/threa/issue/THR-XX) _(if any)_
## Problem
[2–4 sentences. The defect/limitation with real files/symbols/ids. Why it matters.]
## Solution
[Shape in one sentence, then mechanism as tight bullets — real functions, files,
numbers. Fold decisions in as "X over Y — reason" bullets only where a real
alternative existed. Deliberate deviations / out-of-scope: one line each, so a
reviewer doesn't "fix" them.]
## Files
| File | Change |
| ---- | ------ |
| `path.ts` | What changed (**new** / **deleted** where applicable) |
## Test plan
- [x] suite — N pass
- [ ] not done — honest reason
<details>
<summary>📋 Full implementation plan</summary>
[Via /sync-plan or /find-plan. Keep this exact summary line — CodeRabbit,
/code-review, /update-pr find the block by it. Omit when no plan exists.]
</details>
---
🤖 _PR by [Claude Code](https://claude.com/claude-code)_
Match weight to change: docs/one-file PR = Problem / Solution / Test plan only. Don't pad a one-liner; don't crush a rewrite into three sentences.
Style
- Fact-per-word. If a sentence survives deleting half its words, delete them.
- Name real things —
resolveActorRecipients,?panel=,20260613064500_sync_log_retention.sql. "The relevant helper" means unverified. - Concrete numbers ("30-day horizon + ~2,000-row floor", "200ms skeleton delay"), never "configurable"/"small viewports".
- Decisions carry the rejected alternative and its failure mode; cite invariants and rulings verbatim ("Kris's call", "the audit's words (E2EE-22)").
- No slop: "comprehensive", "robust", "seamless", "powerful", "simply". Understated; honest about what's not covered — that candor is what makes the rest trustworthy.
Title
<type>(THR-XX): specific summary — feat/fix/refactor/docs/test/chore; omit parenthetical when no ticket. Title alone says what changed: feat: sync_log retention with below-floor bootstrap fallback, not feat: update sync.