| name | make-pr |
| description | Use when creating a PR description. Triggers include "PR 작성", "PR description", "make PR", "PR 만들어", "풀리퀘", "pull request 작성". |
Make-PR -- PR Description Writer
Write Korean PR descriptions from a senior backend engineer's perspective. Write so that core decisions can be fully understood from the PR alone without reading diffs, clearly separating "what changed" (Changes) from "what needs discussion" (Review Points).
"A good PR description makes review productive. A bad one makes review a guessing game."
<Critical_Constraints>
The Iron Law
NO PR DESCRIPTION WITHOUT SUFFICIENT CONTEXT
Never write a PR description without sufficient context. Continue the interview until ALL items in the Clearance Checklist are YES.
Violating the letter of this rule IS violating the spirit.
Non-Negotiable Rules
| Rule | Why Non-Negotiable | Common Excuse | Reality |
|---|
| Clearance Checklist all YES | Insufficient info leads to inaccurate PR | "I roughly get it, just write it" | Missing context leads to wrong PR |
| Write in Korean | Project convention | "English is easier" | Project rules take priority |
Never run gh pr create without user confirmation | PR creation requires explicit user approval | "Just create it directly" | Always confirm before creating PR |
| Never read git diff file contents for PR description writing | Use metadata only | "Need to see code for accuracy" | Use explore for patterns. User interview is key. Exception: conflict resolution in Step 0-C requires reading file contents to analyze and resolve conflicts |
| Never reference non-git content in PR | Reviewers can't access agent-internal files | "Memory/plan adds context" | PR is a public document; internal files are inaccessible to reviewers |
</Critical_Constraints>
Scope
Writes PR description body. Optionally assesses PR scope for multi-thesis splitting. Detects base branch via heuristic merge-base analysis, confirms target branch with user, performs target branch synchronization with conflict resolution at request start, then collects metadata → interview → assessment → description. Creates the PR via gh pr create after user approval.
When NOT to Use
- Purpose is code review (use code-review skill)
- Purpose is writing commit messages (use git-master skill)
Workflow
digraph make_pr_flow {
rankdir=TB;
"User Request" [shape=ellipse];
subgraph cluster_step0 {
label="Step 0: Base Branch Detection & Synchronization";
style=dashed;
"0-A: Fetch & Analyze\nAll Remote Branches" [shape=box];
"Present Candidate Table\n+ AskUserQuestion" [shape=box];
"Target Branch\nConfirmed" [shape=box];
"0-B: Check Diverge\n(behind count)" [shape=diamond];
"0-B: merge/rebase\nInterview + Execute" [shape=box];
"0-C: Conflict?" [shape=diamond];
"0-C: Per-file\nContext + Interview" [shape=box];
"More Conflicts?" [shape=diamond];
"Commit / Continue\nRebase" [shape=box];
"0-A: Fetch & Analyze\nAll Remote Branches" -> "Present Candidate Table\n+ AskUserQuestion";
"Present Candidate Table\n+ AskUserQuestion" -> "Target Branch\nConfirmed";
"Target Branch\nConfirmed" -> "0-B: Check Diverge\n(behind count)";
"0-B: Check Diverge\n(behind count)" -> "0-B: merge/rebase\nInterview + Execute" [label="behind > 0"];
"0-B: merge/rebase\nInterview + Execute" -> "0-C: Conflict?";
"0-C: Conflict?" -> "0-C: Per-file\nContext + Interview" [label="YES"];
"0-C: Conflict?" -> "Collect Git Metadata" [label="NO"];
"0-C: Per-file\nContext + Interview" -> "More Conflicts?";
"More Conflicts?" -> "0-C: Per-file\nContext + Interview" [label="YES"];
"More Conflicts?" -> "Commit / Continue\nRebase" [label="NO"];
}
"Collect Git Metadata" [shape=box];
"Explore Codebase Patterns" [shape=box];
"Interview Mode" [shape=box];
"Clearance Checklist" [shape=diamond];
"Scope Assessment" [shape=diamond];
"Split Proposal" [shape=box];
"Branch Separation" [shape=box];
"Sub-PR Loop\n(Step 6-8 per sub-PR\nincl. user confirmation)" [shape=box];
"Draft PR Description" [shape=box];
"Present to User" [shape=box];
"User Feedback" [shape=diamond];
"Confirm PR Creation" [shape=diamond];
"CAS Freshness\nCheck" [shape=diamond];
"gh pr create" [shape=box];
"Return PR URL" [shape=ellipse];
"Output Description Only" [shape=ellipse];
"User Request" -> "0-A: Fetch & Analyze\nAll Remote Branches";
"0-B: Check Diverge\n(behind count)" -> "Collect Git Metadata" [label="behind = 0"];
"Commit / Continue\nRebase" -> "Collect Git Metadata";
"Commit / Continue\nRebase" -> "0-C: Conflict?" [label="rebase:\nmore commits"];
"Collect Git Metadata" -> "Explore Codebase Patterns";
"Explore Codebase Patterns" -> "Interview Mode";
"Interview Mode" -> "Clearance Checklist";
"Clearance Checklist" -> "Interview Mode" [label="ANY NO"];
"Clearance Checklist" -> "Scope Assessment" [label="ALL YES"];
"Scope Assessment" -> "Draft PR Description" [label="Single thesis"];
"Scope Assessment" -> "Split Proposal" [label="Multi-thesis"];
"Split Proposal" -> "Branch Separation" [label="Accept"];
"Split Proposal" -> "Draft PR Description" [label="Reject"];
"Split Proposal" -> "Split Proposal" [label="Modify"];
"Branch Separation" -> "Sub-PR Loop\n(Step 6-8 per sub-PR\nincl. user confirmation)";
"Branch Separation" -> "Draft PR Description" [label="Fallback\n(conflict/mixed)"];
"Sub-PR Loop\n(Step 6-8 per sub-PR\nincl. user confirmation)" -> "Return PR URL";
"Draft PR Description" -> "Present to User";
"Present to User" -> "User Feedback";
"User Feedback" -> "Draft PR Description" [label="Revision requested"];
"User Feedback" -> "Confirm PR Creation" [label="Approved"];
"Confirm PR Creation" -> "Output Description Only" [label="Declined"];
"Confirm PR Creation" -> "CAS Freshness\nCheck" [label="Confirmed"];
"CAS Freshness\nCheck" -> "gh pr create" [label="Fresh"];
"CAS Re-sync\n(re-use or\nnew interview)" [shape=box];
"CAS Conflict\nResolution (→ 0-C)" [shape=box];
"CAS Freshness\nCheck" -> "CAS Re-sync\n(re-use or\nnew interview)" [label="Stale"];
"CAS Re-sync\n(re-use or\nnew interview)" -> "gh pr create" [label="sync complete"];
"CAS Re-sync\n(re-use or\nnew interview)" -> "CAS Conflict\nResolution (→ 0-C)" [label="conflict"];
"CAS Conflict\nResolution (→ 0-C)" -> "gh pr create";
"gh pr create" -> "Return PR URL";
}
Step 0: Base Branch Detection & Synchronization
Upon receiving a PR writing request, detect the target base branch via heuristic analysis, confirm with the user, and synchronize the current branch before collecting metadata.
Step 0-A: Base Branch Detection
Phase 1 — Fetch all remote state:
git fetch --all --prune
Phase 2 — Analyze all remote branches as candidates:
For every remote branch except the current branch's remote counterpart (origin/$(git branch --show-current)) and symbolic refs (origin/HEAD), compute merge-base distance:
MERGE_BASE=$(git merge-base HEAD origin/{branch} 2>/dev/null || true)
if [ -z "$MERGE_BASE" ]; then continue; fi
AHEAD=$(git rev-list --count $MERGE_BASE..HEAD)
BEHIND=$(git rev-list --count $MERGE_BASE..origin/{branch})
DIFF_STAT=$(git diff --stat $MERGE_BASE..HEAD | tail -1)
Phase 3 — Build candidate table:
Collect all candidates and present a table showing commits ahead/behind and change scale. Sort by AHEAD ascending (smallest diff from current branch = most likely true base):
| 후보 브랜치 | commits ahead | commits behind | 변경 규모 |
|----------------------|---------------|----------------|----------------------|
| sisyphus-myth-title | 1 | 0 | +53 -70 (8 files) |
| main | 17 | 0 | +1832 -1881 (17 files)|
Show the top 2-3 candidates. If more branches exist, include an "other" option.
Phase 4 — Confirm with user via AskUserQuestion:
Always ask even when the default branch is the only likely candidate — never auto-skip.
Present the candidate table, then ask the user to select the target branch. Include:
- Each top candidate as a labeled option
- An option to type a custom branch name if none of the candidates apply
Use the confirmed value as {base-branch} in all subsequent git commands.
Phase 5 — Record baseline target SHA:
After user confirms the target branch, record the target branch tip SHA as the CAS baseline for Step 8 freshness check:
BASELINE_TARGET_SHA=$(git rev-parse origin/{base-branch})
This value is compared again at PR creation time (Step 8) to detect if the target branch tip has moved during the PR writing process.
Step 0-B: Target Branch Synchronization
After the target branch is confirmed, check if the current branch has diverged:
git rev-list --left-right --count origin/{base-branch}...HEAD
If behind = 0: No synchronization needed. Proceed to Step 1.
If behind > 0: The current branch is behind origin/{base-branch}. Ask the user which strategy to use via AskUserQuestion:
- merge: 타겟 브랜치의 변경사항을 merge commit으로 통합합니다. 기존 히스토리가 보존됩니다.
- rebase: 현재 브랜치의 커밋을 타겟 브랜치 위로 재배치합니다. 선형적인 히스토리를 유지합니다.
Execute the chosen strategy:
git merge origin/{base-branch}
git rebase origin/{base-branch}
If the operation completes without conflict: Proceed to Step 1.
If conflict is detected: Proceed to Step 0-C.
Step 0-C: Conflict Resolution
When a merge or rebase operation encounters conflicts:
Phase 1 — Enumerate conflicted files:
git diff --name-only --diff-filter=U
Phase 2 — Resolve each file interactively:
For each conflicted file, repeat:
- Read the file contents and locate conflict markers (
<<<<<<<, =======, >>>>>>>).
- Analyze both sides:
- During merge:
HEAD side (ours) = current branch changes, incoming side (theirs) = target branch changes
- During rebase:
HEAD side (ours) = target branch changes (commit being rebased onto), incoming side (theirs) = current branch changes (commit being replayed)
- Explain the conflict in plain text to the user: what each side contains and what the conflict represents. Use the correct ours/theirs mapping for the current operation (merge vs rebase).
- Propose a resolution with reasoning.
- Ask the user to choose via AskUserQuestion:
- 제안대로 해결: Apply the proposed resolution
- 현재 브랜치 유지: Keep only the current branch's changes (merge: ours / rebase: theirs)
- 타겟 브랜치 채택: Keep only the target branch's changes (merge: theirs / rebase: ours)
- Apply the chosen resolution and stage the file:
git add {file}
Phase 3 — Finalize the operation:
After all conflicted files are resolved:
git commit --no-edit
git rebase --continue
Phase 4 — Check for additional conflicts:
If git rebase --continue triggers a new conflict (rebase replays commits one by one), return to Phase 1 and repeat for the new conflict set.
When all conflicts are resolved and the operation completes: Proceed to Step 1.
Step 1: Collect Git Metadata
After base branch detection and fetch, collect lightweight git metadata.
git log origin/{base-branch}..HEAD --oneline
git diff origin/{base-branch}..HEAD --stat
git log origin/{base-branch}..HEAD --format='%s%n%b'
Use this metadata as supplementary context for the interview. Use it to gauge the scope and scale of changes, but do NOT read actual file contents.
Step 2: Explore Codebase Patterns
Use the explore agent to understand codebase patterns and structure. For architecture-level changes (e.g., module restructuring, design pattern changes), additionally consult oracle for deeper analysis. Do NOT ask the user about the codebase.
Context Brokering (CRITICAL):
| Question Type | Ask User? | Action |
|---|
| "What's the project architecture?" | NO | Discover via explore |
| "Which files changed?" | NO | Check via git metadata |
| "What are the existing patterns?" | NO | Discover via explore |
| "What's the architectural impact?" | NO | Consult oracle |
| "What's the motivation for this change?" | YES | User interview |
| "What alternatives were considered?" | YES | User interview |
| "Anything you want to ask reviewers?" | YES | User interview |
Only ask the user about PREFERENCES and DECISIONS. Discover FACTS yourself.
Step 3: User Interview
Interview Rules
- One question at a time -- never bundle multiple questions
- Adaptive question count -- repeat until Clearance Checklist is all YES. Could be 1-2 if user provides enough upfront, or 5-6+ for complex changes
- AskUserQuestion = structured choices, plain text = open-ended questions
- Context Brokering -- if the codebase can answer it, use explore instead of asking
- No shortcut from prior sessions -- memory, plans, and previous session context do not replace the interview. Always start from git metadata + explore
Question Type Selection
| Situation | Method | Reason |
|---|
| Decision with 2-4 clear options | AskUserQuestion | Provide structured choices |
| Open/subjective question | plain text | Free-form answer needed |
| Yes/No confirmation | plain text | AskUserQuestion is overkill |
Question Quality Standard
BAD:
question: "What changed?"
GOOD:
question: "I see changes in OrderService and PaymentService from git log.
The commit messages suggest event-based decoupling.
Could you share the core motivation (e.g., removing domain coupling,
transaction separation, scalability)?"
Handling User Responses
Vague answers:
- Do not accept as-is
- Ask specific follow-up questions
- Repeat until clear
Explicit delegation ("figure it out", "pass", "you decide"):
- Investigate autonomously via explore/git metadata
- Decide based on industry best practices or codebase patterns
- Reflect the decision in the PR description
Bare-text reference (e.g., issue key, channel name):
- Ask once for the full URL/permalink so References can be rendered as a markdown link
- If the user has no URL, bare-text is acceptable as fallback
Step 4: Clearance Checklist (Interview Exit Condition)
Run after every interview turn. If ANY NO, continue the interview.
| # | Check | Must Be |
|---|
| 1 | Is the background/purpose clear enough to write Summary? | YES |
| 2 | Are the changes and their reasons clear enough to write Changes? | YES |
| 3 | Are enough technical decisions/concerns collected to write Review Points? | YES |
| 4 | Are acceptance criteria organized enough to write Checklist? | YES |
All YES -> Proceed to Step 5.
Any NO -> Continue interview. Do not proceed.
This checklist is internal -- do NOT show it to the user.
Step 5: Scope Assessment
After Clearance Checklist passes, analyze whether the PR contains multiple independent theses (behavioral changes) that should be separate PRs. Read references/scope-assessment.md now — it contains the complete multi-thesis split framework required for this step.
Quick summary:
- Identify candidate theses, then absorb exception-matching changes (campsite cleanup, minimal cross-domain) into their nearest main thesis
- Check proxy signals (commit type diversity, domain spread, LOC) as initial triggers
- Apply thesis isolation test: "Does this PR prove a single thesis?"
- If single thesis → proceed to Step 6
- If multi-thesis → propose split to user (Accept/Reject/Modify)
- On Accept → separate git branches, write sub-PR descriptions (Step 6-8 per sub-PR)
- On Reject → proceed to Step 6 as single PR
Data sources: git diff origin/{base-branch}..HEAD --stat, git log, explore results, interview answers. Never read git diff file contents.
Step 6: Write PR Title & Description
PR Title
- Include a PR title along with the description body
- Format: conventional commit style (
feat:, fix:, refactor:, etc.)
- Language: Korean
- Length: under 50 characters (excluding prefix)
- Example:
refactor: 주문-결제 간 이벤트 기반 아키텍처 전환
Writing Principles
- Write so fellow developers can quickly understand the changes
- Be concise and focused on essentials
- Separate "what changed" (Changes) from "what needs discussion" (Review Points)
- Proactively identify areas where reviewer feedback would help
- Base on provided documents and code; ask for confirmation if uncertain
Output Format
MUST read references/output-format.md before writing the PR body. It contains the definitive template (emoji headers, Impact Scope field, Review Points 5-part structure, Checklist format). Follow it exactly. Key requirements:
- Use emoji section headers:
📌 Summary, 🔧 Changes, 💬 Review Points, ✅ Checklist, 📎 References
- Each Changes subsection MUST include
**영향 범위** (Impact Scope)
- Each Checklist item MUST be a verifiable acceptance criterion in
- [ ] checkbox format, with the relevant file path indented below. Write true/false verifiable conditions, not file lists or feature descriptions.
- Review Points MUST use the 5-part structure: 배경 및 문제 상황 → 해결 방안 → 구현 세부사항 → 관련 코드 (optional) → 선택과 트레이드오프
Review Points Selection Criteria
- Core architecture decisions
- Trade-offs between competing concerns (performance vs readability, simplicity vs extensibility)
- Patterns/approaches where multiple valid alternatives exist
- Areas where a senior engineer's domain expertise would be valuable
- Implementation choices that deviate from common conventions
- Mixed strategies within the same flow (e.g., different lock mechanisms)
- Data modeling decisions affecting future extensibility
Each Review Point Structure
- 배경 및 문제 상황: Why it was needed, what problem existed
- 해결 방안: How it was solved (overview)
- 구현 세부사항: Detailed implementation explanation
- 관련 코드: (Optional) Useful for Before/After comparison
- 선택과 트레이드오프: Rationale for the choice, rejected alternatives, acknowledged trade-offs. Include open questions only when they naturally arise.
Step 7: User Review & Revision
Present the drafted PR description to the user and collect feedback.
- If approved: proceed to Step 8
- If revision requested: incorporate feedback and re-present
Step 8: PR Creation
After user approves the PR description, ask if they want to create the PR.
Pre-creation Freshness Check (CAS Pattern)
Before pushing and creating the PR, verify the target branch hasn't changed since Step 0-A:
git fetch origin {base-branch}
CURRENT_TARGET_SHA=$(git rev-parse origin/{base-branch})
Compare with baseline:
| Condition | Action |
|---|
CURRENT_TARGET_SHA == BASELINE_TARGET_SHA | Target unchanged — proceed to push + gh pr create |
CURRENT_TARGET_SHA != BASELINE_TARGET_SHA | Target has moved — re-sync before creating PR |
When target has moved:
- Inform the user that the target branch has new commits since the analysis began
- If a strategy was selected in Step 0-B: re-use it automatically (do NOT re-interview)
If Step 0-B was skipped (behind was 0): ask the user via AskUserQuestion which strategy to use (merge/rebase)
- Execute the sync (merge or rebase)
- If conflict arises: follow Step 0-C conflict resolution interview
- After successful sync: proceed to push +
gh pr create
- PR description is NOT re-written (the feature branch changes are the same; only the base has moved)
- If user confirms: push the branch and run
gh pr create with the approved title and description
- If user declines: output the final PR description only
For single PR (create after remote push):
git push --force-with-lease -u origin HEAD
git push -u origin HEAD
TITLE=$(cat <<'EOF'
PR title
EOF
)
gh pr create --base {base-branch} --head $(git branch --show-current) --title "$TITLE" --body "$(cat <<'EOF'
PR description body
EOF
)"
Sub-PR (Stacked split):
- Branch push already completed during Step 5 branch separation procedure
- First sub-PR:
--base {base-branch}
- Subsequent sub-PRs:
--base {previous-split-branch}
TITLE=$(cat <<'EOF'
PR title
EOF
)
gh pr create --base {appropriate-base} --head {target-sub-branch} --title "$TITLE" --body "$(cat <<'EOF'
PR description body
EOF
)"
Return the PR URL to the user after successful creation.
Examples
Read these to calibrate PR body style before writing:
examples/example-001.md: Event-driven architecture PR — domain decoupling, compensating transactions, layer responsibility separation
examples/example-002.md: Kafka event pipeline PR — Transactional Outbox Pattern, idempotency guarantees, multi-module setup
Step-by-step summary cheat-sheet: read references/reference-tables.md when you need a quick step summary.
Known failure-mode lookup: read references/reference-tables.md during self-review to check against documented failure modes.
Reference Files (on-demand)
| Reference file | What it contains | When to read |
|---|
references/scope-assessment.md | Multi-thesis PR split framework | Step 5 (scope assessment) |
references/output-format.md | Definitive PR body template: emoji headers, Impact Scope field, Review Points 5-part structure, Checklist format | Step 6 (write PR title & description) — read before writing |
references/reference-tables.md | Step-by-step summary cheat-sheet + known-failure-mode lookup | When you need a quick step summary or during self-review |
examples/example-001.md | Worked example: event-driven architecture PR (domain decoupling, compensating transactions, layer responsibility separation) | To calibrate PR body style before writing |
examples/example-002.md | Worked example: Kafka event pipeline PR (Transactional Outbox Pattern, idempotency guarantees, multi-module setup) | To calibrate PR body style before writing |
Language Rules
- Entire PR body in Korean
- Conversations with user also in Korean