writing-prs
Use when creating pull requests, writing PR descriptions, or when finishing-a-development-branch creates a PR. Ensures PR titles follow conventional commits and descriptions follow the hybrid template format.
| Model | Source | Category |
|---|---|---|
| sonnet | core | Git |
Tools: Bash(gh *)
Overview
Section titled “Overview”Write PR descriptions that help reviewers — not descriptions that restate the diff.
Core principle: The diff shows what changed. The PR description explains why, where to look, and how to verify.
First action — before anything else:
touch /tmp/.armadillo-pr-skill-activeThis flag signals the skill is active. The flag is single-use — consumed on PR creation.
Mandatory Announcement — FIRST OUTPUT before anything else:
┏━ 🚀 writing-prs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
<details><summary><strong>Full Reference</strong></summary>
# Writing PRs
## Overview
Write PR descriptions that help reviewers — not descriptions that restate the diff.
**Core principle:** The diff shows what changed. The PR description explains why, where to look, and how to verify.
**First action — before anything else:**```bashtouch /tmp/.armadillo-pr-skill-activeThis flag signals the skill is active. The flag is single-use — consumed on PR creation.
Mandatory Announcement — FIRST OUTPUT before anything else:
┏━ 🚀 writing-prs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓┃ [one-line description of what PR you're creating] ┃┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛No exceptions. Box frame first, then work.
PR Title
Section titled “PR Title”Conventional commits format. Always.
<type>(<scope>): <description>| Type | When |
|---|---|
feat | New feature or capability |
fix | Bug fix |
refactor | Code restructure, no behavior change |
test | Adding or updating tests |
docs | Documentation only |
chore | Build, deps, config, tooling |
perf | Performance improvement |
Rules:
- Under 70 characters
- Lowercase after the colon
- No period at the end
!before:for breaking changes:feat!: remove deprecated auth export
PR Description Format
Section titled “PR Description Format”Always Present
Section titled “Always Present”## WhyOne sentence explaining the motivation. Link to issue if one exists.
## Changes▪ First change — what and why (not just "updated file.ts")▪ Second change▪ Third change
## Test plan- [ ] `npm test` passes (or project's test command)- [ ] Manual: specific steps to verify the change works
## Links- Closes #<issue>- Related: #<related-issue>
Generated with [Claude Code](https://claude.com/claude-code)Conditional: Review Guide
Section titled “Conditional: Review Guide”Trigger: PR touches 3 or more files.
Add between Changes and Test plan:
## Review guide| File | Focus ||------|-------|| `src/auth.ts:45-80` | New validation logic — core change || `src/middleware.ts:12` | Error handling flow changed || `tests/auth.test.ts` | New test cases — verify coverage |Rules:
- Include line numbers when pointing to specific logic
- Most important file first
- Skip test files unless they contain surprising logic
Conditional: Breaking Changes
Section titled “Conditional: Breaking Changes”Trigger: PR introduces breaking changes (removed exports, changed types, renamed APIs).
Add after Review guide (or Changes if no review guide):
## Breaking changes▪ Removed `checkAuth()` export — use `validateToken()` instead▪ Changed `UserSession` type — added required `expiresAt` fieldRules:
- Each item: what broke + what to do instead
- Link to migration guide if complex
Conditional: Screenshots
Section titled “Conditional: Screenshots”Trigger: PR includes UI changes.
Add after Changes:
## Screenshots| Before | After ||--------|-------||  |  |How to Build the Description
Section titled “How to Build the Description”Step 1: Analyze the diff
Section titled “Step 1: Analyze the diff”# Full diff against base branchgit diff main...HEAD
# File-level summarygit diff main...HEAD --stat
# Commit historygit log main..HEAD --onelineStep 2: Determine the “Why”
Section titled “Step 2: Determine the “Why””Answer ONE of these — not all:
- What problem does this solve?
- What does the user/developer gain?
- What issue/spec/design does this implement?
If you can’t answer any of these, the PR might not be ready.
Step 3: Write Changes as outcomes
Section titled “Step 3: Write Changes as outcomes”Bad:
▪ Updated auth.ts▪ Modified middleware.ts▪ Added auth.test.tsGood:
▪ Added JWT expiry validation — tokens now rejected after TTL▪ Refactored auth middleware to use centralized validator▪ Added 8 test cases covering valid, expired, and malformed tokensStep 4: Write actionable test steps
Section titled “Step 4: Write actionable test steps”Bad:
- [ ] Tests passGood:
- [ ] `npm test` passes- [ ] Manual: login → wait 5 min → refresh → should redirect to /login- [ ] Check: expired token returns 401, not 500Step 5: Evaluate conditionals
Section titled “Step 5: Evaluate conditionals”| Condition | Add section |
|---|---|
| 3+ files changed | Review guide |
| Breaking changes | Breaking changes |
| UI changes | Screenshots |
| New dependencies | Note in Changes with reason |
Anti-Patterns
Section titled “Anti-Patterns”| Pattern | Problem | Fix |
|---|---|---|
| Restating the diff | ”Updated auth.ts to add validateToken” — reviewer sees that | Explain why: “Added token expiry check to prevent stale sessions” |
| Emoji headers | ”🔧 Changes” | Plain text headers |
| Wall of prose | 3 paragraphs where 3 bullets work | Bullet points |
| Missing “why” | Changes listed without motivation | Always lead with Why section |
| Vague test plan | ”Tests pass” | Specific commands + manual steps |
| Everything in title | 90-char title, empty body | Short title, details in body |
| AI filler | ”This PR introduces several improvements…” | Delete. Start with the first real sentence. |
Creating the PR — REST API
Section titled “Creating the PR — REST API”Always use gh api (REST). Never use gh pr create (GraphQL — rate-limited).
Always use HEREDOC for the body. Always use env -u GITHUB_TOKEN.
# Detect repo slugSLUG=$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')
# Push branch firstenv -u GITHUB_TOKEN git push -u origin <feature-branch>Standard (< 3 files)
Section titled “Standard (< 3 files)”SLUG=$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')BODY=$(cat <<'EOF'## Why<motivation>
## Changes▪ <change 1>▪ <change 2>
## Test plan- [ ] <test command>- [ ] <manual step>
## Links- Closes #<issue>
Generated with [Claude Code](https://claude.com/claude-code)EOF)env -u GITHUB_TOKEN gh api "repos/${SLUG}/pulls" \ --method POST \ --field title="<type>(<scope>): <description>" \ --field head="<feature-branch>" \ --field base="main" \ --field body="$BODY" \ --jq '.number, .html_url'With Review Guide (3+ files)
Section titled “With Review Guide (3+ files)”SLUG=$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')BODY=$(cat <<'EOF'## Why<motivation>
## Changes▪ <change 1>▪ <change 2>
## Review guide| File | Focus ||------|-------|| `<file:line>` | <what to look at> |
## Test plan- [ ] <test command>- [ ] <manual step>
## Links- Closes #<issue>
Generated with [Claude Code](https://claude.com/claude-code)EOF)env -u GITHUB_TOKEN gh api "repos/${SLUG}/pulls" \ --method POST \ --field title="<type>(<scope>): <description>" \ --field head="<feature-branch>" \ --field base="main" \ --field body="$BODY" \ --jq '.number, .html_url'Draft PR (WIP)
Section titled “Draft PR (WIP)”When creating a work-in-progress PR, add --field draft=true:
SLUG=$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')BODY=$(cat <<'EOF'## Why<motivation>
## Changes (so far)▪ <change 1>▪ <change 2>
## StatusWork in progress — not ready for review
Generated with [Claude Code](https://claude.com/claude-code)EOF)env -u GITHUB_TOKEN gh api "repos/${SLUG}/pulls" \ --method POST \ --field title="<type>(<scope>): WIP <description>" \ --field head="<feature-branch>" \ --field base="main" \ --field body="$BODY" \ --field draft=true \ --jq '.number, .html_url'Convert draft to ready:
env -u GITHUB_TOKEN gh api "repos/${SLUG}/pulls/${PR_NUM}" \ --method PATCH \ --field draft=falseWhen to use drafts:
- Early signal on approach before full implementation
- WIP visibility for team awareness
- When
finishing-a-development-branchoffers Option 2 (Draft PR)
Integration
Section titled “Integration”Called by:
finishing-a-development-branch— when creating a PR (Option 1)- Any direct PR creation via
gh api
Enforced by:
.claude/rules/pr-format.md— always-loaded format reminder- Post-push hook — reminds to create PR if branch has no PR after push
Pairs with:
requesting-code-review— review after PR is createdworktree— feature branch isolation before PR