- Verify you're NOT on main/master/develop
- Check for uncommitted changes (invoke commit skill first if any)
- Read the FULL diff against base branch (not just commit messages)
- Scan for breaking changes and document them
- Push the branch before creating the PR
Creating PRs without verification = broken builds, missing context, failed reviews
This is not optional. Every PR requires disciplined preparation. </EXTREMELY-IMPORTANT>
Create Pull Request
MANDATORY FIRST RESPONSE PROTOCOL
Before creating ANY PR, you MUST complete this checklist:
- ☐ Run
git branch --show-current— verify NOT on protected branch - ☐ Run
git status --short— invoke commit skill if uncommitted changes - ☐ Run
git log main..HEAD— verify commits exist - ☐ Run
git diff main...HEAD— read FULL diff (not just commit messages) - ☐ Check for conflict markers in changed files
- ☐ Identify breaking changes (removed exports, schema changes, API changes)
- ☐ Determine PR type, scope, size, and risk
- ☐ Announce: "Creating PR: type: [title]"
Creating PRs WITHOUT completing this checklist = incomplete reviews and rework.
Overview
Validate branch readiness, analyze all commits since divergence from base, generate a structured PR with meaningful title and body, push to remote, and create via gh pr create. If uncommitted changes exist, invoke the commit skill first.
When to Use
- User says "create PR", "open PR", "submit PR", "/pr", "make a PR"
- User says "push and create PR" or "send this for review"
- After completing work and user wants to submit for review
- $ARGUMENTS provided as PR guidance (e.g.,
/pr add auth feature)
Never create a PR proactively. Only when explicitly requested.
Step 1: Gather Branch Context
Gate: Full context collected before proceeding to Step 2.
Run these commands to understand the full picture:
# Current branch name
git branch --show-current
# Check if branch tracks a remote
git status -sb
# Uncommitted changes (never use -uall)
git status --short
# Find the base branch (main or master)
git log --oneline --decorate -1 origin/main 2>/dev/null || git log --oneline --decorate -1 origin/master 2>/dev/null
# All commits on this branch since diverging from base
git log --oneline main..HEAD 2>/dev/null || git log --oneline master..HEAD 2>/dev/null
# Full diff against base branch (what the PR will contain)
git diff main...HEAD 2>/dev/null || git diff master...HEAD 2>/dev/null
Read the actual diff output. You need the full diff to write an accurate PR summary — not just commit messages.
Determine Base Branch
Use this priority:
- If user specifies a base branch in $ARGUMENTS, use it
- Check for
mainbranch:git rev-parse --verify origin/main 2>/dev/null - Check for
masterbranch:git rev-parse --verify origin/master 2>/dev/null - Check for
developbranch:git rev-parse --verify origin/develop 2>/dev/null - If none found, ask the user
Store as $BASE_BRANCH for all subsequent steps.
Step 2: Pre-PR Validation
Gate: Branch ready (commits exist, no uncommitted changes) before proceeding to Step 3.
Uncommitted Changes
If git status --short shows changes:
- Invoke the
commitskill using the Skill tool:Use the Skill tool with skill="commit" - The commit skill handles staging, quality checks, and committing
- After commit completes, re-run Step 1 to pick up the new commit(s)
- Continue with the updated branch state
Empty Branch
If git log $BASE_BRANCH..HEAD shows no commits:
- Stop. "No commits found on this branch relative to $BASE_BRANCH. Nothing to create a PR for."
Branch Naming
Validate branch name is not main, master, or develop:
- If on a protected branch, stop: "You're on $BRANCH. Create a feature branch first."
Step 3: Analyze All Commits
Gate: PR classified (type, scope, size, risk) before proceeding to Step 4.
Read every commit in the branch — not just the latest:
# All commits with full messages
git log --format="%h %s%n%b%n---" $BASE_BRANCH..HEAD
# File change summary across all commits
git diff --stat $BASE_BRANCH...HEAD
# Full diff for understanding scope
git diff $BASE_BRANCH...HEAD
Classify the PR
Based on ALL commits and the full diff, determine:
| Aspect | How to Determine |
|---|---|
| Type | Feature (feat), bugfix (fix), refactor, docs, chore — from commit types and actual changes |
| Scope | Primary area affected — from file paths and branch name |
| Size | S (1-3 files), M (4-10 files), L (11-25 files), XL (26+ files) |
| Risk | Low (docs, tests), Medium (new feature), High (breaking changes, core logic, DB migrations) |
| Breaking | Any API changes, removed endpoints, schema changes, renamed exports |
Detect Breaking Changes
Scan the diff for:
- Removed or renamed public exports
- Changed function signatures
- Database migration files (schema changes)
- API endpoint changes (routes added/removed/changed)
- Environment variable changes
- Package dependency major version bumps
If breaking changes detected, they MUST appear in the PR body.
Step 4: Pre-PR Quality Checks
Gate: No blocking issues before proceeding to Step 5.
Run quality gates across the entire branch diff:
# TypeScript type check
npx tsc --noEmit
# ESLint (if configured)
ls .eslintrc* eslint.config.* 2>/dev/null && git diff --name-only $BASE_BRANCH...HEAD -- '*.ts' | xargs npx eslint
# Conflict markers in any changed file
git diff --name-only $BASE_BRANCH...HEAD | xargs grep -n '<<<<<<<\|=======\|>>>>>>>' 2>/dev/null
If Checks Fail
- Conflict markers: Block. Must resolve before creating PR.
- Type errors: Warn user. Recommend fixing. Ask whether to proceed.
- Lint errors: Show errors. Offer auto-fix. Recommend fixing.
Quality issues are warnings for PRs (reviewer can catch them) — except conflict markers which always block.
Step 5: Generate PR Title
Gate: Title follows conventions before proceeding to Step 6.
Format
<type>(<scope>): <concise description>
Rules
- Under 72 characters
- Imperative mood: "add feature" not "added feature"
- No period at the end
- If breaking change, add
!:feat(api)!: remove legacy endpoint - Scope from branch name or primary file path area
- Must reflect ALL changes, not just the last commit
Title from Branch Name
Use branch name as a hint, verify against actual changes:
| Branch | Likely Title |
|---|---|
feat/add-auth-system | feat(auth): add JWT authentication system |
fix/cart-total-calculation | fix(cart): correct total calculation with discounts |
refactor/search-service | refactor(search): restructure search service architecture |
If $ARGUMENTS contains a clear title, use it (respecting format rules).
Step 6: Generate PR Body
Gate: Body has all required sections before proceeding to Step 7.
Use this template with HEREDOC:
## Summary
<3-5 bullet points describing WHAT changed and WHY>
## Changes
<Grouped by area — list key files/modules changed>
### <Area 1>
- description of change
### <Area 2>
- description of change
## Breaking Changes
<Only if breaking changes detected in Step 3. Otherwise omit entirely.>
- What broke
- Migration steps
## Test Plan
- [ ] <Specific test scenario 1>
- [ ] <Specific test scenario 2>
- [ ] <Specific test scenario 3>
## Notes
<Optional: deployment notes, config changes, dependencies added>
Body Writing Rules
- Summary bullets: Focus on "why" and business impact, not just "what"
- Changes section: Group by module/area, not by commit
- Test Plan: Specific, actionable items a reviewer can verify — not generic "run tests"
- Breaking Changes: Include migration steps if applicable
- Notes: Mention new env vars, DB migrations, service dependencies
- Omit any section with no content (except Summary and Test Plan — always required)
Step 7: Push Branch
Gate: Branch pushed to remote before proceeding to Step 8.
# Push with upstream tracking
git push -u origin $(git branch --show-current)
If push fails:
- Rejected (non-fast-forward): "Remote has changes not in your branch. Pull or rebase first."
- Permission denied: "Push access denied. Check your repository permissions."
- Branch protection: "Branch is protected. Create a PR from a different branch."
Step 8: Create PR via GitHub CLI
Gate: PR created successfully before proceeding to Step 9.
Standard PR
gh pr create --base "$BASE_BRANCH" --title "<title>" --body "$(cat <<'EOF'
<generated body from Step 6>
EOF
)"
With Options from $ARGUMENTS
Parse $ARGUMENTS for additional options:
| User Says | Flag |
|---|---|
| "draft PR", "WIP" | --draft |
| "assign @user" | --assignee user |
| "add reviewer @user" | --reviewer user |
| "label bug" | --label bug |
| "milestone v2" | --milestone "v2" |
Example with options:
gh pr create --base main --draft --reviewer "tech-lead" --label "feature" \
--title "feat(auth): add JWT authentication" \
--body "$(cat <<'EOF'
...body...
EOF
)"
If gh is Not Available
If gh pr create fails with "command not found":
- Show the PR title and body to the user
- Provide the GitHub URL:
https://github.com/<org>/<repo>/compare/$BASE_BRANCH...<branch> - Instruct: "GitHub CLI not found. Create the PR manually using the URL above."
Step 9: Verify and Report
Gate: PR verified and URL reported before proceeding to Step 10.
After creating the PR:
# Get PR details
gh pr view --json number,url,title,state,isDraft
Report to the user:
PR #<number> created: <title>
URL: <url>
Base: <base> <- <branch>
State: <open/draft>
Size: <S/M/L/XL> (<N> files changed, +<additions> -<deletions>)
If there are remaining uncommitted changes, mention them.
Safety Rules
| Rule | Reason |
|---|---|
| Never create PRs proactively | Only when explicitly asked |
| Never force push before PR | Rewrites history others may depend on |
| Never create PR from main/master/develop | These are protected base branches |
| Never create PR with conflict markers | Unresolved conflicts break the build |
| Never fabricate test results in PR body | Test plan must reflect actual state |
| Never omit breaking changes from body | Reviewers must know about breaking changes |
| Never include secrets in PR body | No tokens, passwords, or keys in description |
Always use gh CLI over manual API calls | Handles auth, org context, templates properly |
| Always push before creating PR | Remote must have the branch |
| Always read full diff, not just commits | Commit messages can be misleading |
Quick Reference: PR Readiness Checklist
1. On a feature branch? → BLOCK if on main/master/develop
2. Uncommitted changes? → Invoke commit skill first
3. Has commits vs base? → BLOCK if no commits
4. Conflict markers? → BLOCK until resolved
5. Type errors? → WARN, recommend fixing
6. Lint errors? → WARN, offer auto-fix
7. Breaking changes documented? → Ensure in PR body
8. Branch pushed to remote? → Push if not
9. gh CLI available? → Fallback to manual if not
10. All clear → create PR
Quick Reference: Body Section Guide
Summary → ALWAYS (3-5 bullets, why + what)
Changes → ALWAYS for M/L/XL PRs, optional for S
Breaking → ONLY if breaking changes detected
Test Plan → ALWAYS (specific scenarios, checkboxes)
Notes → ONLY if deployment/config/dependency changes
Resources
See references/pr-body-examples.md for full PR body examples across different PR types (feature, bugfix, refactor, breaking change).
Step 10: Verification (MANDATORY)
After creating PR, verify complete workflow:
Check 1: PR Exists
-
gh pr viewshows the PR details - PR URL is accessible
Check 2: Content Quality
- Title follows conventional format
- Summary section has 3-5 bullets
- Test plan has specific scenarios
Check 3: Breaking Changes Documented
- If breaking changes detected, they appear in PR body
- Migration steps included if applicable
Check 4: Branch State
- Local and remote branches are in sync
- No remaining uncommitted changes
Check 5: PR State
- PR is in correct state (open/draft as intended)
- Base branch is correct
- Labels/reviewers assigned (if requested)
Gate: Do NOT mark PR creation complete until all 5 checks pass.
Quality Checklist (Must Score 8/10)
Score yourself honestly before marking PR creation complete:
Context Gathering (0-2 points)
- 0 points: Created PR without reading diff
- 1 point: Read commit messages only
- 2 points: Read full diff against base branch
Validation (0-2 points)
- 0 points: Created PR with uncommitted changes or from protected branch
- 1 point: Validated some checks
- 2 points: All pre-PR validations pass
Title Quality (0-2 points)
- 0 points: Generic title ("Update code", "Fix bug")
- 1 point: Has type but vague description
- 2 points: Proper format: type(scope): clear description <72 chars
Body Quality (0-2 points)
- 0 points: Empty or minimal body
- 1 point: Has summary but missing test plan
- 2 points: Complete: summary, changes (if M+), breaking changes (if any), test plan
Breaking Changes (0-2 points)
- 0 points: Breaking changes exist but not documented
- 1 point: Breaking changes mentioned but no migration steps
- 2 points: No breaking changes, OR fully documented with migration steps
Minimum passing score: 8/10
Common Rationalizations (All Wrong)
These are excuses. Don't fall for them:
- "The commit messages explain it" → STILL read the full diff
- "It's a small PR" → STILL write summary and test plan
- "I'll add the test plan later" → Write it NOW, reviewers need it
- "There are no breaking changes" → STILL check for removed exports, API changes
- "I can push after creating the PR" → PUSH FIRST, then create PR
- "The title is obvious" → STILL use conventional format with type and scope
- "gh isn't installed" → STILL provide manual URL and formatted body
- "It's just a draft" → Draft PRs STILL need quality body and test plan
Failure Modes
Failure Mode 1: PR from Protected Branch
Symptom: Trying to create PR from main/master/develop
Fix: Create a feature branch first: git checkout -b feature/name
Failure Mode 2: Uncommitted Changes Included
Symptom: PR diff doesn't match expected changes Fix: Invoke commit skill first, then re-run create-pr
Failure Mode 3: Missing Breaking Changes
Symptom: Reviewer discovers undocumented breaking changes Fix: Edit PR body to add Breaking Changes section with migration steps
Failure Mode 4: Branch Not Pushed
Symptom: gh pr create fails with "branch not found on remote"
Fix: Run git push -u origin $(git branch --show-current) first
Failure Mode 5: Empty Test Plan
Symptom: Reviewers ask "how do I test this?" Fix: Add specific, actionable test scenarios with checkboxes
Quick Workflow Summary
STEP 1: GATHER BRANCH CONTEXT
├── git branch --show-current
├── git status --short
├── git log main..HEAD
├── git diff main...HEAD
└── Gate: Context collected
STEP 2: PRE-PR VALIDATION
├── Not on protected branch?
├── Uncommitted changes? → invoke commit
├── Has commits vs base?
└── Gate: Branch ready
STEP 3: ANALYZE ALL COMMITS
├── Read all commit messages
├── Read full diff
├── Classify: type, scope, size, risk
├── Detect breaking changes
└── Gate: PR classified
STEP 4: PRE-PR QUALITY CHECKS
├── Conflict markers?
├── Type errors?
├── Lint errors?
└── Gate: No blocking issues
STEP 5: GENERATE PR TITLE
├── type(scope): description
├── Under 72 chars
├── Breaking? Add !
└── Gate: Title ready
STEP 6: GENERATE PR BODY
├── Summary (3-5 bullets)
├── Changes (if M/L/XL)
├── Breaking Changes (if any)
├── Test Plan (always)
├── Notes (if deployment/config)
└── Gate: Body complete
STEP 7: PUSH BRANCH
├── git push -u origin <branch>
└── Gate: Branch on remote
STEP 8: CREATE PR VIA GH CLI
├── gh pr create with heredoc
├── Add flags: --draft, --reviewer, etc.
└── Gate: PR created
STEP 9: VERIFY AND REPORT
├── gh pr view
├── Report URL and details
└── Gate: PR verified
STEP 10: VERIFICATION
├── Check 1: PR exists
├── Check 2: Content quality
├── Check 3: Breaking changes documented
├── Check 4: Branch state
├── Check 5: PR state
└── Gate: All 5 checks pass
Completion Announcement
When PR is created, announce:
PR created.
**Quality Score: X/10**
- Context Gathering: X/2
- Validation: X/2
- Title Quality: X/2
- Body Quality: X/2
- Breaking Changes: X/2
**Pull Request:**
- PR #[number]: [title]
- URL: [url]
- Base: [base] <- [branch]
- State: [open/draft]
- Size: [S/M/L/XL] ([N] files, +[add] -[del])
**Verification:**
- PR exists: ✅
- Title format: ✅
- Test plan: ✅
- Breaking changes: [None/Documented]
- Branch synced: ✅
**Next steps:**
[Request reviewers, address CI, or wait for review]
Integration with Other Skills
The create-pr skill integrates with:
start— Usestartto identify if PR creation is appropriatecommit— Automatically invoked if uncommitted changes detectedgit-merge-expert-worktree— PRs can be created from worktree branches
Workflow Chain:
Work completed
│
▼
commit skill (if uncommitted changes)
│
▼
create-pr skill (this skill)
│
▼
Review cycle
Auto-Invoke Pattern:
When create-pr detects uncommitted changes via git status --short, it automatically invokes the commit skill first. The user doesn't need to manually run commit before PR creation.