trace
|
Install
mkdir -p .claude/skills/trace-lee-sihyeon && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14286" && unzip -o skill.zip -d .claude/skills/trace-lee-sihyeon && rm skill.zipInstalls to .claude/skills/trace-lee-sihyeon
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
경쟁 가설 기반 evidence-driven 디버깅. 애매한 버그, 인과관계 추적, 성능 문제, 2회 이상 재현 실패한 버그에 사용합니다. "trace", "왜 이게", "원인 분석", "debugging", "버그 추적", "root cause", "원인을 모르겠어", "재현이 안 돼" 트리거로 사용합니다. oh-my-claudecode의 trace 스킬 패턴을 Copilot CLI에 포팅한 스킬입니다.About this skill
TRACE — 경쟁 가설 기반 Evidence-Driven 디버깅
"가설을 세우고, 증거로 죽여라. 살아남은 가설이 답이다."
사용법
/trace "로그인 후 간헐적으로 500 에러 발생"
/trace "특정 유저만 결제 실패"
/trace "배포 후 응답속도 3배 느려짐"
/trace "로컬에선 되는데 CI에서만 실패"
언제 trace를 써야 하는가
USE WHEN:
- 원인이 명확하지 않은 버그 (직관으로 바로 고치기 어려운 경우)
- 2회 이상 다른 곳을 수정했지만 버그가 사라지지 않는 경우
- 간헐적 / 환경 의존적 / 특정 유저에게만 발생하는 버그
- 성능 저하, 메모리 누수, 타임아웃 등 인과관계가 불명확한 경우
- "왜 이게 일어나는지" 물어봐야 하는 모든 상황
AVOID WHEN:
- 에러 메시지가 명확하고 수정 방향이 바로 보이는 경우 (그냥 고쳐라)
- 단순한 typo, 누락된 import, 명백한 null 체크 누락
- 이미 원인을 알고 있고 구현만 필요한 경우
핵심 계약 (The Trace Contract)
Trace 세션은 항상 아래 7개 필드를 유지한다. 이것이 작업 메모리다.
OBSERVATION : [재현 가능한 증상. 구체적으로. "가끔 느림" (X) → "p99 응답 2.3s, 정상 340ms" (O)]
HYPOTHESES : [순위화된 가설 목록. 각 가설은 반증 가능해야 함]
EVIDENCE FOR : [각 가설을 지지하는 실제 데이터/코드 증거]
EVIDENCE AGAINST: [각 가설을 약화시키는 실제 데이터/코드 증거]
BEST EXPLANATION: [현재 가장 유력한 가설 + 신뢰도 (0-100%)]
CRITICAL UNKNOWN: [지금 당장 알 수 없어서 진단을 막는 핵심 미지수]
NEXT PROBE : [CRITICAL UNKNOWN을 해소할 가장 효율적인 실험/탐색]
규칙:
- EVIDENCE는 반드시 실제 코드 줄, 로그, 측정값이어야 한다. "아마도", "보통은" 금지.
- 가설은 반증 가능해야 한다. "뭔가 잘못됐다"는 가설이 아니다.
- BEST EXPLANATION의 신뢰도가 85% 이상이면 진단 완료로 간주.
증거 강도 계층 (Evidence Strength Hierarchy)
증거를 수집할 때 이 순서를 따른다. 상위 증거가 하위 증거를 압도한다.
| 등급 | 유형 | 예시 |
|---|---|---|
| ⬆️ L1 | 직접 실험 (재현 성공) | 로컬에서 버그 재현 → 코드 변경 → 해결 확인 |
| ⬆️ L2 | 1차 소스 (코드/로그/측정) | 실제 스택트레이스, DB 쿼리 실행계획, 프로파일러 결과 |
| ⬆️ L3 | 다중 소스 수렴 | 로그 + 메트릭 + 코드 3가지가 같은 지점을 가리킴 |
| ⬇️ L4 | 단일 소스 추론 | 로그 하나만 보고 내린 결론 |
| ⬇️ L5 | 정황 증거 | "이 PR 이후로 느려짐" (상관관계, 인과관계 아님) |
| ⬇️ L6 | 직관 / 경험 | "이런 거 전에도 있었는데..." |
원칙: L5/L6 증거는 가설 생성에 쓰되, 진단 확정에는 쓰지 않는다. L1/L2 증거 없이 "원인을 찾았다"고 선언하지 않는다.
Phase 0: Observation 수집
/trace 시작 시 먼저 증상을 구체화한다.
자동 수집 (코드베이스)
# 최근 변경 이력 — 정황 증거 L5
git --no-pager log --oneline -20
# 최근 에러 패턴 탐색
grep -rn "error\|Error\|exception\|Exception" . \
--include="*.log" -l 2>/dev/null | head -5
# 관련 설정 파일 탐색
find . \( -name "*.env*" -o -name "*.config.*" \) \
-not -path "*/node_modules/*" -not -path "*/.git/*" | head -10
사용자에게 필수 확인
AskUserQuestion으로 정보 수집:
- 재현 조건: 항상 발생? 간헐적? 특정 환경/유저에서만?
- 최초 발생: 언제부터? 특정 배포/변경 후?
- 관찰 가능한 증거: 실제 에러 메시지, 로그, 스택트레이스 있나?
- 이미 시도한 것: 어떤 가설로 어떤 것을 시도해봤나?
Phase 1: 기본 3-레인 가설 수립
알려진 정보를 바탕으로 3개의 경쟁 가설 레인을 설정한다.
Lane A — 코드 경로 원인
"코드 로직 자체가 잘못됐다"
탐색 포인트:
- 최근 수정된 함수 / 모듈의 로직 오류
- Race condition, 동시성 문제
- 예외 처리 누락, 잘못된 에러 전파
- 잘못된 알고리즘 / 경계 조건 버그
# 최근 변경된 파일 탐색
git --no-pager diff HEAD~5 --name-only 2>/dev/null
# 핵심 함수 로직 확인
grep -rn "TODO\|FIXME\|HACK\|XXX" . \
--include="*.ts" --include="*.py" --include="*.js" \
-not -path "*/node_modules/*" | head -20
Lane B — 설정·환경 원인
"코드는 맞는데 환경/설정이 다르다"
탐색 포인트:
- 환경변수 차이 (로컬 vs 스테이징 vs 프로덕션)
- 의존성 버전 불일치 (package-lock.json drift 등)
- 인프라 설정 차이 (타임아웃, 메모리 제한, 커넥션 풀)
- 외부 서비스 상태 (DB, 캐시, 서드파티 API)
# 의존성 버전 확인
[ -f package.json ] && cat package.json | python3 -c \
"import json,sys; d=json.load(sys.stdin); print(json.dumps(d.get('dependencies',{}), indent=2))"
[ -f requirements.txt ] && cat requirements.txt
[ -f go.mod ] && cat go.mod
# 환경 설정 파일 목록
find . -name "*.env*" -not -path "*/.git/*" 2>/dev/null
find . -name "docker-compose*" -o -name "Dockerfile*" 2>/dev/null | head -5
Lane C — 측정·가정 불일치 원인
"버그가 아니라 우리가 잘못 보고 있다"
탐색 포인트:
- 로깅/모니터링 자체의 오류 (잘못된 메트릭 집계)
- 테스트가 실제 시나리오를 커버하지 않음
- 잘못된 전제 (예: "이 함수는 항상 sorted를 받는다")
- 재현 조건을 잘못 이해하고 있는 경우
Phase 2: /fleet 병렬 탐색
3개 레인을 explore 에이전트로 동시에 탐색한다.
# Atlas가 3개 레인을 병렬로 투입
/fleet [
explore: "Lane A 탐색 — [증상]과 관련된 코드 로직 오류 찾기.
최근 변경된 [관련 파일/모듈] 중심으로 탐색.
찾은 것: 파일 경로, 코드 줄, 의심 로직 설명",
explore: "Lane B 탐색 — [증상]과 관련된 설정/환경 차이 찾기.
.env, config, 의존성 버전, 인프라 설정 중심 탐색.
찾은 것: 설정 항목, 버전, 환경 간 차이점",
explore: "Lane C 탐색 — [증상]이 실제로 문제인지 측정/가정 오류인지 확인.
로깅 코드, 테스트 커버리지, 모니터링 설정 탐색.
찾은 것: 측정 로직 위치, 가정이 명시된 코드, 잠재적 오해"
]
Atlas의 병렬 실행 패턴:
# background 모드로 3 레인 동시 투입
agentA=$(task explore "Lane A: [구체적 탐색 지시]" mode=background)
agentB=$(task explore "Lane B: [구체적 탐색 지시]" mode=background)
agentC=$(task explore "Lane C: [구체적 탐색 지시]" mode=background)
# 완료 후 결과 수집
read_agent $agentA
read_agent $agentB
read_agent $agentC
Phase 3: 증거 수집 및 가설 순위화
각 레인의 결과를 Trace Contract에 채운다.
순위화 기준
| 기준 | 설명 |
|---|---|
| 증거 등급 | L1/L2 증거가 있는 가설 우선 |
| 설명 범위 | 더 많은 증상을 설명하는 가설 우선 |
| 단순성 | 같은 설명력이면 더 단순한 가설 우선 (Occam's Razor) |
| 반증 가능성 | 빠르게 반증 가능한 가설 우선 (실험 비용 고려) |
순위표 출력 형식
HYPOTHESIS RANKING (업데이트: [타임스탬프])
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#1 [가설 설명] — 신뢰도: [N]%
근거: [L1/L2 증거 인용]
약점: [반증 가능성]
#2 [가설 설명] — 신뢰도: [N]%
근거: [증거 인용]
약점: [반증 가능성]
#3 [가설 설명] — 신뢰도: [N]%
근거: [증거 인용]
약점: [반증 가능성]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CRITICAL UNKNOWN: [진단을 막는 핵심 미지수]
NEXT PROBE: [다음 실험/탐색 — 구체적 명령어/방법]
Phase 4: 반론 라운드 (Cross-Validation)
발동 조건: #1 가설 신뢰도가 60-85% 사이일 때. (85% 이상이면 Phase 5로 직행.)
1위 가설과 2위 가설을 oracle에게 교차 검증 요청:
oracle에게 위임:
"현재 #1 가설: [설명] (신뢰도 N%)
현재 #2 가설: [설명] (신뢰도 N%)
검토 요청:
1. #1 가설이 틀렸다면 어떤 증거를 찾아야 하는가?
2. #2 가설이 맞다면 #1 가설의 증거를 어떻게 설명하는가?
3. 두 가설을 한 번에 검증할 수 있는 단일 실험이 있는가?"
oracle 결과를 바탕으로 Discriminating Probe를 설계:
# Discriminating Probe 예시 — 실제 코드 실행/검색
# (증상에 따라 구체적 명령어 결정)
# 로그 타임라인 분석
grep -n "ERROR\|WARN" /path/to/app.log | tail -50
# 특정 조건에서만 발생하는지 코드로 확인
grep -rn "if.*condition" src/ --include="*.ts" | grep -v test
# DB 쿼리 시간 측정 (성능 문제 시)
# EXPLAIN ANALYZE SELECT ...
# 환경변수 값 덤프 (설정 문제 시)
printenv | grep -i "DB\|API\|TOKEN\|URL" | sort
Phase 5: 수렴 / 분기 판단
수렴 조건 (진단 완료)
- BEST EXPLANATION 신뢰도 ≥ 85%
- L1 또는 L2 증거가 1개 이상 존재
- 다른 가설들이 명확히 반증됨
→ Phase 6 최종 합성으로 이동
분기 조건 (추가 탐색 필요)
- BEST EXPLANATION 신뢰도 < 60%
- 여러 가설이 비슷한 신뢰도를 가짐
- CRITICAL UNKNOWN이 해소되지 않음
→ NEXT PROBE를 실행, Phase 2-4를 반복
막힌 상태 탈출 전략
| 상황 | 전략 |
|---|---|
| 재현이 안 됨 | 조건을 좁혀라. 환경변수, 데이터, 타이밍 중 무엇이 변수인가? |
| 모든 가설이 약함 | 가설을 완전히 버리고 OBSERVATION을 재검토. 다른 증상을 찾아라 |
| 증거가 상충함 | 증거의 등급을 확인. 낮은 등급 증거를 버리고 높은 등급 기준으로 판단 |
| 3 레인 모두 음성 | 4번째 가설 레인 추가: "외부 의존성 원인" (DB, API, 네트워크) |
Phase 6: 최종 합성 및 진단 보고
═══════════════════════════════════════════════
TRACE DIAGNOSIS COMPLETE
═══════════════════════════════════════════════
증상: [OBSERVATION 요약]
탐색: [몇 개 레인, 몇 개 probe 실행]
결론: ✅ 확정 | ⚠️ 유력 | ❌ 미확정
ROOT CAUSE:
[가장 유력한 가설 — 구체적 설명]
신뢰도: [N]% (증거 등급: L[N])
증거:
- [L1/L2 증거 1: 파일:줄수 또는 측정값]
- [L1/L2 증거 2: ...]
반증된 가설:
- [가설 A]: [무엇이 이 가설을 부정했는가]
- [가설 B]: [무엇이 이 가설을 부정했는가]
수정 방향:
1. [구체적 첫 번째 액션 — 파일, 함수, 설정 명시]
2. [구체적 두 번째 액션]
3. [검증 방법: 어떻게 고쳐졌는지 확인]
미해소 미지수: (있을 경우)
- [아직 알 수 없는 것 — 모니터링 권장]
═══════════════════════════════════════════════
신뢰도 < 85%로 종료할 때:
⚠️ 미확정 종료 — 신뢰도 [N]%
현재 최선 가설: [설명]
다음 단계 probe: [구체적 실험 방법]
이 정보로 /hephaestus에게 위임하거나 추가 로그 수집 후 재시작 권장.
Atlas Heavy Mode (복잡한 버그)
3 레인으로 부족할 때 atlas heavy mode 활성화:
/fleet [
explore: "코드 경로 심층 분석 — [구체적 범위]",
oracle: "현재까지 수집된 증거 검토 및 반증 설계",
hephaestus: "Discriminating Probe 코드 작성 및 실행"
]
사용 시점:
- 2회 이상 Probe를 돌렸는데 신뢰도가 오르지 않는 경우
- 버그가 여러 컴포넌트에 걸쳐 있을 가능성이 높은 경우
- 수정 비용이 높아서 진단 확실성이 필요한 경우
Anti-Patterns (금지)
- ❌ 첫 번째 가설을 검증 없이 바로 수정하기 — "가장 그럴싸해 보임"은 증거가 아니다
- ❌ L5/L6 증거만으로 원인 확정 — "이 PR 이후로 느려진 것 같음"은 진단이 아니다
- ❌ 신뢰도를 명시하지 않고 "원인을 찾았다"고 선언
- ❌ CRITICAL UNKNOWN을 해소하지 않고 Phase 5 수렴 선언
- ❌ 3개 레인을 순차 탐색 — 반드시 병렬 (
/fleet)로 실행 - ❌ Trace Contract 필드를 생략한 채 대화형으로만 진행
- ❌ 재현 조건 없이 코드 수정 시작 — 수정 후 검증 불가능해진다