Systematic Debugging (체계적 디버깅)
철칙: 근본 원인 조사 없이 수정 금지. 증상만 고치는 것은 실패다.
간단해 보이는 버그, 급한 상황, "빨리 고쳐달라"는 압박일수록 이 프로세스를 지킨다 — 체계적 디버깅이 추측-수정 반복보다 빠르다.
4단계 (각 단계 완료 전 다음 단계 진행 금지)
1단계: 근본 원인 조사
- 에러 메시지를 끝까지 읽는다 — 스택 트레이스 전체, 라인 번호, 에러 코드. 답이 이미 적혀 있는 경우가 많다
- 일관되게 재현한다 — 재현 불가면 추측하지 말고 데이터를 더 모은다
- 최근 변경 확인 — git diff, 최근 커밋, 의존성/설정/환경 차이
- 다중 컴포넌트 시스템이면 계측 먼저 — 각 컴포넌트 경계에서 들어가는/나오는 데이터를 로그로 남겨 어느 레이어에서 깨지는지 증거를 확보한 뒤 그 레이어를 조사
- 데이터 흐름 역추적 — 잘못된 값이 어디서 생겼는지 호출 스택을 거슬러 올라가 원천에서 수정 (증상 위치에서 수정 금지)
2단계: 패턴 분석
- 같은 코드베이스에서 동작하는 유사 코드를 찾아 비교
- 레퍼런스 구현이 있으면 전체를 읽는다 (스키밍 금지)
- 동작하는 것과 깨진 것의 차이를 전부 나열 — "그건 상관없겠지" 가정 금지
3단계: 가설과 검증
- 가설을 하나만, 명확하게: "X가 원인이라고 본다. 근거는 Y"
- 최소 변경으로 검증 — 한 번에 한 변수만
- 실패하면 새 가설 수립. 기존 수정 위에 수정을 쌓지 않는다
- 모르면 "X를 이해하지 못했다"고 말한다. 아는 척 금지
4단계: 구현
- 수정 전에 실패하는 테스트 케이스부터 만든다 (최소 재현)
- 근본 원인에 대한 단일 수정 — "하는 김에" 리팩토링 금지
- 수정 후 검증: 테스트 통과? 다른 테스트 안 깨짐?
3회 실패 규칙
수정을 3번 이상 시도했는데 실패하면 아키텍처를 의심한다. 수정할 때마다 다른 곳에서 새 문제가 나오면 가설이 아니라 구조가 틀린 것이다. 4번째 수정을 시도하지 말고 사용자와 구조 논의부터 한다.
위험 신호 (이 생각이 들면 STOP → 1단계로)
- "일단 빨리 고치고 나중에 조사하자"
- "X를 바꿔보고 되는지 보자"
- "여러 개 한꺼번에 고치고 테스트 돌리자"
- "테스트는 생략하고 수동으로 확인하자"
- "완전히 이해는 안 되지만 이러면 될 것 같다"
- 데이터 흐름 추적 전에 해결책부터 나열하고 있다