Skip to content
Back to skills

Debugging

ASecurity

체계적 디버깅 및 버그 수정 스킬

  • 111 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 2, 2026
ai-agentsgobashtestingdebugginggitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 2, 2026

npx -y skills add Insajin/autopus-adk --skill debugging --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Debugging?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Debugging
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/insajin-debugging/badge)](https://www.skillsdirectory.com/skills/insajin-debugging)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: debugging
description: 체계적 디버깅 및 버그 수정 스킬
compatibility: omp
---

# Debugging Skill

버그를 체계적으로 재현하고 근본 원인을 분석하여 수정하는 스킬입니다.

## 핵심 원칙

**이 버그에 red가 되는 피드백 루프를 먼저 만든다.** 루프가 있으면 이분법·가설 검증·계측이
그것을 소비해 원인에 닿는다. 루프가 없으면 코드를 아무리 들여다봐도 못 찾는다. 루프의 대표
형태가 재현 테스트다: 수정 전 FAIL, 수정 후 PASS.

탐색할 때 `CONTEXT.md`(있으면)로 관련 모듈의 어휘를 잡고, 그 영역의 Lore(`auto why`)를 확인한다.
둘 다 없으면 대상 상수·설정의 doc comment와 Makefile/CI 주석을 Lore로 읽는다 — "예산을 키우는
방식은 세 번 실패했다" 같은 한 줄이 가설 순위를 바꾼다.

**비밀은 먼저 가린다.** 명령·출력·캡처를 보여 줄 때 credential은 `<REDACTED>`로 바꾼다. 루프는
env var를 읽게 만들어 값이 출력에 나오지 않게 한다. 가린 출력으로 진단이 안 되면 그렇다고 말하고
사용자에게 묻는다.

## 디버깅 프로세스

### 1단계: 피드백 루프 만들기

**이 단계가 스킬의 전부다.** 나머지는 기계적이다. 여기에 불균형하게 많은 노력을 쓴다.
공격적으로, 창의적으로, 포기하지 않는다.

루프를 만드는 방법(대략 이 순서로):

1. 버그에 닿는 seam에서의 **실패 테스트** — unit, integration, e2e
2. 개발 서버에 대한 **curl/HTTP 스크립트**
3. fixture 입력으로 **CLI 호출**, stdout을 known-good 스냅샷과 diff
4. UI를 몰고 DOM/console/network를 단언하는 **headless browser 스크립트**
5. 실제 요청/페이로드/이벤트 로그를 저장해 격리된 코드 경로로 **replay**
6. 시스템 최소 부분집합만 띄우는 **throwaway harness**
7. **이미 있는 flaky 테스트**라면 바이너리를 한 번 빌드(`go test -c`)하고 K개를 동시에
   `-count=N`으로 돌려 부하를 재현한다. 라운드마다 바이너리/서브테스트 red 수를 표로 집계한다
8. "가끔 틀린다"면 무작위 입력 1000개로 **property/fuzz 루프**
9. 두 상태(커밋, 데이터셋, 버전) 사이에서 생겼다면 `git bisect run`이 가능한 **bisection harness**
10. 구버전 vs 신버전, 두 설정, 또는 **런타임을 뺀 같은 메커니즘**(셸 스크립트만으로 exec 비용
    재현 등)에 같은 입력을 넣고 diff하는 **differential 루프**
11. 최후 수단: 사람이 클릭해야 하면 사람을 몰아가는 **HITL 셸 스크립트**

**루프를 조인다.** 하나 생기면 제품처럼 다듬는다: 더 빠르게(setup 캐시, 무관한 init 생략,
범위 축소), 더 날카롭게("죽지 않았다"가 아니라 정확한 증상을 단언), 더 결정적으로(시간 고정,
RNG seed, 파일시스템 격리, 네트워크 동결). 30초짜리 flaky 루프는 없는 것과 비슷하고, 2초짜리
결정적 루프는 **tight**하다.

**비결정적 버그**는 깨끗한 재현이 아니라 **재현율 상승**이 목표다. 트리거를 100번 반복,
병렬화, 스트레스, 타이밍 창 좁히기, sleep 주입. 50% 재현은 디버깅 가능하고 1%는 불가능하다.
코드를 못 고치는 단계에서는 **무수정 관찰**로 스톨 위치를 잡는다: 루프가 도는 동안 `ps`로
프로세스 상태·CPU를 샘플링하고, 시스템 로그와 데몬 부하(macOS의 XProtect/fseventsd 등)를 본다.

**루프를 정말 못 만들면** 멈추고 그렇다고 말한다. 시도한 것을 나열하고 (a) 재현 환경 접근,
(b) 가린 캡처(HAR, 로그 덤프, 코어 덤프, 타임스탬프 있는 화면 녹화), (c) 임시 운영 계측 허가
중 하나를 요청한다. 루프 없이 가설로 넘어가지 않는다.

**완료 기준**: 이미 최소 한 번 실행한(호출과 가린 출력을 보여 준) **명령 하나**를 댈 수 있고,
그 명령이
- [ ] **red-capable**: 실제 버그 코드 경로를 몰고 사용자의 정확한 증상을 단언한다
- [ ] **deterministic**: 매번 같은 판정. flaky면 **라운드 단위 ≥90% red**를 기준으로 삼고
  바이너리/서브테스트 단위 재현율도 함께 적는다(단위마다 다르므로 하나만 쓰면 판정이 갈린다)
- [ ] **fast**: 분이 아니라 초
- [ ] **agent-runnable**: 무인 실행 가능

seam(어느 테스트·어느 단언)을 고르기 위해 테스트와 대상 코드를 읽는 것은 필요하다. 그러나
이 명령이 생기기 전에 **원인 이론**을 세우고 있다면 **멈춘다** — 가설로 바로 뛰는 것이 이 스킬이
막는 실패다.

### 2단계: 재현 + 최소화

루프를 돌려 red를 본다. 사용자가 말한 그 실패인지(근처의 다른 실패가 아닌지), 여러 번 재현되는지,
정확한 증상(에러 메시지, 잘못된 출력, 느린 시간)을 캡처했는지 확인한다.

red가 되면 **red가 유지되는 가장 작은 시나리오**로 줄인다. 입력·호출자·설정·데이터·단계를
하나씩 잘라내고 매번 루프를 다시 돌려, 실패에 필요한 것만 남긴다. 부하 의존 flake의 "입력"은
환경 축이다: 병렬도 K, `-race`, 파일 신선도, OS 상태를 하나씩 빼 본다. 남은 요소를 하나라도 빼면
green이 될 때 끝이다. 최소 재현은 3단계의 가설 공간을 줄이고 5단계의 회귀 테스트가 된다.

```go
// 버그 재현 테스트 — 수정 전 FAIL, 수정 후 PASS
func TestBug_IssueNumber_ReproductionTest(t *testing.T) {
    // Given: 버그 발생 조건
    // When: 버그 트리거 동작
    // Then: 기대한 동작 (현재는 실패)
}
```

### 3단계: 가설

테스트하기 전에 **순위 매긴 가설 3~5개**를 만든다. 하나만 만들면 처음 그럴듯한 생각에 닻을
내린다. 각 가설은 **반증 가능**해야 한다 — 예측을 말한다:

> "X가 원인이면 Y를 바꿨을 때 버그가 사라진다 / Z를 바꾸면 더 나빠진다."

예측을 말할 수 없으면 가설이 아니라 감이다. 버리거나 벼린다. 가설마다 **이미 관측된 찬/반
증거**를 적어, 반증된 가설과 미검증 가설이 같은 모양으로 보이지 않게 한다. **순위 목록을 사용자에게 먼저
보여 준다** — 도메인 지식으로 즉시 재정렬되는 일이 많다. 사용자가 자리에 없으면 자기 순위로
진행한다.

### 4단계: 계측

각 probe는 3단계의 특정 예측에 대응한다. **한 번에 변수 하나만** 바꾼다.

도구 우선순위: (1) 디버거/REPL — breakpoint 하나가 로그 열 개보다 낫다, (2) 가설을 가르는
경계에만 두는 targeted log, (3) "전부 찍고 grep"은 하지 않는다.

**모든 디버그 로그에 고유 접두어를 붙인다**(예: `[DEBUG-a4f2]`). 정리가 grep 한 번이 된다.
태그 없는 로그는 살아남고 태그된 로그는 죽는다.

**성능 회귀**에는 로그가 대개 틀린 도구다. 기준 측정(타이밍 harness, profiler, query plan)을
먼저 만들고 bisect한다. 먼저 재고, 그다음 고친다.

도구 활용:
```bash
# Go: 레이스 컨디션 탐지
go test -race ./...

# 스택 트레이스 분석
go test -v -run TestBug 2>&1

# pprof 프로파일링
go test -cpuprofile cpu.out -memprofile mem.out
```

근본 원인 분류:
- **로직 오류**: 조건문, 계산 실수
- **경계 조건**: 빈 입력, 최대값, 최소값
- **동시성**: 레이스 컨디션, 데드락
- **타입/변환**: 오버플로우, nil 포인터
- **외부 의존성**: API 변경, 설정 오류

Caller/shared root-cause rule:
- 증상 위치(symptom location), owning function/path, caller 목록 또는 grep evidence를 기록합니다.
- caller와 shared root-cause path를 먼저 확인한 뒤 패치 위치를 선택합니다.
- 증상 위치만 패치하고 caller/shared root-cause evidence가 없으면 patch plan을 `revise-target`으로 표시합니다.
- evidence가 증상 위치 자체가 root cause이거나 affected caller가 하나뿐임을 보여줄 때만 focused patch를 허용합니다.

### 5단계: 수정 + 회귀 테스트

회귀 테스트를 **수정 전에** 쓴다 — 단, **올바른 seam**이 있을 때만. 올바른 seam은 버그가
호출 지점에서 실제로 일어나는 패턴을 그대로 밟는 자리다. 쓸 수 있는 seam이 너무 얕으면
(여러 호출자가 필요한 버그에 단일 호출자 테스트, 트리거 체인을 재현 못 하는 unit test) 그 자리의
회귀 테스트는 거짓 확신이다. **올바른 seam이 없다는 것 자체가 발견이다.** 기록하고 다음 단계로
넘긴다 — 코드 구조가 버그를 잠그지 못하게 막고 있다.

seam이 있으면: 최소 재현을 그 seam의 실패 테스트로 만든다 → 실패를 본다 → 수정 → 통과를
본다 → 1단계 루프를 원래(최소화 전) 시나리오로 다시 돌린다.

```
수정 원칙:
- 버그 수정에만 집중 (리팩토링 금지)
- 가능한 한 작은 변경
- 사이드 이펙트 최소화
```

### 6단계: 검증과 정리

```bash
# 재현 테스트 통과 확인
go test -run TestBug -v

# 회귀 테스트 실행
go test ./...

# 레이스 컨디션 재확인
go test -race ./...
```

## 체크리스트

- [ ] tight하고 red-capable한 피드백 루프 명령 하나를 실행해 보였다
- [ ] 사용자의 증상 그대로 재현하고 최소화했다
- [ ] 반증 가능한 가설 3~5개를 순위 매겨 사용자에게 보였다
- [ ] caller/shared root-cause path 확인 또는 `revise-target` 기록
- [ ] 회귀 테스트 작성(또는 올바른 seam 부재 기록) 및 수정 전 FAIL 확인
- [ ] 최소 수정 적용, 회귀 테스트 PASS, 원래 시나리오 루프 green
- [ ] `[DEBUG-...]` 계측 전부 제거(`grep` 접두어), throwaway harness 삭제
- [ ] 전체 테스트 스위트 통과
- [ ] 커밋 메시지에 이슈 번호와 **맞은 것으로 판명된 가설**을 남겨 다음 사람이 배우게 한다

1단계 루프 구성·조이기와 3~6단계 규율은 mattpocock/skills `diagnosing-bugs`(MIT)에서 가져와 다듬었다.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.