| name | see-it-first |
| description | Forces reproduction before any fix. When something doesn't work, this skill stops the symptom→guess→patch loop and first reproduces the bug locally on the same branch, data, and inputs the user saw — because an unreproduced bug is an unsolved one. 버그·이상 동작 앞에서 추측 패치의 유혹을 끊고, 먼저 눈앞에 똑같이 재현하게 만드는 엔지니어링 철학 스킬. |
| when_to_use | Use whenever something doesn't work — phrases like "bug", "broken", "not working", "error", "doesn't work", "fix", "버그", "안 돼", "이상해", "에러", "왜 이러지", "고쳐줘" — and especially in intermittent or hearsay reports ("가끔 안 돼요", "어쩌다 한 번", "사용자가 이렇다는데", "PM이 메인 깨졌대요"), or when a fix is about to be attempted without a log, screenshot, or reproduction steps in hand. |
| allowed-tools | Read Bash Grep |
한 줄. 버그는 고치기 전에 재현한다. 못 본 버그는 고친 게 아니다.
Why this mindset
버그 앞에서 가장 큰 유혹은 증상 → 추측 → 패치입니다. 그러나 못 본 버그는 고친 게 아닙니다.
일단 내 눈앞에 똑같이 다시 띄우는 것에서 시작합니다. 재현이 되면 절반은 풀린 것입니다.
재현 안 되는 버그는 추측으로 사라진 게 아니라, 다음에 더 큰 모습으로 돌아옵니다.
Instructions
증상을 들으면 코드부터 펴고 싶어진다. 한 번 멈추고, 먼저 본다.
-
재현 조건을 받아 적는다.
언제·어디서·어떤 입력·어떤 결과·기대한 결과. 다섯 칸이 채워지면 재현은 거의 자동으로 따라온다. 비개발자에게 묻는 법: "조금 전에 어떤 화면에서 → 뭘 눌렀더니 → 뭐가 떴어요? 원래는 어떻게 돼야 했어요?"
-
같은 환경을 만든다.
같은 브랜치, 같은 데이터, 같은 입력. 다르면 다른 버그를 잡게 된다. 재현 환경 정렬이 안 되면 (a) 정렬을 먼저 하고, (b) 사용자에게 *"내 환경에선 이렇게 보여요 — 같아요?"*로 확인한다.
-
최소 재현으로 좁힌다.
재현되면 그 다음은 불필요한 단계를 하나씩 빼는 것. 10단계 → 7 → 4 → 2. 줄어들수록 원인은 분명해진다. "이거 한 줄만 있어도 터진다"까지 좁히면 가설은 거의 다 잡힌 거다.
-
재현된 다음에 가설을 세운다.
재현 전에 세운 가설은 추측이고, 재현 후에 세운 가설은 관찰이다. 둘은 정확도가 다르다. 추측 패치로 증상은 사라졌는데 원인은 모르는 상태는 가장 위험한 마무리다.
-
고친 뒤, 못 재현됨을 확인한다.
같은 조건으로 다시 돌려서 이번엔 안 터지는지를 본 뒤에 "고쳤다"고 말한다. 가능하면 그 재현 조건을 테스트로 남긴다 — 다음에 같은 자리가 또 무너지지 않게.
Examples
"가끔 안 돼요"를 좁히기:
- 사용자: "가끔 로그인이 안 된대요."
- Claude: "가끔을 좀 좁혀보자. (a) 특정 시간대인지, (b) 특정 브라우저인지, (c) 특정 계정인지, (d) 새 가입자인지 기존인지. 사용자에게 직전 단계 한 번 더 물어볼 수 있을까? 그거 있어야 재현돼."
전언으로 끝내지 않기:
- 사용자: "PM이 메인 페이지 깨졌대요."
- Claude: "내가 지금 메인 페이지 열어봤는데 잘 떠. 어떤 화면에서 깨졌는지·뭘 눌렀는지·스크린샷이나 에러 메시지가 있어야 같은 걸 보고 시작할 수 있어. PM한테 한 줄만 더 받아줄 수 있을까?"
재현된 다음:
- Claude: "재현했어 — 빈 검색어로 엔터 치면 터져. 원인은
query.trim() 호출이 빈 문자열일 때 다음 줄에서 query[0]을 읽어서 그래. 고쳤고, 같은 입력으로 다시 돌려봤는데 이번엔 안 터져. 빈 검색어 케이스 테스트 한 줄도 같이 넣어둘게."
Pitfalls
- 추측 → 패치 → 다시 발생 → 추측 → 패치… 무한 루프
- 재현 없이 "고쳤어요" 보고 → 며칠 뒤 같은 버그 재등장
- "가끔"·"이상하게" 같은 모호한 증상으로 시작해 안 좁히고 코드부터 뒤지기
- 재현이 어렵다고 재현을 건너뛰고 패치 → 보통 더 오래 걸린다
- 고친 뒤 못 재현됨을 확인 안 하기 → "맞아 진짜 안 터지는 건가?"
버그는 적이 아니다. 증거다. 잘 보이는 자리에 갖다 놓으면, 그 다음은 코드가 답한다.