순환 고리 끊기 - 심층 버그 분석
디버깅이 완료된 후, 이 스킬을 사용하여 "버그 수정 -> 망각 -> 반복" 순환을 끊기 위한 심층 분석을 수행하세요.
분석 프레임워크
방금 수정한 버그를 다음 5가지 차원에서 분석하세요:
1. 근본 원인 카테고리
이 버그는 어떤 카테고리에 속하나요?
| 카테고리 | 특징 | 예시 |
|---|---|---|
| A. 누락된 스펙 | 수행 방법에 대한 문서가 없음 | 체크리스트 없는 새 기능 |
| B. 계층 간 계약 | 계층 간 인터페이스가 불명확 | API가 예상과 다른 형식 반환 |
| C. 변경 전파 실패 | 한 곳을 변경하고 다른 곳을 놓침 | 함수 시그니처 변경, 호출 지점 누락 |
| D. 테스트 커버리지 갭 | 유닛 테스트는 통과, 통합 테스트는 실패 | 단독으로는 동작하지만 결합 시 실패 |
| E. 암묵적 가정 | 문서화되지 않은 가정에 의존하는 코드 | 타임스탬프 초 vs 밀리초 |
2. 수정 실패 이유 (해당하는 경우)
성공하기 전에 여러 번 수정을 시도했다면 각 실패를 분석하세요:
- 표면적 수정: 증상만 고치고 근본 원인은 해결하지 못함
- 불완전한 범위: 근본 원인은 찾았으나 모든 사례를 다루지 못함
- 도구 한계: grep이 놓치거나, 타입 검사가 엄격하지 않음
- 멘탈 모델: 같은 계층에서만 찾으려 하고, 계층 간 생각을 하지 않음
3. 방지 메커니즘
어떤 메커니즘이 이 버그의 재발을 막을 수 있을까요?
| 유형 | 설명 | 예시 |
|---|---|---|
| 문서화 | 기록하여 사람들이 알게 함 | 사고 가이드 업데이트 |
| 아키텍처 | 구조적으로 오류를 불가능하게 함 | 타입 안전 래퍼 |
| 컴파일 시점 | 엄격한 타입 검사, 탈출구 없음 | 시그니처 변경 시 컴파일 오류 |
| 런타임 | 모니터링, 알림, 스캔 | 고아 엔티티 감지 |
| 테스트 커버리지 | E2E 테스트, 통합 테스트 | 전체 흐름 검증 |
| 코드 리뷰 | 체크리스트, PR 템플릿 | "X를 확인했나요?" |
4. 체계적 확장
이 버그가 드러내는 더 광범위한 문제는 무엇인가요?
- 유사한 문제: 이 문제가 또 어디에 존재할까?
- 설계 결함: 근본적인 아키텍처 문제가 있는가?
- 프로세스 결함: 개발 프로세스 개선점이 있는가?
- 지식 격차: 팀이 이해하지 못하는 부분이 있는가?
5. 지식 포착
인사이트를 시스템에 확고히 기록하세요:
-
.trellis/spec/guides/사고 가이드 업데이트 - 관련
.trellis/spec/문서 업데이트 - 이슈 기록 생성 (해당되는 경우)
- 근본 수정을 위한 기능 티켓 생성
- 필요시 체크 가이드라인 업데이트
출력 형식
분석을 다음 형식으로 출력하세요:
## 버그 분석: [짧은 설명]
### 1. 근본 원인 카테고리
- **카테고리**: [A/B/C/D/E] - [카테고리명]
- **구체적 원인**: [상세 설명]
### 2. 수정 실패 이유 (해당하는 경우)
1. [첫 번째 시도]: [실패 이유]
2. [두 번째 시도]: [실패 이유]
...
### 3. 방지 메커니즘
| 우선순위 | 메커니즘 | 구체적 조치 | 상태 |
|----------|----------|-------------|------|
| P0 | ... | ... | TODO/DONE |
### 4. 체계적 확장
- **유사한 문제**: [비슷한 문제가 있는 곳 목록]
- **설계 개선**: [아키텍처 수준 제안]
- **프로세스 개선**: [개발 프로세스 제안]
### 5. 지식 포착
- [ ] [업데이트할 문서 / 생성할 티켓]
핵심 철학
디버깅의 가치는 버그를 수정하는 데 있는 것이 아니라, 이 유형의 버그가 다시는 발생하지 않도록 하는 데 있습니다.
세 가지 인사이트 수준:
- 전술적: 이 버그를 수정하는 방법
- 전략적: 이 유형의 버그를 예방하는 방법
- 철학적: 사고 패턴을 확장하는 방법
30분의 분석이 30시간의 미래 디버깅 시간을 절약합니다.
사고 프레임워크: 베이즈 추론
여러 근본 원인이 plausible하고 증거가 불완전할 때, 초기 가정에 집착하지 말고 새로운 증거에 비례하여 신념을 업데이트하세요.
1단계: 사전 확률 설정
조사 전에, 무엇을 믿고 왜 믿는지 명시하세요:
| 가설 | 사전 확률 | 근거 |
|---|---|---|
| H1: [원인 A] | 40% | 이 패턴에서 가장 흔함 |
| H2: [원인 B] | 30% | 환경 상 plausible |
| H3: [기타] | 30% | 포괄적 가설 |
사전 확률은 반드시 합이 100%여야 합니다. 확률을 할당할 수 없으면 먼저 조사하세요.
2단계: 증거 관찰
발견한 내용을 구체적으로 문서화하세요 — 신뢰도에 대해 구체적으로:
- 정확히 무엇을 관찰했나요?
- 신뢰도는? (테스트 출력 > 로그 메시지 > 사용자 보고 > 직감)
- 여러 가설이 이를 설명할 수 있나요?
3단계: 신념 업데이트
각 가설에 대해 묻습니다: 이 가설이 참이라면 이 증거가 얼마나 likely한가?
계산보다 업데이트 방향이 중요합니다:
- H1이 강하게 예측한 증거 → H1 확률 증가
- H2와 모순되는 증거 → H2 확률 감소
- 모든 가설에서 동등하게 likely한 증거 → 업데이트 없음
4단계: 판별적 증거 탐색
같은 종류의 증거를 더 모으지 마세요. 상위 가설 간에 크게 다른 증거를 찾으세요.
H1과 H3가 비슷하다면: "H1이 참일 때 보이고 H3이 참일 때는 보이지 않는 것은 무엇일까?" 그런 다음 확인하세요.
5단계: 신뢰도 명시
| 신뢰도 | 조치 |
|---|---|
| 90% 이상 | 수정 진행, 모니터링 |
| 70-90% | 진행하되, fallback 확인 추가 |
| 50-70% | 가설을 테스트한 후 확정 |
| 50% 미만 | 더 많은 증거 필요, 추측하지 마세요 |
증거가 불완전할 때 절대 이진적 확신을 표현하지 마세요. "가장 likely", "plausible하지만 unlikely", "조사할 가치 있음"을 사용하세요.
일반적인 오류
| 오류 | 예시 | 교정 |
|---|---|---|
| 기저율 무시 | "테스트 실패 → 코드가 깨짐" | 테스트가 다른 이유로 실패하는 빈도는? |
| 확증 편향 | "반드시 경쟁 조건일 거야, 경쟁 조건 증거를 찾자" | 최상위 가설에 반하는 증거를 적극적으로 찾으세요 |
| 앵커링 | "지난번에는 캐싱 문제였으니, 아마 또 캐싱 문제일 거야" | 어제의 버그가 아닌 현재 컨텍스트에서 사전 확률을 설정하세요 |
분석 후: 즉시 조치
중요: 위 분석을 완료한 후, 반드시 즉시 다음을 수행하세요:
-
spec/guides 업데이트 - TODO만 나열하지 말고, 실제 관련 파일을 업데이트하세요:
- 크로스 플랫폼 문제 →
cross-platform-thinking-guide.md업데이트 - 계층 간 문제 →
cross-layer-thinking-guide.md업데이트 - 코드 재사용 문제 →
code-reuse-thinking-guide.md업데이트 - 도메인 특화 문제 →
backend/*.md또는frontend/*.md업데이트
- 크로스 플랫폼 문제 →
-
템플릿 동기화 -
.trellis/spec/업데이트 후,src/templates/markdown/spec/에 동기화 -
스펙 업데이트 커밋 - 이것이 주요 산출물이며, 단순한 분석 텍스트가 아닙니다
분석이 채팅에 머물면 가치가 없습니다. 가치는 업데이트된 스펙에 있습니다.