make-pr
SkillDev toolsUse when creating a PR description. Triggers include "PR 작성", "PR description", "make PR", "PR 만들어", "풀리퀘", "pull request 작성".
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the make-pr skill
What this skill tells your AI
The instructions your AI receives, as published by toongri/oh-my-toong-playground in skills/make-pr/SKILL.md and read by ahel’s review.
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 body & conversation in Korean | Project convention | "English is easier" | Project rules take priority. Sole exception: PR title language follows the surveyed {title-convention} when one exists |
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, separating each sub-PR into its own worktree. Detects base branch via heuristic merge-base analysis, confirms the target, and requests later sync or conflict decisions only when their prerequisite state exists before collecting metadata + surveying repo PR conventions (title/branch/label) → interview → assessment → description. Creates the PR via gh pr create after user approval, assigned to the authenticated gh user, with labels per the surveyed convention.
When NOT to Use
- Purpose is code review (use code-review skill)
- Purpose is writing commit messages (use git-master skill)
Workflow
Discover facts before asking anything. Ask one user decision at a time, and ask only preferences or decisions; do not ask the user for facts you can determine. Run the target-branch setup, metadata discovery, interview, scope assessment, drafting, review, and explicit PR-creation approval in that order.
Interview contract: Ask one user decision at a time. Present detected target-branch evidence, then ask the user to confirm the target; never auto-select. Only after target confirmation, re-check divergence. If behind > 0, ask sync strategy before merge/rebase. If behind = 0, do not ask a sync question. Only if synchronization actually conflicts, obtain the conflict policy/decision before resolving. File-by-file mode asks one file decision at a time. Do not execute dependent actions before their required answer.
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:
# For each remote branch {branch}:
MERGE_BASE=$(git merge-base HEAD origin/{branch} 2>/dev/null || true)
if [ -z "$MERGE_BASE" ]; then continue; fi # Skip unrelated/orphan branches
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)|
Present the detected target-branch evidence, then ask the user to confirm the target; never auto-select. Do not add candidate-count or UI-option rules.
Phase 4 — Target confirmation:
After presenting the evidence table, ask only for the target branch confirmation. Only after the user confirms the target, re-check divergence. Ask sync strategy only when the confirmed target is behind; if behind = 0, do not ask a sync question. Ask conflict policy only if synchronization actually conflicts, before resolving it. Do not execute dependent actions before their required answer.
| # | header | question | options | Included when |
|---|---|---|---|---|
| 1 | 타겟 브랜치 | 이 PR의 base 브랜치는 어디인가 | Show the detected candidates and ahead/behind/change scale evidence for user confirmation | Always |
| 2 | 동기화 방식 | 타겟 브랜치가 앞서 있으면 그 커밋들을 어떻게 가져올까 | Explain the meaning and consequences of merge or rebase | Confirmed target is behind |
| 3 | 충돌 처리 | 동기화 중 충돌이 나면 어떻게 처리할까 | 파일별로 확인, 제안대로 자동 해결, 현재 브랜치 우선, 타겟 브랜치 우선 | Synchronization conflicts |
The confirmed {base-branch} is used in subsequent git commands. Collect each later decision only when its prerequisite state exists.
Step 0-B: Target Branch Synchronization
After target confirmation, re-check the confirmed target's actual divergence before executing:
git rev-list --left-right --count origin/{base-branch}...HEAD
# Output: {behind}\t{ahead}
If behind = 0: No synchronization needed. Proceed to Step 1.
If behind > 0: Ask the user for {sync-strategy} and wait for the answer before running merge or rebase. Do not ask a sync question when behind = 0. If synchronization actually conflicts, ask for {conflict-policy} and wait for that answer before resolving conflicts.
# merge
git merge origin/{base-branch}
# rebase
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 — Analyze every conflicted file in this round:
For each file in the list, first render the path as one shell-safe literal and bind it before any shell command. Use CONFLICT_FILE=<shell-word:file> (single-quote escaping as needed); after that binding, use only quoted variable expansions for the path:
CONFLICT_FILE=<shell-word:file>
git ls-files -u -- "$CONFLICT_FILE"
Stage 2 is ours and stage 3 is theirs. A missing stage is a deletion on that side, so do not assume that the worktree contains conflict markers (modify/delete and rename/delete conflicts may not). Read the present stage blobs (git show ":2:$CONFLICT_FILE" / git show ":3:$CONFLICT_FILE") when analyzing the two sides, then form a proposed resolution with reasoning. Use the correct ours/theirs mapping for the operation in progress:
- During merge:
HEADside (ours) = current branch changes, incoming side (theirs) = target branch changes - During rebase:
HEADside (ours) = target branch changes (commit being rebased onto), incoming side (theirs) = current branch changes (commit being replayed)
Phase 3 — Settle them per {conflict-policy}:
{conflict-policy} | How this round is settled |
|---|---|
| 파일별로 확인 | Explain one conflicted file at a time in plain text: what each side holds, what the conflict represents, the proposed resolution and its reasoning. Ask one file decision at a time, then resolve only that file. Each question offers 제안대로 해결 / 현재 브랜치 유지 (merge: ours / rebase: theirs) / 타겟 브랜치 채택 (merge: theirs / rebase: ours) |
| 제안대로 자동 해결 | Apply the Phase 2 proposal to every file, preserving whether it is a side selection, deletion, or synthesized/custom result |
| 현재 브랜치 우선 | Take the current branch's side in every file — merge selects ours (stage 2), rebase selects theirs (stage 3) |
| 타겟 브랜치 우선 | Take the target branch's side in every file — merge selects theirs (stage 3), rebase selects ours (stage 2) |
Phase 2 proposals may be an explicit side selection, a deletion, or a synthesized/custom result. For a deletion proposal, resolve it with git rm -- "$CONFLICT_FILE". For a synthesized/custom proposal, preserve the exact proposed content in the worktree, then stage it with git add -- "$CONFLICT_FILE". The stage checkout procedure below applies only to explicit current-branch/target-branch side choices. For those side choices, resolve the selected stage explicitly. If the selected stage is absent, resolve the deletion with git rm -- "$CONFLICT_FILE"; otherwise check out the selected side and stage it:
stages=$(git ls-files -u -- "$CONFLICT_FILE")
# selected_stage is 2 (ours) or 3 (theirs), according to the mapping above
if ! printf '%s\n' "$stages" | awk -v stage="$selected_stage" '$3 == stage { found=1 } END { exit !found }'; then
git rm -- "$CONFLICT_FILE"
else
git checkout --$selected_side -- "$CONFLICT_FILE"
git add -- "$CONFLICT_FILE"
fi
This stage inspection and missing-stage git rm rule also applies to file-by-file choices; never blindly run git checkout when the chosen side is a deletion.
Under the three non-interactive policies, report what was applied per file in plain text after the operation finishes, so the user can see the resolutions they did not individually approve.
Phase 4 — Finalize the operation:
After all conflicted files are resolved:
# If merge:
git commit --no-edit # creates the merge commit with default message
# If rebase:
git rebase --continue
Phase 5 — 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. {conflict-policy} is answered once and carries across every round — do not re-ask it.
When all conflicts are resolved and the operation completes: Proceed to Step 1.
Step 1: Collect Git Metadata & PR Conventions
After base branch detection and fetch, collect lightweight git metadata.
# Commit history
git log origin/{base-branch}..HEAD --oneline
# Changed file list
git diff origin/{base-branch}..HEAD --stat
# Commit messages and descriptions
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.
PR Convention Survey
Survey the repo's recent PRs to learn its title, branch-name, and label conventions. Run once per session, right after metadata collection:
# Recent PRs (10-30): title / branch / label conventions
gh pr list --state all --limit 30 --json number,title,labels,headRefName
# Labels that actually exist in the repo
gh label list --limit 100
From the survey, derive and record three values for later steps:
| Value | Derived from | What to extract |
|---|---|---|
{title-convention} | title field | Prefix style (conventional commit / gitmoji / bare), language, typical length |
{branch-convention} | headRefName field | Naming pattern (e.g., feat/*, fix/*, {user}/*, kebab-case topic) |
{label-convention} | labels field | Which labels are applied to which kinds of change (feature/fix/refactor/docs …) |
Convention exists only when a majority pattern does. An axis counts as having a convention only when BOTH hold: (1) at least 5 PRs were surveyed, and (2) strictly more than half of them share the pattern — an exact tie (e.g., 3-3 between two styles) means no convention. With fewer than 5 surveyed PRs, mark every axis "no convention" — a handful of PRs is not a convention. For any axis without a convention, use the fallback defaults (title: conventional commit style Korean, branch: keep current name, labels: none).
Every branch name this skill creates, renames, or proposes must use English words only. A surveyed branch convention may determine structure, but never overrides the English-only rule.
Never invent labels. Only labels present in gh label list output may ever be applied. If no existing label fits, apply none.
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. This rule applies globally; request each later decision only when its prerequisite state exists, and wait for the answer before dependent actions.
- 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 → create one git worktree per sub-PR (so each PR stays editable side by side once review starts), 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: follow
{title-convention}from the Step 1 PR Convention Survey — match the surveyed prefix style, language, and length - Title-language precedence: for the title only, the surveyed language wins over the Korean default (an English-titled repo gets an English title). The PR body and user conversation remain Korean regardless
- Fallback (no surveyed convention): conventional commit style (
feat:,fix:,refactor:, etc.), Korean, under 50 characters (excluding prefix) - Fallback example:
refactor: 주문-결제 간 이벤트 기반 아키텍처 전환 - Split sub-PR: the title carries its position in the series as a
(K/N)suffix after the convention-conforming title —feat: 주문 이벤트 스키마 정의 (1/3). The suffix sits at the end so the surveyed prefix style still leads
PR Labels
- Select labels per
{label-convention}from the Step 1 survey: pick the label(s) the repo applies to this kind of change - Only labels that exist in
gh label listoutput — never invent one; if none fits, apply none - Present the selected labels alongside the title and body in Step 7 so the user reviews them together
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 Check
Before pushing, verify the branch still holds commits that {base-branch} does not:
git fetch origin {base-branch}
AHEAD=$(git rev-list --count origin/{base-branch}..HEAD)
| Condition | Action |
|---|---|
AHEAD > 0 | Proceed to push + gh pr create |
AHEAD == 0 | The branch's commits already exist in {base-branch} — there is nothing to open a PR for. Tell the user and stop |
AHEAD is a property of the current branch, so this check is evaluated once and its answer does not change when the target branch receives new commits meanwhile. It is also the only precondition gh pr create needs: GitHub computes the merge server-side, so the branch does not have to be up to date with the target. Synchronizing the branch with the target is handled earlier, by the Step 0-B merge/rebase that runs before the interview.
- If user confirms: check branch name convention, push the branch, and run
gh pr createwith the approved title, description, assignee, and labels - If user declines: output the final PR description only
For a split sub-PR, resolve its branch → worktree mapping from Step 5 and bind the matching $WT_DIR before any ahead check, branch-name/convention check, remote lookup, rename, or push. If the mapping is missing, stop and ask the user; never infer a worktree path. Never interpolate a raw branch/ref placeholder into shell source: render each external value as one shell-safe literal into a variable, validate branch refs with git check-ref-format --branch when created or renamed, and use only quoted variable expansions. A branch such as feat;id, $() or backticks remains data. Run those operations from the bound $WT_DIR, then create the PR with the mapped branch. This binding rule applies only to split sub-PRs; single-PR Step 8 keeps the flow below unchanged.
Branch Name Convention Check (before push)
If {branch-convention} exists (Step 1 survey) and the current branch name does not match it:
- Skip when the branch already exists on origin (
git ls-remote --heads origin {current-branch}non-empty) — renaming a pushed branch orphans the remote copy - Otherwise propose a convention-conforming name via AskUserQuestion:
- {proposed-name}으로 변경:
git branch -m {proposed-name}then push under the new name - 현재 이름 유지: push as-is
- {proposed-name}으로 변경:
For single PR (create after remote push):
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 25
- Forks
- 1
- Last commit
- Sep 2026
ahel review
K4blow
destructive-scoped (in references/scope-assessment.md)K4blow
destructive-scoped (in tests/test-scenarios.md)
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Catalog kind
- skill
- Gateway key
make-pr-toongri- Source
- github.com/toongri/oh-my-toong-playground