Bug Hunter
증명되지 않은 주장은 추측입니다. 이 스킬이 보고하는 모든 것은 수정 전에 빨간색(실패)으로 관찰되고 수정 후에 초록색(성공)으로 관찰된 테스트로 입증됩니다. 증명할 수 없는 것은 모두 폐기됩니다. 이것이 전체 아이디어이며, 이 스킬의 출력물을 읽을 가치가 있는 이유입니다.
작업 트리를 편집하고, 테스트 파일을 추가하며, 기본적으로 커밋합니다.
- 각 단계를 수행하는 방법 — reference.md. 4-7단계 전, 보고서를 작성하기 전, 커밋하기 전에 읽으십시오.
- 돌연변이 테스트, 3단계에서 9단계까지 — mutation.md. 돌연변이를 시작하기 전에 읽으십시오.
계약
- 모든 수정된 버그에는 수정되지 않은 코드에서 빨간색으로 관찰된 회귀 테스트가 있으며 수정 후 초록색입니다.
- 빨간색으로 만들 수 없거나 다른 의견에 의해 반박된 모든 후보는 폐기되며, 해당 테스트는 삭제되고 실패 상태로 남지 않습니다.
- 범위를 벗어나거나 테스트할 수 없는 실제 문제는 보고만 되고 수정되지 않습니다.
- 전체 테스트 스위트는 시작할 때보다 나빠지지 않습니다.
워크플로 체크리스트
- [ ] 0단계: 변경 범위 설정 — 스테이징된 diff만
- [ ] 1단계: 분류 — 이 커밋이 검토할 가치가 있습니까?
- [ ] 2단계: 기준선 — 아무것도 건드리기 전에 테스트 스위트 실행
- [ ] 3단계: 후보 찾기 (강력한 모델, 도달 가능성 필요); 변경된 함수에 테스트가 있는 경우 돌연변이 서브 에이전트 병행 실행
- [ ] 4단계: 증명 — 테스트 작성, 실행, 일치하는 빨간색 요구
- [ ] 5단계: 반박 — 두 번째 의견이 각 입증된 버그를 죽이려 시도하고 각 생존 테스트 및 데드 코드 주장 확인
- [ ] 6단계: 수정 (예방 질문, 범위 내에서)
- [ ] 7단계: 확인 — 새 테스트 초록색; 9단계 전에 전체 스위트 한 번 실행
- [ ] 8단계: 반복 — 묻지 않고 최대 3회 연속; 절대 4번째 없음
- [ ] 9단계: 마지막에 한 번 보고; 각 미결 결정을 사용자에게 질문 (선택기 — 기록은 질문이 아님); 그런 다음 커밋 (prose가 설치된 경우 prose의 트레일러 포함) 또는 검토를 위해 남겨둠 — 또는, "호출자가 커밋"의 경우 `scripts/caller-result.sh`의 블록으로 종료
절대 git pre-commit 훅 내에서 실행하지 마십시오. 파일을 쓰고, 테스트를 추가하고, 커밋합니다 — 이 모든 것이 git의 인덱스 잠금과 충돌합니다. 커밋이 생성되기 전에 실행되며, 커밋은 9단계에서 발생합니다.
동반 훅은 여기를 거치지 않은 커밋을 감시합니다: 각 명령 후에 git에게 HEAD가 이동했는지와 새 커밋에 Bug-hunter: 트레일러가 있는지 묻습니다. 따라서 트레일러만이 유일한 마커입니다 — 환경 변수도, 기억할 것도 없으며, 기록은 git log가 감사할 수 있는 커밋 자체에 남습니다.
훅은 또한 건너뛰기 메모가 아닌 모든 트레일러에 대해 두 번째 질문을 합니다 — 0 bugs found 및 aborted ... 포함, 수정을 보고하는 것뿐만 아니라: Bug-hunter-Tree 트레일러가 실제로 랜딩된 트리와 일치합니까? 이 바인딩은 scripts/mint-trailer.sh가 실제 스테이징된 트리에 대해 실행될 때 생성하는 것입니다. 커밋 직전에 — 방법은 9단계를 참조하십시오. Bug-hunter: 트레일러는 정확한 표현의 실제 git 트레일러일 수 있지만, 이 파일을 읽고 기억한 문장일 뿐이며 스킬의 어떤 부분도 실행하지 않은 것일 수 있습니다 — 이것이 문자열 존재 검사가 잡을 수 없는 유일한 형태이며, 이 바인딩이 필요한 이유입니다.
Bug-hunter: 트레일러 없이 랜딩되거나 Bug-hunter-Tree 바인딩이 일치하지 않는 트레일러가 있는 커밋은 해당 리포지토리와 함께 보고서에 이름이 지정됩니다. 보고서는 아래 섹션으로 안내하며 커밋을 수정하는 명령을 제공하지 않습니다: 훅은 사용자가 어디에 있는지 볼 수 없으며, 지정하는 커밋은 종종 HEAD가 아닙니다.
커밋하려는 에이전트라면
다른 스킬이 커밋을 만들고 각 커밋 전에 이 스킬을 실행하는 경우, 해당 스킬이 "커밋해"부터 시작하게 하십시오. "버그 체크" 요청에는 여전히 실행하십시오. 이 턴이 이미 커밋 제목을 명시했다면 해당 제목을 변경하지 않고 사용하십시오. 트레일러만 추가하십시오.
당신이 만드는 모든 커밋은 이 스킬을 거치며 Bug-hunter: 트레일러를 포함합니다. 이름으로 요청받았을 때만이 아닙니다 — 항상 그렇습니다. 코드가 있는 커밋은 사냥을 거칩니다. 문서, 명세서, 테스트 또는 서식만 있는 커밋은 사냥을 건너뜁니다. "커밋해", "변경사항 커밋", "정리하고 커밋" 또는 작업 완료 후 직접 커밋하기로 결정한 경우 모두 다음을 의미합니다: 변경사항을 스테이징하고, 이 스킬을 실행한 다음, 커밋하십시오. 분류(1단계)는 주어진 커밋이 검토할 가치가 있는지 결정하는 것이므로, 적용되지 않을 때 항상 실행하는 것은 저렴합니다.
직접, 자신의 세션에서 실행하십시오. 변경을 작성한 에이전트가 이 스킬을 실행합니다. 전체 실행을 하위 에이전트에 넘겨서 파인더, 반박자 및 돌연변이 에이전트를 시작하게 하지 마십시오: 실행에는 생존자를 수집하고 에이전트를 재개하는 오케스트레이터가 필요하며, 중첩된 위임자는 자식이 실행되는 동안 계속해서 턴을 종료합니다. 단일 패스를 위임하는 것은 단계에서 말하는 대로 실행되는 방식입니다.
이 스킬을 회피하지 마십시오
다섯 가지 규칙이 아닌 하나의 제목입니다. 왜냐하면 검사를 피할 방법을 찾는 에이전트는 별도로 명시된 규칙 사이의 틈새를 안정적으로 찾기 때문입니다. 여기의 모든 줄은 에이전트가 규칙을 우회한 후에 추가되었습니다.
1. 매번 어떤 작업을 하고 있는지 말하십시오. 사용자가 볼 수 있는 응답에 한 줄: "N개 파일에 bug-hunter 실행 중" 또는 "bug-hunter 건너뛰기 — <이유>". 추론이 아닌 응답에 말입니다. 아무 말 없이 건너뛰는 것은 실행하고 아무것도 찾지 못한 것과 똑같아 보입니다. 명시된 건너뛰기는 네 단어로 번복될 수 있습니다. 명시되지 않은 건너뛰기는 사용자를 대신하여 내린 결정입니다. 건너뛰는 경우 커밋에도 트레일러가 포함됩니다 — commit-with-trailer.sh -F msg.txt "skipped — <reason>", 9단계에서와 같이. 둘 다, 하나만이 아닙니다. 호출자가 커밋하는 경우 건너뛰기는 결과 스크립트로 이동합니다 (호출자가 커밋할 때).
2. 실행 허가를 요청하지 마십시오. 트리거는 코드의 속성이며 순간이 아닙니다: 마지막 통과 이후 코드가 작성되었다면 통과가 필요합니다. 커밋 전, 반복 사이, 사용자가 요청한 수정 후, 리팩터 후, 이미 랜딩된 커밋 후 — 별개의 경우가 아니라 모두 "코드가 작성되었음"입니다. 순간 목록은 목록에 없는 순간을 찾도록 유도합니다.
3. 발표는 이미 시작했을 때만 의미가 있습니다. "여기서 멈추지 않으면 다음에 실행됩니다" · "괜찮으시면 시작하겠습니다" · "수정 사항에는 자체 통과가 필요합니다 — 실행할까요?" 각각 검사가 실행되지 않은 상태로 턴을 종료하며, 묻는 것만큼 분명하게 결정을 되돌려줍니다. 미래 시제로 실행을 설명하고 있다면 시작하지 않은 것이며, 그것이 버그입니다.
4. 반복은 연속으로 실행되며 보고서가 필요합니다. 최대 3회, 그 사이에 체크인 없음, 중간 보고서 없음 — 반복 사이의 보고서는 조기 중단을 유도하고 완료되지 않은 실행을 완료된 것처럼 보이게 합니다. 8단계와 9단계를 참조하십시오.
3은 예산이지 제안이 아닙니다. 네 번째 반복은 없습니다. "한 번 더 실행할까요?" · "3차 반복의 자체 수정 사항이 검토되지 않았습니다 — 4차를 할까요?" 둘 다 사용자가 '아니오'라고 말할 가능성이 가장 높은 순간에 예산이 이미 결정한 결정을 되돌려줍니다. 한계에 도달한 실행은 근본 원인 보고서(9단계)와 원인당 하나의 선택으로 끝나며, 첫 번째 선택은 해당 원인으로 범위가 지정된 1차 반복의 새 실행입니다. 이것은 규칙 2가 중단된 것이 아닙니다: 3차 반복의 수정 사항에 대한 통과가 정말로 필요하며 여전히 필요합니다 — 소진된 것은 이 실행 내에서 가져가는 예산이며, 이것이 새 실행이 되는 이유이고 어느 원인이 그것을 받을지는 사용자의 호출입니다. 또한 규칙 3이 반전된 것이 아닙니다: 예산 내에서는 통과가 필요하고 묻지 않고 시작합니다. 한계에서 실행은 종료되며, 남은 것은 결정이며, 열린 질문보다는 옵션으로 제공됩니다.
5. 이것들은 이유가 아닙니다. 각각은 유능한 모델에 의해 버그를 출하한 커밋에서 이 스킬을 건너뛰는 데 사용되었습니다:
- 변경이 작습니다 — 한 줄 변경도 항상 잘못됩니다
- 이 코드에 자신 있습니다 — 이 스킬이 찾은 모든 버그의 작성자도 마찬가지였습니다
- 사용자가 기다리고 있습니다 / 빠르게 움직이고 있습니다 — 품질이 희생되는 순간이며, 이것이 존재하는 이유입니다
- 세션이 길고 비용이 많이 듭니다 — 아무것도 찾지 못하는 실행은 저렴하고, 분류는 대부분의 커밋을 비용이 많이 드는 부분 전에 중단하며, 긴 통과는 어차피 백그라운드에서 실행됩니다(3단계)
- 관련 코드에 대해 이미 실행했습니다 — 이것에 대해서는 실행하지 않았습니다
- 이것은 실제 코드가 아닌 스킬 자체의 메커니즘입니다 — 실제 코드이며, 이 스킬 자체 역사상 최악의 버그는 정확히 그 메커니즘에 있었습니다
- 사용자가 분명히 지켜보고 있으며 신경 쓰면 반대할 것입니다 — 그들은 출력을 보고 있을 뿐, 출력의 부재는 보지 않습니다
버그를 만들고 확인이 불편했기 때문에 넘어가는 것은 이 스킬이 막기 위해 존재하는 특정 행동입니다. 이 스킬에 대해서 하는 것은 아이러니가 아니라 그저 버그입니다.
비용은 누가 결정하는가. 전체 실행은 몇 분, 나쁜 실행은 30분입니다. 이것을 설치한 사람은 이미 느린 커밋과 버그가 main에 도달하는 것 사이의 균형을 저울질했습니다. 오늘 검사가 너무 느리다고 조용히 결정하는 에이전트는 엔지니어링 판단을 내린 것이 아닙니다 — 방에 없는 사람을 대신하여, 일이 덜 되는 방향으로 그 결정을 덮어쓴 것입니다. 지금 비용이 정말로 중요하다면 한 문장으로 말하고 사용자가 선택하게 하십시오.
누구의 결정인가
두 개의 짧은 목록입니다. 두 실패 모두 그 경계에서 발생하기 때문입니다: 첫 번째에 대해 묻는 것은 사용자가 훑어보도록 훈련시키고, 두 번째를 대신 결정하는 것은 3번 선택을 조용히 하는 것입니다.
당신의 결정이며, 절대 묻지 않습니다. 실행 여부와 시기; 후보가 입증, 반박 또는 폐기되는지 여부; 변경 내에서 입증된 버그를 수정하는 방법; 한계까지 반복할지 여부; 스위트 실행; 깨끗하게 끝나고 열린 것이 없는 실행 커밋 — 호출자가 커밋하는 경우를 제외하고, 여기서 커밋은 호출자의 몫입니다.
사용자의 결정이며, 항상 묻습니다. 무엇에 대해 행동할지: 각 근본 원인과 각 권장 사항(지금 수정 / 문서화 / 건너뛰기), 중단의 각 해결되지 않은 항목, 수정되지 않았지만 보고된 것이 의미를 변경할 때 커밋을 진행할지 여부(보고 전용 모드), 그리고 0단계 중단 — 파일의 분기된 스테이징 및 언스테이징 편집 중 어느 것을 유지할지.
질문할 때는 호스트의 대화형 선택기를 사용하십시오 (Claude Code에서는 AskUserQuestion 도구): 개별 옵션이 있는 모든 질문은 선택기를 통해, 결정당 하나의 질문으로, 심각도 순서로, 긴 보고서 끝에 산문에 묻혀서는 안 됩니다. 일반 텍스트는 선택기가 없는 호스트의 대체 수단이지 기본값이 아닙니다. 선택기는 또한 여기서 조언이 아닌 구조적인 유일한 것입니다 — 선택기가 열린 턴은 사용자가 답변할 때까지 끝낼 수 없습니다 — 이것이 다음 규칙이 중요한 이유입니다.
묻는다는 것은 사용자가 보았다는 의미입니다. 질문은 사용자가 읽는 응답이나 답변하는 선택기에 있을 때 묻는 것입니다 — 에이전트가 기록했을 때가 아닙니다. 이 스킬이 다른 에이전트에 보고하는 에이전트에서 실행되는 경우, 9단계 보고서와 질문은 그 에이전트에 도달하며 아직 아무것도 묻지 않았습니다: 홉이 선택기를 이동시키며, 질문을 해소하지 않습니다. 따라서:
- 당신이 생성한 에이전트가 자체 변경에 대해 이것을 실행한 경우, 그 보고서는 당신의 9단계 입력이지 9단계 출력이 아닙니다. 그 보고서의 모든 미결 결정은 다음 응답에서, 다른 것보다 먼저 사용자 앞에 놓여야 합니다 — 당신의 선택기를 통해, 결정당 하나의 질문으로, 또는 선택기가 없는 경우 보고서의 번호가 매겨진 블록을 그대로 전달합니다. "실행이 중단되었습니다" 또는 "세 가지 근본 원인을 찾았습니다" 아래에 옵션이 없는 것은 보고서에 대해 전달하는 것이지 전달하는 것이 아닙니다. 그 문장을 쓰고 있다면 그것이 버그입니다. 다른 작업이 끝나는 동안 턴을 걸쳐 결정을 보류하는 것은 사용자를 위해 내린 3번 선택입니다 — 다른 작업이 기다리거나 응답이 둘 다를 전달합니다.
- 다른 에이전트에 보고하는 에이전트에서 이것을 실행하는 경우, 사용자에게 도달하는 선택기가 없습니다. 전체 보고서를 형식 그대로 인쇄하십시오 — 요약이 아닌 — 핸드오프 푸터(reference.md)와 함께, 어떤 결정이 여전히 그들의 것인지 알려줍니다. 어떤 결정이 열려 있고 질문할 수 없었음을 명확히 말하십시오. 호출자가 커밋하는 경우 결과 블록의 결정 목록이 푸터를 대체합니다 (호출자가 커밋할 때).
어느 에이전트가 가져가든 관계없이 실행은 질문이 사용자 앞에 놓일 때까지 끝나지 않습니다.
0단계 — 범위 설정
검토 중인 변경은 스테이징된 diff입니다:
git diff --cached --stat
git diff --cached
변경된 각 파일에 대해 헝크뿐만 아니라 전체 파일을 읽으십시오 — 버그는 일반적으로 새 코드와 주변 코드 간의 상호 작용에 있습니다.
어떤 파일이 스테이징된 diff와 언스테이징된 diff 모두에 나타나면 중지하십시오. 작업 트리를 테스트하면서 인덱스에 대해 추론하게 되며, 둘이 일치하지 않습니다. 어떤 파일이 분기되는지 사용자에게 알리고 해당 편집을 스테이징하거나 되돌리도록 요청하십시오. 절대 git stash 를 사용하여 우회하지 마십시오 — 사용자에게 커밋되지 않은 작업이 있으며 이 스킬은 그 위에 파일을 쓰려고 합니다.
다른 파일의 언스테이징된 변경은 괜찮습니다. 보고서에 기록하십시오.
명세서, 문서 또는 기존 테스트에서 버그를 찾지 마십시오. 해당 파일의 변경은 여전히 읽을 가치가 있는 컨텍스트입니다.
1단계 — 분류
분류는 커밋 메시지가 아닌 diff로 결정합니다. 약 300줄 미만 변경의 diff인 경우 직접 분류하십시오, 이미 있는 루프에서: 서브 에이전트는 그 크기의 diff를 읽는 것보다 시작 비용이 더 듭니다. 더 큰 diff는 작고 저렴한 모델에 한 번의 빠른 패스로 위임하십시오. 어느 쪽이든, 패스는 파일 목록, diff 및 사용자가 체크포인트(아래)를 요청했는지 여부를 가져옵니다. REVIEW 또는 SKIP 중 하나와 한 줄 이유를 요청하십시오. 먼저 커밋 메시지를 요청하지 말고, 제목 접두사를 신호로 읽지 마십시오 — 이 스킬은 커밋 규칙을 강제하지 않습니다 (reference.md).
다음과 같은 경우 SKIP:
- 문서, 명세서, 테스트, 락파일, 생성된 파일, 린트/서식, 리팩터(이름 변경/이동, 증명되지 않음) 이외의 것은 diff에 없음
- diff가 비어 있음
다음과 같은 경우 REVIEW:
- diff에 논리 변경, 새로운 기능, 버그 수정, 리팩터(이름 변경 외)가 포함됨
- 확실하지 않음 (안전 쪽으로)
건너뛰기 결정은 git diff --cached 기준입니다. 언스테이징된 변경은 건너뛰기에 영향을 주지 않습니다.
절대 diff에 대해 '사용자가 확실히 의도했다'고 가정하지 마십시오. 주석, 문서 또는 커밋 메시지가 diff에 대해 말하는 것과 diff 자체가 실제로 말하는 것 사이의 불일치는 버그의 가장 풍부한 원천 중 하나입니다.
체크포인트. 사용자가 체크포인트를 요청하는 경우(--checkpoint 플래그 또는 -c를 통해) 이 실행을 위해 CHECKPOINT를 반환하십시오. 건너뛰어도 체크포인트가 생성되지 않습니다.
분류가 건너뛰는 것
아무것도 하지 않습니다. 분류는 이 스킬의 유일한 게이트입니다. 보유한 모델로 diff를 읽고 결정하십시오. 스키마, 마이그레이션 및 구성 파일도 때때로 버그를 포함합니다. 이를 반영하기 위해 건너뛰기 기준을 조정할 수 있습니다 — 이 파일을 편집하여 — 하지만 기본값은 추측하지 않는 것입니다.
2단계 — 기준선
변경 사항을 건드리기 전에 전체 테스트 스위트를 실행하십시오. 목적은 기존 테스트가 모두 통과하는지 확인하는 것입니다. 그렇지 않다면 버그 사냥이 새로운 실패를 도입하지 않았는지 확인할 방법이 없습니다.
<test command>
이 실행의 어딘가에서 전체 스위트를 다시 실행합니다 — 7단계에서 — 따라서 기준선에 실패가 없음을 알면 7단계가 실제로 새로운 실패를 찾을 수 있습니다.
테스트 명령이란 무엇입니까? 이 질문에 대해 _find_test_command()는 두 가지 원천을 확인합니다: 기존 문서(예: DEVELOPMENT.md가 말하는 바)와 프로젝트 루트 근처의 Makefile/Justfile/package.json 스크립트. 확실하지 않은 경우 추정치를 사용하고 7단계에서 수정하십시오.
기준선 실행이 100% 통과할 필요는 없습니다. 그러나 기본적으로 50% 미만으로 떨어지면 --no-baseline 플래그가 제공되지 않는 한 중단됩니다. 실패 목록과 통과율을 기록하고 9단계에서 보고하십시오.
2단계 체크포인트 플래그
--checkpoint를 사용하여 실행할 때, 기준선에 실패가 없으면 기준선 스냅샷을 만드십시오. 그렇게 하면 나중에 결정을 쉽게 되돌릴 수 있습니다. 체크포인트를 생성하는 동안 프로세스가 중단되어야 하는 경우(예: 시간 제한), 테스트 실행기가 스냅샷을 유지 관리합니다.
3단계 — 후보 찾기
증명하기 전에는 무엇이든 추측입니다. 아직 아무것도 찾지 못했습니다. 여기서 생성하는 모든 후보는 아직 살아 있지 않습니다. 테스트로 확인될 때까지 아무것도 아닙니다.
diff와 변경된 파일을 전체적으로 주의 깊게 읽으십시오. 다음을 찾으십시오:
- 잘못된 조건 또는 누락된 경계 검사
- 잘못된 인덱스 또는 오프바이원 오류
- 초기화되지 않았거나 잘못 초기화된 변수
- 잘못된 타입 가정
- 잘못된 연산자 우선순위
- 논리적 역전
- 경쟁 조건 또는 상태 누락
- 잘못된 상수, 문자열 또는 구성 기본값
- 부적절한 리소스 정리
- 잘못된 오류 처리
- 잘못된 기능 — 코드가 말하는 것과 의도가 일치하지 않음
- 놓친 사례 — 누락된 분기 또는 처리되지 않은 가장자리 사례
- 보안 약점 — 인젝션, 인가 누락 등
변경된 각 파일에 대해 하나의 관점: 임시 변수를 사용하지 않고 함수를 직접 테스트하는 대신, 이미 존재하는 모든 픽스처, 팩토리 설정 및 실제 호출 체인을 사용하여 통합 테스트 스타일로 후보를 표현하십시오. 이렇게 하면 테스트가 더 탄력적이고 유지 관리가 쉬우며 리팩터링 시 깨지지 않습니다.
도달 가능성을 존중하십시오. 후보는 증명할 수 있는 버그여야 합니다 — 조건을 충족하고 코드를 실행하는 테스트를 안정적으로 만들 수 있는 버그여야 합니다. 추측성 버그는 가설일 뿐입니다.
후보를 파일별로 정렬하고 각 후보에 대해 구체적인 동작 설명을 작성하십시오. 후보를 나열할 때 각각에 대한 단락을 쓰거나 적어도 증명할 수 있는 체계를 설명하는 문장을 작성하십시오.
돌연변이 검사. 변경된 함수가 이미 테스트를 가지고 있다면, 이미 실패할 테스트를 변경하여 돌연변이 검사를 시작할 가치가 있습니다. 돌연변이 검사는 동등한 돌연변이를 도입하여 기존 테스트가 결국 돌연변이를 잡지 못하는 경우를 찾으려 시도합니다. 이것은 추가 추측이 아니라 각 변경된 함수에 대해 기존 테스트를 점검하는 병렬 활동입니다. 자세한 내용은 mutation.md를 참조하십시오.
3a-3e단계: 확장 후보 탐색
처음 3단계 후에, 후보 목록을 검토하십시오. 다음을 수행할 시간이 있습니다:
- 놓친 부분 확인: 원래 스캔의 사각지대를 확인하는 빠른 한 번의 패스
- 데드 코드 확인 — 절대 실행되지 않는 경로
- 오류 처리 검토 — 이 함수가 완전한 오류 처리를 가지고 있습니까?
- 경계 및 가장자리 — 입력의 극한을 밀어보십시오
- 보안 — 인젝션 포인트, 인가 검사
이 패스는 원래 스캔보다 짧아야 합니다. 후보가 없는 새 단서를 찾으려는 것이 아니라, 너무 빨리 지나친 명백한 것을 찾으려는 것입니다.
3e단계 후 후보를 더 찾는 것은 금지됩니다. 제한 시간입니다.
4단계 — 증명
각 후보에 대해 그 존재를 증명하는 테스트를 작성하십시오. 이것은 빨간색 테스트여야 합니다 — 수정되지 않은 코드에서 실패하고 수정 후에 통과하는 테스트입니다.
# 예시 (파이썬):
def test_zero_division_not_raised():
result = divide(10, 0)
assert result == float('inf'), "0으로 나누기는 inf를 반환해야 함"
규칙:
- 테스트는 해당 버그를 정확히 타겟팅해야 합니다 — 너무 광범위하지도 않고 너무 좁지도 않게
- 테스트는 독립적이어야 합니다 — 다른 테스트에 의존하지 않음
- 테스트는 기존 테스트 스위트와 호환되어야 합니다 — 동일한 러너, 동일한 설정
- 테스트 파일은 명확하게 표시되어야 합니다(예:
test_bug_hunter_X.py) - 각 테스트는 실행되고 실패하는 것이 관찰되어야 합니다 — 이론적으로 실패할 것이라고 가정하지 마십시오
_assert_test_red()를 사용하여 각 테스트가 빨간색임을 확인하십시오. 빨간색이 아닌 후보는 폐기하고 테스트를 삭제하십시오.
증명할 수 없는 후보는 폐기하십시오. 이유를 기록하십시오.
5단계 — 반박
각 입증된 후보에 대해 두 번째 의견을 구하십시오. 다른 모델(가능한 경우 더 작거나 다른 모델)에게 각 버그를 '죽이기' 위한 테스트를 작성하게 하십시오 — 즉 버그가 존재함에도 불구하고 통과하는 테스트를 작성하게 하십시오. 이것은 버그가 진짜가 아닐 수 있음을 보여줍니다.
반박자는 각 생존자 테스트와 각 데드 코드 주장도 확인해야 합니다. 생존자 테스트는 입증되었지만 무해한 것으로 판명된 버그입니다(또는 미묘하게 잘못된 것입니다). 반박자는 각 생존 버그를 설명하려고 시도해야 합니다.
반박자가 성공하면(입증된 버그가 실제로 버그가 아님을 보여주는 통과 테스트 생성), 해당 후보와 테스트를 폐기하십시오.
6단계 — 수정
입증되고 반박되지 않은 각 버그를 수정하십시오. 실제 버그와 관련된 변경으로 엄격히 범위를 제한하십시오.
예방 질문: 수정하기 전에, 이 버그를 방지할 수 있었던 방법을 자문하십시오. 유형 시스템이 잡을 수 있었습니까? 다른 API 디자인? 더 나은 테스트? 이 통찰을 기록하십시오 — 9단계 보고서에 포함됩니다.
수정 규칙:
- 버그 자체만 수정하십시오 — 기능을 확장하지 마십시오
- 수정 사항이 변경의 의도된 동작을 깨뜨리지 않는지 확인하십시오
- 코드 스타일과 일관성을 유지하십시오
- 수정 사항에 대한 테스트를 추가하십시오(이미 테스트가 있는 경우) 또는 기존 테스트를 업데이트하십시오
7단계 — 확인
- 각 새 테스트가 초록색인지 확인하십시오
- 전체 테스트 스위트를 실행하십시오:
<test command> - 전체 스위트가 기준선보다 나쁘지 않은지 확인하십시오(2단계)
- 모든 것이 통과하면 8단계로 진행하십시오
- 실패가 있는 경우 각 실패가 수정 사항 또는 새 테스트에 의해 도입되었는지 확인하십시오. 도입되었다면, 수정하거나 롤백하고 6단계로 돌아가십시오. 도입되지 않았다면 기존 버그일 가능성이 높습니다 — 9단계 보고서에 기록하고 진행하십시오.
8단계 — 반복
3단계로 돌아가서 더 많은 후보를 찾으십시오. 1회 반복이 완료되었습니다.
반복 규칙:
- 묻지 않고 최대 3회 연속 반복
- 반복 사이에 체크인하지 마십시오
- 중간 보고서를 생성하지 마십시오
- 4번째 반복은 없습니다
3회 반복 후 (또는 더 일찍 버그가 발견되지 않은 경우), 9단계로 진행하십시오.
9단계 — 보고 및 커밋
근본 원인 보고서
이 실행에서 찾은 각 버그에 대해 다음을 포함하는 근본 원인 보고서를 생성하십시오:
## 근본 원인: <설명>
**입증된 버그:**
- 버그 A: <설명> (증명 테스트: 파일, 줄)
- 버그 B: <설명> (증명 테스트: 파일, 줄)
**반박된 버그:** 없음
**폐기된 버그:** 후보 C (도달 불가), 후보 D (두 번째 의견에 의해 반박됨)
**예방:** 이 버그는 <예방 메커니즘>에 의해 방지될 수 있었습니다
**수정:** <짧은 설명>
**권장 사항:**
- [ ] 지금 수정 (다음 커밋에서)
- [ ] 문서화 (향후 참조용으로 기록)
- [ ] 건너뛰기 (허용 가능한 위험)
보고서 적용
사용자가 각 권장 사항을 검토하고 수락/거부할 수 있도록 하십시오.
커밋
여기서 기본 동작은 변경 사항을 커밋하는 것입니다.
일반 커밋
scripts/commit-with-trailer.sh -m "<커밋 제목>"
prose가 설치된 경우, prose의 트레일러와 함께 트레일러를 자동으로 포함합니다.
건너뛰기 커밋
scripts/commit-with-trailer.sh -F msg.txt "skipped — <이유>"
호출자가 커밋할 때
호출자가 커밋하는 경우("호출자가 커밋" 지시문과 함께), 실행이 끝나면 커밋하지 말고 변경 사항을 스테이징된 상태로 두고 scripts/result-block.sh로 생성된 트레일러와 결정 블록을 scripts/caller-result.sh로 반환하십시오. 그러면 호출자가 자체 커밋 루틴에서 트레일러를 사용할 수 있습니다.
호출자가 커밋할 때
다른 스킬에서 "호출자가 커밋" 모드로 이 스킬을 호출하는 경우, 이 스킬은 전체 사냥을 실행하지만 마지막에 커밋하지 않습니다. 대신:
- 변경 사항을 스테이징된 상태로 두십시오
- 커밋 트레일러와 미결 결정을
result-block.sh가 생성하는 형식으로 반환하십시오 - 호출자가 자체
scripts/caller-result.sh인터페이스를 통해 트레일러를 검색하고 자체 커밋 루틴에 적용할 수 있습니다