Use when creating or merging a pull request in this project — PR 본문 작성, 브랜치 구성, 머지·머지 후 정리 시점. 본문 서사(문제→접근), rebase 머지 원칙, 머지 후 브랜치 정리(워크트리 베이스 브랜치 복귀 포함), 머지 후 하네스 신호 보고를 다룬다. Triggers on "PR 올리자", "PR 만들어", "머지하자", "브랜치 정리해". Does NOT trigger on PR 코드 리뷰 수행(review 스킬 또는 유저 직접), 커밋 메시지 작성(commit 스킬), 이슈 작성(issue 스킬).
Scanned 9/22/2026
Install to Claude Code
npx -y skills add sudopark/TodoCalendar --skill pr --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Pr?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/sudopark-todocalendar)More formats (shields.io, HTML) on the badges page.
---
name: pr
description: Use when creating or merging a pull request in this project — PR 본문 작성, 브랜치 구성, 머지·머지 후 정리 시점. 본문 서사(문제→접근), rebase 머지 원칙, 머지 후 브랜치 정리(워크트리 베이스 브랜치 복귀 포함), 머지 후 하네스 신호 보고를 다룬다. Triggers on "PR 올리자", "PR 만들어", "머지하자", "브랜치 정리해". Does NOT trigger on PR 코드 리뷰 수행(review 스킬 또는 유저 직접), 커밋 메시지 작성(commit 스킬), 이슈 작성(issue 스킬).
---
# PR — 생성·머지·정리
## 단계
이 스킬은 **PR 생성**과 **머지·정리** 두 단계로 나뉘고, 각각 별도 지시로 발동한다. 발동 지시가 커버하는 단계까지 수행하면 완료다 — 생성만 하고 끝난 런은 이탈이 아니다.
## 브랜치·올리기 전
- 브랜치명 `features/<이슈번호>-<슬러그>` (`feature/` 아님). develop에서 분기. 대응 이슈가 없는 작업(하네스 정비 등)은 이슈번호 없이 슬러그만.
- 페이즈가 나뉘는 작업은 페이즈별 PR — 머지 후 다음 페이즈 착수.
- WIP 정리는 PR 올리기 전에 (commit 스킬의 흡수 절차) — 리뷰어에게 보이는 커밋은 논리 단위 최종본이어야 한다.
### 구독 보관함 검토 (필수)
프로덕션에 `Set<AnyCancellable>` 이 남지 않았는지 본다 — 검증 명령과 배경은 `.claude/rules/swift-style.md` §6 `검증`. 출력이 비어야 통과다.
### 주석 검토 (필수)
PR 생성 **전에** 이번 브랜치가 추가한 주석을 훑는다:
```bash
python3 .claude/scripts/check-comments.py
```
- 지적된 건의 처분은 셋이고, **이 순서로 본다**:
1. **삭제** — 이름·코드가 이미 말하고 있으면 지운다. 기본값이다.
2. **구조 수정** — 그 주석이 없으면 안 읽힐 것 같으면, 주석을 다듬지 말고 **그 코드를 고친다.** 한 메서드가 결정을 여럿 이고 있다는 신호라, 함수를 쪼개거나 이름에 처리 케이스를 박으면 주석이 필요 없어진다. **스크립트가 낸 "주석이 몰린 구간"은 대개 이 처분이다** — 낱개로는 평범한 한 줄들이 한 메서드에 몰린 것이라 고칠 대상은 주석이 아니라 그 메서드다.
3. **남기기** — 앞의 둘이 다 안 되는 건만. 그 주석 없이는 복원 불가능한 정보(플랫폼 함정·순서 의존·fail-closed 의도·매직넘버 근거)여야 하고, 남긴 건과 그 이유를 유저에게 한 줄로 보고한다.
- **판단을 미루고 그대로 올리지 않는다.** 남기기를 기본 탈출구로 쓰면 이 검토는 통과 의례가 된다 — PR #1143 에서 스크립트가 낸 한 건이 남기기로 통과했고, 유저 리뷰에서 "주석 적을 생각하지 말고 로직을 리팩토링해"로 되돌아왔다.
- 스크립트는 검토 목록만 낸다 — 종료코드로 막지 않으니 출력이 비어야 통과가 아니라, **본 뒤 판단해야 통과다.**
- 지적이 반복되는 유형이 보이면 그건 작성 습관 문제다. `.claude/rules/swift-style.md`의 주석 조항을 다시 읽고 다음 작업에 반영한다.
배경: #820에서 AI 작업으로 유입된 서술형 주석 354줄을 걷어냈다. 사후 일괄 정리는 비용이 크니 유입 시점에 막는다.
### 문장 검토 (필수)
이번 브랜치의 커밋 메시지와 추가된 문서 줄에서 고정 표현을 훑는다 (CLAUDE.md §1 글 규범):
```bash
{ git log --format='%B' origin/develop..HEAD; \
git diff origin/develop...HEAD -- '*.md' ':!CLAUDE.md' ':!.claude/agents' ':!.claude/skills/pr/SKILL.md' | grep '^+'; } \
| grep -nE '의 경우|에 있어|함으로써|에 의해|되어지다|를 가능하게|에 대해 고려|(^|[^가-힣])이는[ ,.]|이를 통해|매우 중요한'
```
- 걸린 건 **기본이 수정이다.** 인용문 안이거나 그 표현 자체를 논하는 자리면 남기고, 남긴 건과 이유를 유저에게 한 줄로 보고한다.
- **정의 파일 셋(`CLAUDE.md`·`.claude/agents`·이 파일)은 제외했다** — 금지 표현을 예시로 싣고 있어 매번 자기참조로 걸린다. 그 셋을 고치는 PR 이면 해당 diff 를 눈으로 훑는다.
- **위치·반복 조건이 걸린 항목은 패턴에서 뺐다.** "따라서·또한·하지만·결과적으로" 는 문두에서 잇달아 쓸 때만 금지라 문자열 매칭으로 판정할 수 없고, "필수적인" 은 기술 문서의 정상 용법과 과장 용법을 가를 기준이 조항에 없다. 둘 다 눈으로 본다.
- **이 grep 은 규범의 일부만 덮는다.** 비문·무생물 주어·명사화·훈계형 마무리는 고정 문자열이 아니라 안 걸린다 — PR 본문을 쓴 뒤 소리 내 읽어 직접 확인한다. 출력이 비어야 통과가 아니라, **본 뒤 판단해야 통과다.**
### static 검토 (필수)
같은 시점에 이번 브랜치가 추가한 `static`을 훑는다:
```bash
git diff origin/develop...HEAD -- '*.swift' | grep -n '^+.*static '
```
- `static func`는 금지다 (CLAUDE.md §1). 각 건이 `.claude/rules/swift-style.md` §3 예외(프로토콜·프레임워크 요구사항, 전역 설정값 정본)에 해당하는지 확인하고, 아니면 인스턴스 소속으로 옮긴 뒤 PR을 올린다. case 없는 enum으로 감싼 형태도 같은 금지 대상이다.
- `static let`은 swift-style §1(`private enum Constant` 응집) 기준으로 본다. 그 밖의 `static`(`static var` 등)은 §1·§2가 규정하는 대상이 아니라 §3 예외(프로토콜·프레임워크 요구사항 — AppIntents `static let title` 류, 전역 설정값 정본) 해당 여부만 확인하고 넘어간다.
- 남긴 건과 그 근거 조항을 유저에게 한 줄로 보고한다. 주석 검토와 같이 **본 뒤 판단해야 통과다.**
## 본문
**기준: 보는 사람이 코드를 까보기 전에 본문만으로 내용을 파악할 수 있어야 한다.**
- 여러 커밋을 엮은 전체 작업의 서사: **문제 → 접근**. 개별 커밋은 그 서사의 단위. 파일 목록 나열 금지.
- "남은 과제"는 이번 PR에서 **의도적으로 뺀 게 실제로 있을 때만** 쓴다. 이슈·선행 PR에 이미 적힌 내용을 옮겨 적지 않는다 — 빈 섹션은 군더더기다.
- implement 완료 판정에서 승계된 **유저 검증 대기** 항목이 있으면 본문에 싣는다 (implement §완료 판정 4) — 검증 인계의 영속 자리가 PR 본문이라, 여기서 빠지면 기록이 사라진다.
- **폐기한 안·검토 경위·시행착오는 적지 않는다.** 본문은 최종 결과의 서사다 — "안 한 것" 같은 섹션으로 우회하지 않는다.
### 종결보고 배선 — 작전명령이 있는 런
작전명령(`docs/operations/<이슈>/opord.md`)이 있는 작업의 PR 은 종결보고(`docs/operations/templates/report-debrief.md`)가 본문의 골격이다:
- **1(최종상태 대조)·3(알려진 한계)·10(리뷰어 체크리스트)** 을 본문 섹션으로 싣는다. **2(산출물·검증)** 는 위 서사(문제→접근)와 "유저 검증 대기" 승계 항목에 흡수한다 — 별도 섹션으로 중복하지 않는다.
- **전문**은 `report-debrief.md` 머리 게시 줄대로 봇 코멘트(`mcp__github-reviewer__add_issue_comment`)로 이슈에 `<!-- debrief -->` 게시하고 `@sudopark` 를 멘션한다(리뷰 대기). 4(잔여 위험)·5(가정 검증)·9(상위 계획 피드백)의 campaign.md 반영은 L 의 DP 일 때만 — campaign 평가 모드를 호출한다. 8(하네스 갭)은 사이즈 무관 doctrine 소관이다(implement Rules 갭 보고 루프가 doctrine 으로 넘긴다) — campaign.md 반영 대상이 아니다.
- PR 생성 시 진행 파일(`.operations/<이슈>/progress.md`)의 `명령 상태:` 를 `검토` 로 올리고 이슈 본문 미러를 재조립한다 (opord §6·§7 — 종결은 머지다. 머지 전엔 리뷰로 방향·계획이 바뀔 수 있고, 리뷰 반영이 본문 층을 바꾸면 부록 D 단편명령으로 누적한다).
- 작전명령 없는 런(S·하네스 정비)은 종결보고를 만들지 않는다 — 위 본문 규정만 따른다. 단 **진행 파일 상태 전이는 같다** — 킥오프 씨앗이 있으면 PR 생성 시 `명령 상태:` 를 `검토` 로 올리고 board-sync 를 짝으로 부른다 (미러 재조립은 없다 — 본문 층이 없다). 안 올리면 상황판이 리뷰 대기 내내 `정찰` 로 보인다.
## 보드
PR을 올리면 대응 이슈를 개발 대시보드(Project #2)의 `Review + QA`로 옮긴다:
```bash
.claude/scripts/project-board.sh <이슈번호> "Review + QA"
```
- **대응 이슈가 없는 PR(하네스 정비 등)은 보드에 올리지 않는다** — PR 자체를 아이템으로 넣지 않는다.
- 머지 후 `Done` 이동은 머지·정리 단계가 수행한다 (아래).
- 배선이 실패해도 PR 작업은 계속한다. 실패 사실만 유저에게 한 줄로 알린다.
리뷰 수행은 이 스킬 밖이다 — 공개된 PR에 대해 유저가 지시할 때만 review 스킬로 (유저 직접 리뷰도 가능).
## 머지·정리
- 머지는 `gh pr merge --rebase`, squash 금지 — 단계별 커밋이 develop에 보존돼야 회귀 분석 시 변경 의도를 추적할 수 있다.
- **머지 직후 종결 처리를 수행한다** — 대응 이슈 클로즈(한 줄 코멘트: 해소한 PR# — issue 스킬 규정), 보드 `Done` 이동(`.claude/scripts/project-board.sh <이슈번호> "Done"`), 진행 파일 `명령 상태:` 를 `종결` 로 전이 + 미러(작전명령 있는 런만)·board-sync (opord §6 — 머지까지가 명령 달성이다). 상위 계획이 있으면(L 의 DP) campaign 원장 규칙(§5)대로 원장(`머지`)·상위 이슈 미러를 갱신하고 — 국면 확정은 §4 말미 조건(종료 조건이 머지를 요구하는 단계만 재대조)대로, §4 평가 모드 재실행 아님 —, 단독 M·S 는 상위 이슈가 있을 때만 진행 코멘트 한 줄. 이 처리 누락이 2026-09-06 correction 2건의 원인이었다 — 머지 보고 전에 수행한다.
- **머지된 작업의 산출물이 그 작업의 base 브랜치에서 되돌려진 걸 확인하면** 그 작업을 `회귀` 로 내린다 — revert PR 을 머지했든 핫픽스가 직행했든, base 가 develop 이든 앞 DP 브랜치든, 되돌림을 확인한 세션이 그 자리에서 한다. 아래는 DP 인 경우고, 상위 계획 없는 단독 M·S 는 말미 단서로 간다. 원장(campaign §5)의 해당 DP 행을 `회귀` 로 갱신하고, 상위 이슈 미러를 재조립하고, `campaign-board-sync.sh <상위이슈>` 를 짝으로 부른다. **그리고 즉시보고(`report-immediate.md`)를 상위 이슈에 봇 코멘트로 게시하고 `@sudopark` 를 멘션한다** — campaign.md 17항이 이걸 상시 즉시보고 조건으로 세웠고, 게시를 빠뜨리면 되돌림이 GitHub 어디에도 안 남아 유저가 모르고 지나간다. 게시 직후 campaign 평가 모드(§4 말미 회귀 접수)를 호출한다 — 후속 DP 재판정·계획 개정·이슈 재오픈이 거기 있고, 여기서 멈추면 원장만 `회귀` 인 채 이슈는 닫히고 보드는 `Done` 으로 남아 셋이 어긋난다. 상위 계획이 없는 단독 M·S 는 원장이 없으니 진행 파일 `명령 상태:` 를 `실행` 으로 되돌리고 board-sync 만 부른다.
- 머지 후 브랜치(로컬·리모트) 정리 여부를 유저에게 확인한다. 확인을 요청한 시점이 이 조항의 이행이다 — 답변 대기로 끝나도 이탈이 아니다.
- **작업 브랜치를 지우기 전에, 그 브랜치가 체크아웃된 워크트리를 자기 베이스 브랜치로 되돌린다.** 체크아웃 중인 브랜치는 삭제가 거부되기 때문이다. 임시 브랜치(`tmp/...`·`wip/...`)를 만들어 피하지 않는다 — 그 우회는 정리될 주인이 없는 브랜치를 매번 하나씩 남긴다.
- 워크트리마다 develop 을 미러링하는 **상시 베이스 브랜치**가 있다 — 메인 워크트리는 `develop`, 서브 워크트리는 `base/<워크트리명>` (`base/orthodox`·`base/southpaw`·`base/spare`).
- 메인 워크트리: `git switch develop && git pull origin develop`
- 서브 워크트리: 베이스를 최신 develop 에 맞춘 뒤 거기로 이동한다. **얹힌 커밋 확인이 리셋보다 먼저다** — `switch -C` 가 돌고 나면 베이스가 origin/develop 과 같아져 사후 확인은 항상 0건으로 나온다.
```bash
git -C <워크트리경로> fetch origin develop
git -C <워크트리경로> log --oneline origin/develop..base/<워크트리명> # 커밋이 잡히면 아래를 실행하지 말고 유저에게 보고한다
git -C <워크트리경로> switch --no-track -C base/<워크트리명> origin/develop
```
`--no-track -C` 는 upstream 을 달지 않고 베이스를 origin/develop 으로 리셋한다 — upstream 이 develop 이면 베이스에서 실수로 push 했을 때 develop 에 바로 꽂힌다.
- 그 다음 작업 브랜치를 지운다 — **PR 이 머지된 걸 확인한 뒤** 로컬 `git branch -D <브랜치>`, 리모트 `git push origin --delete <브랜치>`. rebase 머지는 커밋을 새 SHA 로 재작성해 얹어서 로컬 브랜치가 develop 의 조상이 아니다 — `-d` 는 `not fully merged` 로 거부된다. 머지 확인을 건너뛰고 `-D` 를 쓰면 머지 안 된 작업을 지운다.
- 머지 후 신호 판정 (#690 flywheel):
```bash
gh issue list --label harness --state open --json body --jq '.[].body' > /tmp/harness-open.md
python3 .claude/scripts/triage-usage.py --recorded-file /tmp/harness-open.md
```
- **판정은 스크립트가 한다 — 추론으로 다시 하지 않는다.** duplicate(이미 누적 이슈에 적힘)·stale(대상 조항이 그 신호보다 나중에 개정됨 = 정비는 됐고 소비 마킹만 안 됨)·actionable 셋으로 갈린다. 판정을 세션마다 추론으로 하면 같은 신호가 런마다 다르게 읽힌다.
- **무출력이면 아무 말도 하지 않는다.** "신호 없음"도 보고하지 않는다 — 보고할 게 없다는 뜻이지 언급할 자리가 아니다.
- **stale 블록이 나오면 출력된 마킹 명령을 그대로 실행한다.** 유저 보고 대상이 아니다. 이 정리를 건너뛰면 이미 정비된 신호를 다음 런이 또 판단한다.
- **actionable 만 유저에게 보고한다.** 기여 레코드(ts·요지)가 함께 출력되니 그 데이터로 보고한다 — 기억으로 재구성하지 않는다.
- 유저가 **"기록해"** 라고 지시하면 improve-skill §5(누적 이슈 기록)로 간다. 정비를 지시하면 improve-skill §1~4로 간다. 신호마다 이슈를 새로 따지 않는다.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!