원클릭으로
investigate
버그/이슈의 근본 원인을 4단계 구조화 프로세스로 분석하는 스킬. "근본 원인 없이 수정 금지" 철칙. 증상→분석→가설→검증→수정 순서를 강제.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
버그/이슈의 근본 원인을 4단계 구조화 프로세스로 분석하는 스킬. "근본 원인 없이 수정 금지" 철칙. 증상→분석→가설→검증→수정 순서를 강제.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Multi-worker 검수 스킬 (Codex + Gemini Double / Opus + Codex + Gemini Triple). 단일 Codex 검수 대비 100% 보완 카테고리 커버. 트리거: /cr-multi, /cr-double, /cr-triple, plan/spec 저장 후 자동(CR_MULTI_AUTO=on), plateau 3회 자동 승격.
Planner-Generator-Evaluator 하네스. Planner+Generator는 메인 컨텍스트에서 직접 실행하고, Evaluator만 subagent로 격리하여 독립 검수를 보장한다. spec 없는 개발 전용 하네스 — 버그 수정은 `/forge-fix` 사용.
QA 하네스 부트스트랩 스킬 (AD-92 Phase 0 + P0-FIX). /qa 실행 전 자동 호출되어 서버 생명주기 관리, qa-config.json 생성, DB seed 격리, API 전수 발견, scenarios.md 게이트를 준비한다. 트리거: /qa 실행 시 Phase 0 자동 진입, 또는 QA 환경 세팅, 서버 기동 후 테스트, scenarios.md 생성 요청 시.
루프 설계 마법사 + scaffold. "자동으로 실행되게 해줘", "반복 작업 에이전트 만들어줘", "루프 짜줘" 등 루프 자동화 의도 감지 시 발동. 4단계: 7Q 인터뷰 → 패턴 매핑 → 안전장치 검증 → [STOP] blueprint 승인 → scaffold. 산출물: 루프 SKILL.md + workflow.js + HUMAN-GATES.md + STATE.md + TRIGGER.md. 커널(same_issue/plateau/oscillation/max_cycles 등 8 stop-condition)을 소유 — scripts/loop-kernel.js. /qa·/healer는 이 커널을 직접 호출해 SSoT로 삼는다(2026-07-05 단일화 — 더 이상 SKIP 대상 아님, agents/healer.md §loop-kernel.js SSoT 연동 참조). SKIP: /migration-audit(DB 전용), 1회성 단순 검사.
Detects semantic code quality issues (logic, architecture, UX) that static hooks cannot catch. Provides 10 rules across 4 categories: API patterns, HTML/accessibility, architecture, and logic. Auto-triggered in Forge Dev Check 8.7Q and referenced during code review.
구현 착수 전 아이디어를 설계 문서로 전환하는 스킬. 기능 추가·컴포넌트 생성·동작 변경 등 창의적 작업 시 반드시 사용. 의도·요구사항·설계를 탐색한 후 구현으로 전환.
| name | investigate |
| description | 버그/이슈의 근본 원인을 4단계 구조화 프로세스로 분석하는 스킬. "근본 원인 없이 수정 금지" 철칙. 증상→분석→가설→검증→수정 순서를 강제. |
| user-invocable | true |
| context | fork |
| model | sonnet |
역할: 당신은 버그/이슈의 근본 원인을 4단계 구조화 프로세스로 분석하는 디버깅 전문가입니다. 컨텍스트: 사용자가 버그, 에러, 이상 동작을 겪을 때 호출됩니다. 출력: 근본 원인 분석 보고서 + 수정 계획을 반환합니다.
파이프라인 위치:
/forge-fix버그 파이프라인 ① 조사·재현 스테이지. 독립 호출도 유지.
버그, 에러, 이상 동작의 근본 원인을 4단계 구조화 프로세스로 분석한다.
RAG 선검색 → 조사 → 분석 → 가설 검증 컨텍스트 격리. Stage 4+5(재현+수정)는 human gate 후 healer/forge-pge 위임.
패턴: RAG(Explore) → Investigate(소스+gitnexus) → Analyze(가설 2개+) → Verify → [STOP] human gate.
실행: Workflow({ script: Bash("cat ~/.claude/skills/investigate/workflow.js"), args: { issue, target, skipVerify } })
skipVerify=true → Stage 3 skip, 가설 목록만 반환. CLAUDE_CODE_DISABLE_WORKFLOWS=1 시 기존 직접 실행 fallback.
근본 원인을 특정하지 않은 상태에서 수정하지 않는다. 증상만 보고 패치하면 다른 곳에서 같은 문제가 재발한다.
/investigate "로그인 후 세션이 유지되지 않는 문제"
/investigate "grants-write가 작성요령 span을 삭제하는 버그"
/investigate "RAG 검색 결과에 관련 없는 문서가 상위에 나옴"
이슈 키워드(에러 메시지 + 모듈명 + 증상)로 forge-outputs를 먼저 검색한다.
rag-search 스킬 호출
forge-outputs/01-research/bugs/**/*.md + forge-outputs/docs/reviews/**/*.md 직접 탐색 → 파일명에 키워드 포함 시 Readdate: 또는 # ... YYYY-MM-DD 패턴에서 YYYY-MM-DD 추출## 근본 원인 / ## 수정 파일 섹션에서 .ts/.js/.py/.cs/.go 경로 Grep-- .)로 대체git -C "{프로젝트 루트}" log --since="{YYYY-MM-DD}T00:00:00+09:00" --oneline -- {관련 파일들} 실행재현이 자명하지 않은 버그는 ${FORGE_ROOT:-$HOME/forge}/.claude/rules-on-demand/bug-feedback-loop.md 참조 — 루프 구축법 11종(실패 테스트→curl→트레이스 재생→bisect→차등 루프…), tight 4기준(red-capable·결정적·빠름·agent-runnable), 비결정 버그 재현율 전략. red-capable 명령이 존재하기 전에 코드를 읽으며 가설부터 세우는 것 금지. 가설은 3~5개 랭킹 생성(단일 가설 = 앵커링) 후 검증 착수 — Stage 2 "가설 2개+"의 상한 확장.
아래 11종 카탈로그가 전체 인라인 SSoT (외부 파일 없음). Stage 0.5 빠른 매핑 + Stage 2 가설 수립에 공통 참조한다.
| # | 카테고리 | 증상 힌트 |
|---|---|---|
| 1 | off-by-one | 경계값 근처에서만 실패, N-1개 처리, 마지막 요소 누락 |
| 2 | race-condition | 간헐적 실패, 동시 요청 시에만, 타이밍 의존, 재현 불안정 |
| 3 | null-deref | NPE/NullReference, undefined 접근, optional 미처리 |
| 4 | type-coercion | 타입 변환 후 잘못된 비교, JS == vs ===, implicit cast |
| 5 | state-mutation | 전역 변수 오염, 클로저 캡처 오류, 공유 상태 예상 외 변경 |
| 6 | async-order | Promise chain 순서 오류, callback hell, await 누락, 이벤트 순서 의존 |
| 7 | boundary-check | 배열 범위 초과, 페이지 0/마지막, 빈 입력 미처리 |
| 8 | resource-leak | 파일/커넥션 미닫힘, 메모리 누수, 소켓 고갈, GC pressure |
| 9 | config-mismatch | 환경별 설정 불일치, 시크릿 미주입, 피처 플래그 반전, 경로 불일치 |
| 10 | dependency | 라이브러리 버전 충돌, 패키지 누락, peer dependency 불일치 |
| 11 | regression | 이전에 정상이었으나 특정 커밋 이후 재발, git bisect 대상 |
→ Stage 0.5에서 1~2개 특정 후 Stage 1 진입. Stage 2 가설 수립 시 해당 카테고리 패턴을 근거로 활용.
Stage 2(분석) 및 Stage 3(가설 검증) 진행 시, 아래 4가지 추론 모델 중 상황에 맞는 것을 선택하여 적용한다. 기존 5-step 역추적(Stage 2 §코드 경로 역추적)과 병행 사용.
| 모델 | 적용 상황 | 방법 |
|---|---|---|
| binary-search | 재현 가능하나 원인 범위가 넓을 때 (대규모 코드베이스, 수백 커밋) | 범위를 절반씩 좁힘. git bisect 또는 코드 경로를 반으로 나눠 어느 쪽이 실패하는지 확인 → 반복 |
| differential | "A 환경에서는 정상, B 환경에서는 실패" 패턴일 때 | 두 환경의 차이점 목록화 (설정·버전·데이터·실행 순서) → 차이 항목을 하나씩 교체하며 실패 재현 |
| causal-chain | 에러 스택트레이스 또는 로그가 있을 때 (원인-결과 체인 역추적) | 증상(결과)에서 출발해 "무엇이 이것을 유발했는가"를 거슬러 올라감. 5-Whys와 결합. 최초 입력/상태 오류 지점 도달 시 종료 |
| invariant-check | 복잡한 상태 기계·데이터 파이프라인·분산 시스템에서 간헐적 실패 | 시스템이 항상 참이어야 하는 불변 조건(invariant)을 명시 → 각 체크포인트에서 불변 조건 위반 여부 확인 → 위반 지점 = 원인 |
추론 모델 선택 가이드:
증상을 11-Category Bug Pattern 카탈로그(위)에 빠르게 매핑한다. Stage 1 탐색 범위를 사전에 좁히기 위함.
→ 해당 카테고리 1~2개 특정 후 Stage 1 시작.
증상을 정확히 기록하고, 재현 조건을 특정한다.
시작 전 — GitNexus 구조 탐색 (인덱스된 프로젝트에서 우선 실행):
0. mcp__gitnexus__list_repos → indexed_date 확인 (7일+ stale = 경고 후 계속)
1. mcp__gitnexus__query({query: "{에러_키워드} {모듈명}"})
→ 관련 Process + Symbol 발견 (grep 추측 대신 그래프 근거)
2. mcp__gitnexus__context({name: "{의심_함수}"})
→ callers/callees 360도 뷰 → 재현 시나리오 근거
→ gitnexus 결과 없으면 기존 grep/소스 탐색 fallback
시작 전: .claude/reference/codebase-analysis.md 존재 시 Read → 아키텍처·의존성 그래프 파악 후 영향 범위 추론에 활용
## 증상
- 무엇이 발생하는가:
- 언제 발생하는가:
- 어디서 발생하는가:
- 재현 가능한가: [Yes/No/간헐적]
- 재현 계정: [예: test_j만 / test_j + test_m 동일 / 모든 계정]
## 재현 단계
1. ...
2. ...
3. → 여기서 문제 발생
## 기대 동작 vs 실제 동작
- 기대: ...
- 실제: ...
수집 방법:
UI/레이아웃 버그 분기 (증상이 시각적 깨짐·렌더링 이슈인 경우):
# 1. 재현 전 스크린샷 (RED) — mcp__claude-in-chrome 사용
# 저장: docs/bug_report/screenshots/{BUG-ID}-red-before.png
# 2. 스크린샷을 bug report에 첨부 → healer Vision evaluator가 참조
# Chrome 접속 → 해당 페이지 이동 → screenshot 캡처
# 파일 없으면 healer a4 Vision evaluator 판정 불가 → 반드시 캡처
API 응답 캡처 분기 (데이터 없음 vs 버그 구분이 필요한 경우):
# Stage 1에서 API 응답 body 저장
# 저장: docs/bug_report/artifacts/{BUG-ID}-api-response.json
# → healer가 재현 시 동일 API 재호출 없이 참조 가능
# → "데이터 없음(정상)" vs "버그" 구분 근거로 사용
과거 버그 자동 검색 (필수): Stage 1 시작 시 두 채널로 유사 버그 확인.
# (1) learnings.jsonl 의 bug-fix-pattern (compounding — global + project, access.log 자동 기록)
LEARN_BY=investigate bash ~/.claude/scripts/learnings.sh load bug-fix-pattern 2>/dev/null
# (2) rag-search (보완 — forge-outputs/01-research/bugs/ 본문 검색)
rag-search("{project} {증상 키워드}")
→ 관련 결과 있으면 Stage 1 보고서에 "관련 과거 버그" 섹션 추가 (learnings의 apply = 이전 근본원인+수정 패턴 요약 / bug 리포트 = 상세).
다층 시스템 boundary 진단 (멀티 컴포넌트 시스템 필수):
시스템이 다층 구조(Frontend → API → DB, CI → build → deploy, Auth proxy → SignalR → backend)일 때 추측 금지 — evidence 수집 우선.
각 컴포넌트 경계에 진단 instrumentation 추가하여 WHERE 깨지는지 한 번에 확인:
For EACH component boundary:
- 컴포넌트 진입 시 입력 데이터 로깅
- 컴포넌트 출구 시 출력 데이터 로깅
- 환경변수/설정 propagation 검증
- 각 레이어 상태(헤더·세션·토큰·DB connection state) 캡처
→ 한 번 실행 → evidence 수집 → 깨진 경계 식별 → 해당 컴포넌트만 Stage 2 분석
예시 (starbeginz 3 repo: avatarplay-frontend → .NET API → MySQL):
# Layer 1: Frontend 요청
console.log('[FE→API] req:', { url, headers: { Authorization: token?.substring(0,20) }, body });
# Layer 2: .NET 진입
_logger.LogInformation("[API entry] User={UserId}, Endpoint={Path}, JwtClaims={Claims}", ...);
# Layer 3: ServiceStack OrmLite 쿼리
_logger.LogInformation("[DB query] SQL={Sql}, Params={Params}", db.GetLastSql(), parameters);
# Layer 4: 응답
_logger.LogInformation("[API exit] resultCode={Code}, dataKeys={Keys}", result.ResultCode, ...);
원칙: 1 회 실행 + 4 layer 로그 = 깨진 경계 즉시 식별 → 해당 1개 layer만 깊이 조사. 4 layer 동시 추측 = thrashing.
가능한 원인을 모두 나열하고, 증거 기반으로 좁힌다.
가설 나열 전, 동일 코드에서 정상 동작 경로(working example) 와 실패 경로 를 나란히 비교한다:
→ working example 비교 없이 가설 목록만 나열하면 Stage 2 미완료.
아래 생각이 들면 멈추고 근거를 먼저 수집한다:
## 가설 목록
| # | 가설 | 가능성 | 근거 |
|---|------|:-----:|------|
| 1 | ... | High | ... |
| 2 | ... | Medium | ... |
| 3 | ... | Low | ... |
## 제외된 가설
| 가설 | 제외 이유 |
|------|---------|
| ... | ... |
분석 방법:
가장 가능성 높은 가설부터 검증한다.
## 검증 결과
| 가설 | 검증 방법 | 결과 | 확정? |
|------|---------|------|:----:|
| 1 | ... | ... | ✅/❌ |
검증 방법:
(선택) Advisor 가설 우선순위 조언 — 가설이 3개 이상이고 각각 검증 비용이 클 때:
Agent(
subagent_type="advisor-strategist",
prompt=f"""
근본 원인 가설 중 검증 우선순위 조언 요청.
증상:
{핵심 증상 3~5줄}
후보 가설 목록:
1. {가설 1}
2. {가설 2}
3. {가설 3}
이미 검증된 것:
- {가설 X}: {검증 결과 요약}
제약:
- 검증 시간 평균 {n}시간/가설
- 프로덕션 영향 있음 (유지보수 창구 제한)
질문:
1. 다음 검증할 가설 순서를 근거와 함께 제시해주세요.
2. 각 검증의 예상 비용(시간)과 차단 리스크를 짚어주세요.
"""
)
Advisor 응답 받아 Stage 3 진행 순서 결정.
근본 원인이 확정되면, 수정 전에 재현 테스트를 먼저 작성한다.
Prove-It 원칙: 버그를 코드로 증명한 후에만 수정한다. 재현 테스트 없는 수정은 "고쳤다고 생각했는데 다시 터짐"의 원인이다.
## 재현 테스트
- 테스트 파일: ...
- 테스트 내용: [버그를 정확히 재현하는 테스트]
- 실행 결과: ❌ FAIL (버그가 재현됨을 확인)
프로세스:
blast-radius 게이트: 수정 예상 범위가 >5개 파일이면 Stage 5 진입 전 중단. → Human에게 범위 확인 요청 또는 scope 축소 후 재진행. >5 파일 수정 = 설계 문제 또는 wrong-root-cause 신호.
재현 테스트가 FAIL하는 것을 확인한 후에만 수정한다.
## 근본 원인
[1문장으로 정확히 기술]
## 수정 내용
- 파일: ...
- 변경: ...
- 이유: ...
## 검증
- [ ] 재현 테스트 → ✅ PASS (수정 확인)
- [ ] 기존 테스트 → ✅ 전체 PASS (회귀 없음)
## 재발 방지
- [ ] 재현 테스트가 CI에 포함됨
- [ ] /learn에 패턴 저장
- [ ] 관련 규칙/문서 업데이트
fix-attempt 카운터를 추적한다. Stage 5를 재진입할 때마다 +1.
토큰 캡: Stage 진입마다 확인.
INVESTIGATE_TOKEN_CAP = 환경변수 INVESTIGATE_TOKEN_CAP (기본: 300000)
각 Stage 진입 전:
if estimated_tokens ≥ INVESTIGATE_TOKEN_CAP:
"[STOP] INVESTIGATE_TOKEN_CAP={cap} 도달. Stage {N} 진입 취소."
현재까지 수집한 증거 + 가설 목록 + 마지막 Stage 결과 반환
INVESTIGATE_TOKEN_CAP 미설정 시 기본값 300000 적용.same-root-cause oscillation 가드: Stage 5에서 2회 연속 동일 근본 원인이 도출됐으나 테스트가 여전히 FAIL인 경우 → Stage 2 재진입 금지, 즉시 에스컬레이션.
same-root-cause 판정:
Stage 5 attempt N 완료 후:
current_root = "## 근본 원인" 섹션 1줄(정규화 소문자, 앞 120자)
prev_root = attempt N-1 의 동일 추출값
if current_root == prev_root AND 테스트 FAIL:
"[OSCILLATION] 동일 근본 원인 2회 — 수정 패치가 실제 원인에 미도달."
"Stage 2 재진입 금지. 설계 검토 필요. Human 에스컬레이션."
STATUS: BLOCKED (조사 완료 상태 선언)
handover에 oscillation 경위 + 마지막 root-cause 기록 의무
| 합리화 패턴 | 반박 | 올바른 행동 |
|---|---|---|
| "증상이 명확하니 원인도 명확하다" | 증상 ≠ 원인. 증상은 여러 원인의 결과일 수 있다 | Stage 2 가설 최소 2개 이상 |
| "이 파일만 보면 충분하다" | 다층 시스템에서 레이어 간 경계가 진짜 실패 지점 | Stage 1 boundary 진단 먼저 |
| "긴급하니 Stage 건너뜀" | 빠른 우회 패치 = 재발 보장 | Stage 순서 고정, 긴급 = 근거 수집 속도 ↑ |
| "3번 시도했으니 이게 맞다" | 반복 실패 = 가설이 틀렸다는 신호 | 3-fix 에스컬레이션 규칙 적용 |
| "테스트 추가는 나중에" | 재현 테스트 없으면 수정 검증 불가 | Stage 4 Prove-It 먼저 |
Stage 3 이후 [STOP] human gate 전, 반드시 아래 3종 중 하나로 완료 상태 선언:
| 상태 | 의미 | 조건 |
|---|---|---|
| DONE | 근본 원인 특정 완료, 수정 가능 | 가설 검증 PASS + 재현 명령 FAIL 확인 |
| DONE_WITH_CONCERNS | 원인 특정했으나 부작용/불확실성 존재 | 가설 검증 PASS + 경고 사항 명시 |
| BLOCKED | 근본 원인 특정 불가, 추가 정보 필요 | 3-fix 에스컬레이션 도달 또는 재현 불가 |
출력 형식 (human gate 직전):
조사 완료 상태: DONE | DONE_WITH_CONCERNS | BLOCKED
근본 원인: <1줄>
확인 명령: <재현 명령>
다음 단계: <healer 위임 | 추가 정보 요청 | 에스컬레이션>
learnings.sh append --category bug-fix-pattern 자동 1줄)Stage 5 수정 완료 후 반드시 bug log를 forge-outputs에 저장한다.
저장 경로: forge-outputs/01-research/bugs/{project}/{YYYY-MM-DD}-{slug}.md
{project}: 현재 작업 디렉토리에서 추론 (godblade, portfolio, pingame-server 등){slug}: 증상 요약 kebab-case (예: session-not-persisted-after-login)---
project: {project}
date: {YYYY-MM-DD}
severity: P0/P1/P2
status: fixed
tags: [관련 키워드]
---
## 증상
[Stage 1의 증상 요약]
## 근본 원인
[Stage 5의 근본 원인 1문장]
## 수정 내용
- 파일: ...
- 변경: ...
## 재발 방지
[Stage 5의 재발 방지 내용]
## 관련 버그
[rag-search에서 발견된 연관 버그 링크, 없으면 "없음"]
rag-search 자동 인덱싱: 저장 즉시
forge-outputs/01-research/bugs/가 rag-search 범위에 포함되어 다음/investigate호출 시 Stage 1에서 이 버그가 참조됨.
+ learnings.jsonl 1줄 append (compounding — 필수): bug log MD 저장 후, 그 요약을 learnings에도 기록한다 (다음 세션·동료가 learnings.sh load bug-fix-pattern으로 자동 참조). 헬퍼가 sanitize(스택트레이스 full/토큰 차단)·collision-id·validate 처리:
bash ~/.claude/scripts/learnings.sh append --category bug-fix-pattern \
--summary "<증상 1줄>" \
--trigger "<재현 조건 1줄>" \
--apply "<근본 원인 + 수정 패턴 1줄>" \
--evidence "01-research/bugs/{project}/{YYYY-MM-DD}-{slug}.md"
📌 learnings 신규: <id>. exit 2(secret 감지) → ⚠️ bug-fix-pattern learning 억제 — <패턴명>, 내용 비노출 만 (raw 노출 X). exit 3(다줄 등) → summary/apply를 1줄로 압축 후 재시도. exit 4(git repo 아님) → learning 내용을 사용자 보고에 1줄 노출(손실 0).summary·apply·evidence·trigger = 각 1줄 (개행 금지 — 스택트레이스는 본문 bug log MD에만, learnings엔 1줄 요약).롤업 자동 갱신 (신선도 — append 성공 후): bug-fix 패턴 기록 직후 프로젝트 Graph RAG 롤업 즉시 재생성 (단일 sync 엔진, idempotent·non-blocking):
REPO=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo unknown)
[ -d "${FORGE_OUTPUTS:-$HOME/forge-outputs}/.rag-index" ] && [ "$REPO" != unknown ] && \
OPENAI_API_KEY="" timeout 180 python3 ~/forge/shared/scripts/rag/project_knowledge_sync.py --project "$REPO" >/dev/null 2>&1 || true
Stage 6 bug log 저장 후 자동 호출:
/codex-review --stage bugfix --target <patch file or PR-N>
검증 포커스 (적대적):
정책:
bugfix stage = blocking NO. WARN/FAIL → 사용자 컨펌 후 진행forge-outputs/docs/reviews/bugfix/{date}-{slug}.{md,json}CODEX_REVIEW_AUTO_STAGES=off실패 시 [[pev-self-correction]] 적용
/investigate 세션 종료 시 아래 3-state enum 중 하나를 명시적으로 선언한다.
| 상태 | 의미 | 조건 |
|---|---|---|
DONE | 근본 원인 특정 + 수정 완료 + 재현 테스트 PASS | Stage 5 성공 + Stage 6 저장 완료 |
DONE_WITH_CONCERNS | 수정 완료했으나 주의 항목 존재 | Stage 5 성공이지만 ① Codex WARN ② blast-radius 5↑ ③ 임시 패치 |
BLOCKED | Human gate 또는 3-fix 에스컬레이션 | ① Stage 4 [STOP] ② 3회 수정 실패 ③ 설계 개입 필요 |
세션 마지막 보고에 포함:
[investigate] STATUS: DONE | 근본 원인: <1줄> | 수정 커밋: <hash>
[investigate] STATUS: DONE_WITH_CONCERNS | 사유: <Codex WARN 항목 / 임시 패치 이유>
[investigate] STATUS: BLOCKED | 사유: <Human gate 필요 이유> | 권고: <다음 액션>
DONE_WITH_CONCERNS / BLOCKED는 handover §발견한 이슈에 상세 기록 필수.