description: PR 리뷰 코멘트를 분석하여 수용/반론을 판단하고, 결정 근거를 스레드에 남깁니다. user-invocable: true
Triage Review Comments — PR 리뷰 코멘트 트리아지
PR에 달린 리뷰 코멘트를 하나씩 검토하여, 수용할지 반론할지 판단한다. 맹목적 수용도, 맹목적 무시도 하지 않는다.
전제: 리뷰 코멘트는 사용자(또는 동료 리뷰어)가 본 PR에 보낸 지시·요청 그 자체다. 코멘트를 받고 "이걸 어떻게 할지 사용자에게 다시 물어볼까?"는 회피 루프 — 코멘트 자체가 이미 결정 질의이므로 본 스킬은 자체 판단으로 수용/반론을 결정하고 자동 실행한다. 사용자에게 코멘트 처리 방향을 다시 묻지 않는다.
실행 방법
- PR 번호를 인자로 받거나, 현재 브랜치의 PR을 자동 탐지한다.
collect_comments.sh로 3채널 미처리 코멘트를 수집한다.- 각 코멘트에 대해 판단 루프를 실행한다.
- 결과를 사용자에게 보고하고, 승인 후 실행한다.
코멘트 수집
monitor-pr의 collect_comments.sh를 사용하여 미처리 코멘트를 수집한다:
REPO=E5presso/spakky-framework PR_NUMBER={N} bash {MONITOR_PR_SKILL_DIR}/scripts/collect_comments.sh
{MONITOR_PR_SKILL_DIR}은monitor-pr스킬 디렉토리 경로. 동일.agents/skills/하위이므로 상대 경로로$(dirname {SKILL_DIR})/monitor-pr로 접근.
2채널 구조
| 채널 | 소스 | 설명 |
|---|---|---|
| CH1 | 인라인 리뷰 코멘트 (pulls/comments REST) |
in_reply_to_id 추적으로 내가 reply하지 않은 코멘트 |
| CH2 | 일반 PR 코멘트 (issues/comments REST) |
내가 응답하지 않은 코멘트 |
TOTAL == 0이면 처리할 코멘트가 없으므로 즉시 종료한다.
판단 루프 (코멘트 1건당)
Step 1: 지적 이해
- 코멘트가 가리키는 코드를 읽는다.
- 지적의 핵심을 한 문장으로 요약한다.
Step 2: 타당성 검증
다음 질문을 순서대로 확인한다:
| # | 질문 | No이면 |
|---|---|---|
| 1 | 지적이 사실에 기반하는가? (코드를 잘못 읽은 건 아닌가) | 반론: 사실 오류 지적 |
| 2 | 이 코드에 실제 소비자(caller)가 있는가? | Step 3 YAGNI 역설 검사 후 결과에 따라 수용/반론 |
| 3 | 제안된 변경이 문제를 실제로 해결하는가? | 반론: 근본 원인 불일치 |
| 4 | 변경의 범위가 현재 이슈 스코프 안에 있는가? | 반론: 스코프 초과, 별도 이슈로 분리 (Step 4 처리) |
| 5 | 변경 후 더 나은 상태가 되는가? (이름, 시그니처, 동작) | 수용 |
모든 질문에 Yes이면 → 수용. 하나라도 No이면 → 해당 근거로 반론 (단 #2는 Step 3 결과를 따름, #4는 Step 4 처리).
Step 3: YAGNI 역설 검사 (Step 2 #2가 No일 때 필수)
"caller 없음 → YAGNI 반론"으로 즉시 흐르지 않는다. review-heuristics.md 원칙 5(YAGNI 역설)에 따라 다음을 모두 확인한 뒤 판정:
- 소비자 추적: 코드베이스에서 해당 심볼을 호출하는 곳을
Grep. GitHub Issue 백로그에서 해당 심볼을 사용할 이슈를 검색. - 도메인 완전성 검사: 해당 심볼이 도메인 모델·계약·기본 상태 필드의 완성도를 구성하는가? (예: AggregateRoot의 기본 상태 필드, Port의 기본 메서드 세트, DTO의 도메인 식별자 필드.) 도메인 완전성에 필요하면 caller 부재로 빼지 않는다.
- 구조적 일관성 검사: 같은 카테고리의 다른 심볼(형제 Port·형제 Aggregate·형제 UseCase)이 동일한 메서드/필드를 가지는가? 일관성을 깨고 빠지면 향후 호출자가 자연스럽게 도달하지 못한다.
- 도메인상 복수 caller 자명성: 코드베이스에 caller가 없어도 도메인 분해상 caller가 자명하게 예정되어 있는가? (예: 마일스톤 description의 후속 Wave가 명시 호출하기로 약속한 심볼.)
판정:
- (2)·(3)·(4) 중 하나라도 Yes → 수용 또는 현행 유지 (caller 부재만으로 YAGNI 반론 금지). 단순 "있어야 한다" 직감만으로 정당화 금지 — 어느 항목이 충족되는지 근거를 스레드에 명시.
- (2)·(3)·(4) 모두 No이면서 caller도 없음 → YAGNI 반론 (정당). 반론 본문에 검사 결과 4줄 포함.
Step 4: 스코프 초과 처리 (Step 2 #4가 No일 때)
"별도 이슈로 분리"로 답하는 경우 즉시 본 SKILL의 "후속 이슈 생성" 절차로 진입한다 — 이슈 생성·blocker 설정·처리 약속까지 끝나기 전에는 PR 스레드에 답변하지 않는다. "후속 이슈로 분리하겠습니다"만 남기고 종결하면 그 이슈은 유기된다.
실행
수용하는 경우
- 코드를 수정한다.
- PR 스레드에 수용 근거를 남긴다.
- "수용합니다. [한 줄 이유]"
- 커밋 & push한다.
반론하는 경우
- 코드를 수정하지 않는다.
- PR 스레드에 반론 근거를 남긴다.
- 판단 루프에서 No가 된 질문과 구체적 근거를 포함한다.
- 대안이 있으면 제시한다 (예: "소비자가 확정되면 그때 시그니처를 결정")
- 사용자에게 반론 내용을 보고한다.
후속 이슈 생성이 필요한 경우 (스코프 초과 / 제거 약속 / 이관 약속)
스코프를 벗어난 작업을 후속 이슈으로 분리한다고 답했다면, 응답 전에 반드시 이슈를 실제로 생성·의존 설정·처리 약속까지 완료한다. 스레드에 "후속 이슈를 만들겠다"·"후속 이슈 #N을 만들었습니다"로만 응답하면 그 이슈은 유기된다 — behavioral-guidelines.md "감지된 스펙 이슈는 /plan-issues로 후속 이슈 + 같은 세션의 서브에이전트로 즉시 분해 개시. 다음 세션 위임 금지" 정합 강제.
/plan-issues또는gh issue edit 또는 GitHub connector 갱신로 이슈 생성.- 의존 관계(
blockedBy) 필수 설정 — 규칙 전체는.agents/rules/behavioral-guidelines.md"후속 이슈 생성 시 의존 관계(blockedBy) 필수 설정" SSOT. - 생성 후
gh issue view 또는 GitHub connector 조회로relations.blockedBy를 재확인. - 처리 자동 개시 (필수) — 이슈를 만들기만 하고 끝내지 않는다. 사용자 confirm 질의 자체가 또 다른 유기 경로이므로 묻지 않는다. 본 세션 컨텍스트에서 자동 실행:
- 기본 동작: 본 세션 내 서브에이전트로
/process-ticket {신규-ISSUE-NUMBER}를 백그라운드로 즉시 실행. PR 머지를 차단하지 않으며 별도 워크트리에서 병행. 이게 default —behavioral-guidelines.md"감지된 스펙 이슈는 후속 이슈 + 같은 세션의 서브에이전트로 즉시 분해 개시" 정합. - 즉시 분해가 컨텍스트상 무의미한 경우만(예: blocker가 진행 중이거나 새 이슈이 현재 PR과 동일 파일을 수정하여 머지 충돌이 예상될 때) 반드시
/schedule스킬(durable remote routine)로 자동 처리 routine을 즉시 등록(기본 cadence: 본 PR 머지 예상 시점 + 1 working day, KST 09시대). cadence 결정도 사용자에게 묻지 않고 디폴트 적용. - 휘발성 스케줄러 사용 절대 금지 —
.agents/rules/behavioral-guidelines.md"후속 이슈 자동 실행 default" SSOT. 유일 허용 경로는/scheduledurable remote routine — routine ID는trig_...접두어, 다른 식별자는 휘발성 신호. - 어느 경로든 PR 스레드 응답에 "처리 경로: {즉시 분해 / scheduled} — {agent ID 또는 routine ID(
trig_...)}"를 명시한다.
- 기본 동작: 본 세션 내 서브에이전트로
- PR 스레드에 (a) 이슈 URL, (b) 설정된 blocker 목록, (c) 자동 개시된 처리 경로(agent/routine ID) 세 가지를 함께 보고한다. 셋 중 하나라도 누락되면 reply 금지.
보고 형식
## 리뷰 코멘트 트리아지 결과
### 수용 (N건)
- [파일:라인] 요약 — 수용 이유
### 반론 (N건)
- [파일:라인] 요약 — 반론 근거 (판단 루프 #N: 이유)
"보류" 카테고리는 두지 않는다 — 코멘트 1건당 반드시 수용 또는 반론으로 결정한다. 1차 검토에서 결정 못 한 경우 (a) 코멘트 본문 재독 + 코드 추가 grep + GitHub 백로그 추가 검색을 1회 더 시도하고, (b) 그래도 결정 단서가 부족하면 default = 수용 (코멘트 작성자의 지시 방향을 신뢰). 보수적 수용이 잘못된 결정으로 판명되면 후속 PR에서 되돌린다.
규칙
- 코멘트에 답변할 때 감정적 표현을 쓰지 않는다. 근거와 사실만 기술한다.
- "틀렸습니다"가 아니라 "검토 결과 현행 유지로 판단했습니다. 근거:" 형식을 쓴다.
- 수용이든 반론이든, 판단 과정을 스레드에 투명하게 남긴다.
- 사용자 confirm 질의 금지 — 코멘트 처리 방향은 본 스킬이 자체 판단으로 결정한다. "이 코멘트 어떻게 할까요?" 형태의 사용자 질문 금지. 재시도 후에도 결정 못 하면 위 "default = 수용" 규칙 적용.
- 에이전트 reply 마커 필수: 모든 reply 본문 끝에
<!-- claude-agent-reply to=<id> -->를 포함한다 (<id>는 응답 대상 코멘트/리뷰의 숫자 GitHub ID). collect_comments.sh가 이 태그를 기반으로 "처리된 ID 집합"을 구성하므로 id 누락 시 대상 매칭 실패로 원본 코멘트가 미처리 상태로 남는다. 상세 포맷과 채널별 예시는monitor-pr/SKILL.md"에이전트 reply 마커" 참조.