| name | Writing Pull Requests |
| description | Encodes PR authoring conventions including imperative titles with repository-capability verbs, motivation-focused descriptions, hidden context surfacing, and prose flow guidelines. Must be loaded before composing any pull request title or description, whether drafting interactively or creating programmatically with gh pr create. |
| user-invocable | false |
Writing Pull Requests
Effective pull requests communicate the why behind changes, not the what. Code diffs already show what changed; the PR title and description convey motivation, impact, and context that accelerates review.
Core Principle: Repository Transformation
The PR title describes how the repository changes when the PR merges. The verb targets the repository capability, not the developer action.
The "Fill in the Blank" Technique
Complete this sentence with your title: "After this PR merges, the repository will _____."
The verb must make grammatical sense in this frame. Developer-action verbs fail the test:
| Verb | "The repository will _____" | Works? |
|---|
| Parse MAC addresses | "The repository will parse MAC addresses" | Yes |
| Add rate limiting | "The repository will add rate limiting" | No |
| Handle nil emails | "The repository will handle nil emails" | Yes |
| Implement caching | "The repository will implement caching" | No |
Developer-action verbs (add, implement, create, write, update, change) describe what the developer did. Repository-capability verbs (parse, handle, support, expose, enable, optimize, simplify, prevent, serialize, validate, extract) describe what the code does.
Quick Reference by Intent
| Intent | Verbs |
|---|
| New capability | handle, parse, transform, validate, serialize, cache, pool |
| Improvement | optimize, simplify, consolidate, enhance |
| Fix | fix, correct, respect, prevent |
| Structural | extract, expose, define, introduce |
| Removal | remove, drop, deprecate |
| Configuration | configure, enable, disable |
| Documentation | explain, clarify, document |
For comprehensive verb guidance and rationale, see examples/bad-pr-examples.md.
Title Structure
PR titles follow imperative mood, beginning with a verb:
Format: <Verb> <what the repository now does>
- Begin with an action verb in imperative form
- Describe the new capability or behavior
- Keep concise but descriptive
- Capitalize the first letter (it is a sentence)
Examples:
Parse MAC addresses without separators
Limit authentication attempts to prevent brute-force attacks
Serialize connection pool cleanup to prevent leaks
Extract authentication into dedicated service
Gathering Context
Before drafting a PR, gather context from multiple sources:
From Git
Analyze the working tree to understand the change scope:
- Review the diff to understand what changed
- Check commit history to see the progression of work
- Note branch name conventions that may encode intent
From the Repository
Search for related context in the repository:
- Check open issues that may relate to the changes
- Review recently closed issues for ongoing efforts
- Look at recent PRs touching similar areas
Use gh issue list and gh pr list to discover related work. Reference relevant issues in the PR description to connect the contribution to ongoing efforts.
From the Conversation
Draw context from the discussion that led to the changes:
- Why was this change initiated?
- What alternatives were considered?
- What constraints shaped the solution?
When context is missing, ask proactively. The motivation behind a change is essential for a good PR.
Surfacing Hidden Context
PRs live in the solution-space: the author has made decisions and the changeset reflects those decisions. The description must surface the context that led to this solution.
What the Prose Must Capture
The diff shows what changed. The description must explain what the diff cannot convey:
- Expected outcome: What the change accomplishes (verifiable against the changeset)
- Intent behind the change: Why this change, why now
- Constraints that shaped the solution: Technical, organizational, or timeline limitations that drove this approach
- Designed exclusions: What this change explicitly does not address and why that's intentional
- Reevaluation triggers: Conditions under which this decision should be revisited
- Assumptions made: What must remain true for this solution to work
- Trade-offs accepted: What was sacrificed and why it was acceptable
Alternatives considered may be worth brief mention, but focus on constraints and exclusions over exhaustive comparison of rejected options.
Detecting Missing Context
Use intelligence to detect when essential context is missing. When gaps exist, ask targeted questions before drafting:
- "What constraint prevented the simpler solution?"
- "What is explicitly out of scope for this change, and why?"
- "Under what conditions should we revisit this approach?"
- "What should reviewers verify to confirm this works as intended?"
If the user cannot provide the information after being asked, insert actionable placeholders that specify exactly what information is missing and how to obtain it:
[FILL: Ask the original author why X was chosen over Y]
[FILL: Check git blame for commit message explaining this constraint]
[FILL: Review linked issue for context on why this approach]
Placeholders must be specific enough that someone can act on them immediately.
Embedding Rationale in Code
When rationale is uncovered, check the changeset for appropriate places to embed it permanently. Respect existing project conventions - do not introduce new documentation patterns.
Preferred locations (in order of preference):
- Code comments: Near the code the rationale affects - constraints, reevaluation triggers, non-obvious decisions
- Doc strings: In existing function/method documentation - API contracts, assumptions, usage caveats
- Existing documentation: If the project has architecture docs, design docs, or similar markdown files that already cover this area
Do not:
- Create ADR files if the project has no ADR convention
- Add niche sections to an otherwise generic README
- Introduce documentation patterns the project doesn't use
If no trivial code location exists, include the rationale in the PR description. The PR is the fallback, not the first choice - but it's better there than nowhere.
Repository Templates
Before drafting, check for repository-specific templates that encode team conventions.
Locating Templates
Search these paths (first match wins):
.github/pull_request_template.md
.github/PULL_REQUEST_TEMPLATE.md
docs/pull_request_template.md
pull_request_template.md (root)
.github/PULL_REQUEST_TEMPLATE/ (multiple templates)
Using Templates
When a template exists, evaluate fit:
- Good fit: Follow the template structure
- Partial fit: Use relevant sections, adapt others with judgment
- Poor fit: Draft freely but note why the template didn't apply
Templates are guides, not rigid forms.
Description Philosophy
PRs are solution-space documents. Issues define what needs solving (problem-space); PRs explain why this particular solution was chosen and what outcome it achieves.
The description explains why this solution exists and what outcome it delivers. The expected outcome must be verifiable: reviewers should be able to confirm the changeset achieves the stated intent.
The first paragraph immediately follows the title without a header. This opening carries the weight of explaining the change purpose.
When an issue is linked: The description can be brief since the issue provides problem-space context. Focus on the solution rationale: why this approach, what trade-offs were accepted.
When no issue exists: The description must compensate by providing both problem-space context (what prompted the change, who is affected) and solution-space rationale (why this approach over alternatives).
PR Scope
Keep PRs focused on a single logical change.
Signs of good scope:
- Reviewable in one sitting (under 400 lines typical)
- Single purpose evident from title
- All changes relate to stated intent
Signs of scope creep:
- "Also fixes..." or "While I was here..." in description
- Multiple unrelated file groups changed
When scope grows, split into stacked PRs or separate unrelated changes.
Proofs
Complex changes benefit from proof that they work as expected:
- Library code: Examples in code demonstrate capability; tests prove fixes
- Executables/backends: Manual verification in production-like environments
Link proofs using trailer format: Proof: org/repo#123 (comment)
Workflow
When creating a PR:
- Gather context: Review diff, commits, branch name, and conversation
- Search for related work: Check open/closed issues and recent PRs
- Identify the capability: What does the repository do differently?
- Draft title: Verb + capability (not developer action)
- Write description: Focus on why, link related issues, include proof for complex changes
- Review: Does the title describe repository transformation? Does the description explain motivation?
Reference Files
For detailed guidance, consult:
| File | Contains |
|---|
references/description-structure.md | Description format, prose flow, issue linking, post-merge patterns |
examples/good-pr-examples.md | Effective PR examples with probe tags showing context discovery |
examples/bad-pr-examples.md | Anti-patterns with detailed rationale for why they fail |
About probe tags: Example files use <probe> tags to demonstrate targeted questions that surface essential context. Each probe shows what to ask ("What constraint prevented the simpler solution?", "What's the proof?") and the information it reveals. Use this pattern when gathering context before drafting.
What to Avoid
Rehashing commits in bullet lists
The git log shows commits; the description explains intent the diff cannot convey.
Describing file-by-file changes
The diff shows which files changed. Describe the capability, not the file list.
Starting with "This PR adds/implements/creates..."
This describes developer action. Start with why this change matters or what outcome it achieves.
Skipping context when no issue exists
Without a linked issue, the description must provide problem-space context. "Fixes the bug" with no issue is meaningless.
Using developer-action verbs in titles
| Avoid | Why | Use Instead |
|---|
| add | Describes action of adding | handle, define, introduce |
| implement | Narrates development | handle, support, enable |
| update | Vague about what changed | optimize, fix, refactor (be specific) |
| change | Maximally vague | optimize, correct, simplify (be specific) |
| create | Focuses on creation not function | define, establish, introduce |
These describe what the developer did, not what the repository now does. See examples/bad-pr-examples.md for comprehensive analysis.
Line Formatting for GitHub
GitHub's markdown renderer treats hard newlines within a paragraph as literal line breaks. When composing --body content for gh pr create, write each paragraph as a single continuous line with no mid-sentence wraps. Newlines should only appear:
- Between paragraphs (blank line)
- Before list items, headings, or code blocks
- Where markdown syntax requires them
This differs from git commit -m, where hard wraps are conventional because terminals render them directly.
Self-Review Checklist
Before presenting the PR:
Process:
Title:
Description: