Communitygithub.com

wangnan0916/debug-mode-skill

에이전트 독립적인 디버그 모드 스킬로, 로컬 NDJSON 로그를 수집합니다.

debug-mode-skill란 무엇인가요?

이 스킬은 AI 에이전트(Claude Code, Cursor, Codex 등)가 사용자의 명시적인 디버그 모드 요청('debug-mode', '$debug-mode', 'debug mode', 'instrumented debugging')에 응답하여 임시 런타임 계측을 통해 버그의 근본 원인을 체계적으로 추적할 수 있도록 설계되었습니다. 모든 에이전트와 호환되며, 가설-기반 디버깅 루프를 실행합니다: 관련 코드를 읽고, 2-5개의 순위가 있는 가설을 세우고, 로컬 루프백 수집기를 재사용하여 3-8개의 타겟 프로브를 추가하고, 수동 재현 체크포인트를 거친 후 로그를 분석하여 최소한의 수정만을 적용합니다. Node.js, Python, 브라우저 JavaScript 환경을 지원하며, 핵심 규칙으로는 체크포인트 생략 금지, 추측에 의한 수정 금지, 설정 전 프로브 제거 금지, 민감 정보 로깅 금지 등이 있습니다. 프로브는 `#region DEBUG_MODE_PROBE` 마커로 감싸져 있어 정리 작업이 기계적으로 이루어집니다. 또한, 가설 분류(확인/기각/불명확)를 요약하고, 문제 해결 가이드와 정리 체크리스트를 제공하여 체계적이고 반복 가능한 디버깅 워크플로우를 보장합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add wangnan0916/debug-mode-skill

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Debug Mode (디버그 모드)

이 스킬은 사용자가 명시적으로 debug-mode, $debug-mode, debug mode, 또는 instrumented debugging을 호출한 경우에만 사용하세요.

사용자가 명시적으로 동의하지 않았다면 일반적인 디버깅을 수행하세요. 이 스킬은 임시 런타임 계측이 실질적으로 도움이 될 때만 언급하세요.

Core Loop (핵심 루프)

가설 기반 디버깅 루프를 실행하세요:

  1. 관련 코드, 재현 세부 정보 및 기존 로그를 읽습니다.
  2. H1, H2, H3과 같은 ID와 함께 2-5개의 순위가 있는 가설을 나열합니다. 각 가설은 런타임 프로브가 무엇을 보여줄지 예측해야 합니다.
  3. 루프백 수집기(Collector Contract)를 시작하거나 재사용합니다.
  4. 가설을 구분할 수 있는 3-8개의 타겟 프로브를 추가합니다. stdout/stderr가 아닌 DEBUG_URL + "/log"로 전송되는 구조화된 이벤트를 사용하세요. 아래의 Event Shape, Region Markers 및 Helpers를 따르세요.
  5. 수동 체크포인트에서 멈춥니다. Checkpoint Template을 보냅니다. 사용자가 A, B, 또는 C로 응답할 때까지 프로브를 분석, 수정 또는 제거하지 마세요.
  6. A 응답 후에, 출력된 LOG_FILE을 검사하고 각 가설을 CONFIRMED, REJECTED, 또는 INCONCLUSIVE로 분류한 다음, 로그가 근본 원인을 설명하는 경우에만 최소한의 수정을 가합니다. 아래의 Evidence Summary를 따르세요.
  7. 수정 후 한 번의 실행(runId: "post-fix" 태그 포함) 동안 프로브를 활성 상태로 유지합니다.
  8. 사용자가 수정 후 체크포인트에 B로 응답한 후, 모든 계측을 제거하고 관련 검사를 실행합니다. 아래의 Cleanup Checklist를 따르세요.

Hard Rules (엄격한 규칙)

  • 프로브를 추가한 후 수동 재현 체크포인트를 절대 건너뛰지 마세요.
  • 이 스킬이 활성화되어 있는 동안 추측으로 수정하지 마세요.
  • 사용자가 수정 후 확인을 완료하기 전에 프로브를 제거하지 마세요.
  • 디버그 로그나 임시 계측을 커밋하지 마세요.
  • 비밀, 토큰, 쿠키, 인증 헤더, API 키, 원시 요청 본문, 개인 데이터가 포함될 수 있는 원시 응답 또는 불필요한 개인 데이터를 절대 로깅하지 마세요.

Collector Contract (수집기 규약)

번들로 제공되는 수집기는 의도적으로 작습니다:

  • GET /health는 기존 수집기를 재사용할 수 있는지 확인합니다.
  • POST /log는 하나의 JSON 객체를 수락하고 하나의 NDJSON 라인을 비동기적으로 추가합니다. 유효성 검사 후 200을 반환합니다. 라인은 백그라운드에서 기록됩니다.
  • 다른 세션은 독립적인 큐로 별도의 파일에 기록되므로, 세션 간에 병렬로 기록을 진행할 수 있습니다.
  • 로그는 기본적으로 작업 공간 외부의 OS 임시 디렉토리에 저장됩니다.
  • --ensure는 DEBUG_URL, SESSION_ID, LOG_DIR, LOG_FILE 및 HEALTH_URL을 출력합니다.
  • 수집기는 첫 번째 이벤트에서 LOG_FILE을 생성합니다. 재현 후에는 touch, 사전 생성, 잘라내기 또는 지우지 마세요.
  • 수집기는 루프백 전용입니다. 0.0.0.0이나 공용 인터페이스에 바인딩하지 마세요.

다음과 같이 시작하거나 재사용하세요:

node <skill-dir>/scripts/log-server.mjs --ensure --session <session_id> --host 127.0.0.1 --port 0

로컬 포트 리스너를 차단하는 관리형 샌드박스에서는 첫 번째 시도에 에이전트의 일반 승인을 요청하세요. 이유를 이 루프백 전용 디버그 수집기를 시작하거나 재사용하는 것으로 한정하세요.

Checkpoint Templates (체크포인트 템플릿)

프로브를 추가한 후, 실제 세션 세부 정보와 함께 이 형식을 보내고 중단하세요:

debug-mode 프로브를 추가했으며 수집기가 기록 중입니다:

- 세션: <session_id>
- 로그 파일: <LOG_FILE>
- 디버그 엔드포인트: <DEBUG_URL>/log

버그를 수동으로 재현한 후 다음으로 답변해 주세요:

A - 재현됨
B - 수정됨
C - 기타; 발생한 상황 설명

수정 후 확인을 위해서는 시작 문장만 변경하세요:

수정 후 확인을 위해 debug-mode 프로브를 활성 상태로 유지했으며 수집기가 기록 중입니다:

- 세션: <session_id>
- 로그 파일: <LOG_FILE>
- 디버그 엔드포인트: <DEBUG_URL>/log

원래 버그를 수동으로 확인한 후 다음으로 답변해 주세요:

A - 재현됨
B - 수정됨
C - 기타; 발생한 상황 설명

체크포인트 응답을 작은 상태 머신으로 해석하세요:

  • 수정 전 A: NDJSON 로그를 읽고, 가설 증거를 분류한 다음, 확인된 원인만 수정하거나 더 좁은 프로브를 추가합니다.
  • 수정 후 A: 버그가 여전히 재현되었습니다. 수정 후 로그를 읽고 더 좁은 가설이나 프로브로 계속 진행합니다.
  • 수정 전 B: 종료 상태가 아닙니다. 계측 하에서 버그가 재현되지 않았다는 증거로 취급하고 설명이나 더 좁은 재현을 요청합니다.
  • 수정 후 B: 프로브를 제거하고 최종 검사를 실행합니다.
  • 언제든지 C: 사용자의 텍스트를 증거로 취급합니다. 재현, 가설 또는 프로브를 조정합니다.

Event Shape (이벤트 형식)

구조화되고 낮은 볼륨의 이벤트를 사용하세요. 일반적인 이벤트는 다음과 같습니다:

{
  "session": "<session_id>",
  "runId": "pre-fix",
  "probe": "settings.beforePersist",
  "hypothesis": "H1",
  "file": "src/settings/save.ts",
  "fn": "saveSettings",
  "vars": {
    "enabled": true,
    "userId": "redacted"
  }
}

수정 전에는 runId: "pre-fix"를, 확인을 위해서는 runId: "post-fix"를 사용하세요. 높은 빈도의 경로의 경우 상태 변경 시에만 로깅하거나 적극적으로 샘플링하세요.

Region Markers (영역 마커)

모든 임시 계측을 감싸서 정리가 기계적으로 이루어지도록 하세요:

// #region DEBUG_MODE_PROBE <session_id> settings-before-persist
debugModeLog({
  probe: "settings.beforePersist",
  hypothesis: "H1",
  file: "src/settings/save.ts",
  fn: "saveSettings",
  vars: { enabled, userId: "redacted" },
});
// #endregion DEBUG_MODE_PROBE <session_id>

일반적인 주석 형식:

// #region DEBUG_MODE_PROBE <session_id> ...    JavaScript, TypeScript, Java, C#, Go, Rust, C, C++
# #region DEBUG_MODE_PROBE <session_id> ...     Python, Ruby, Shell, YAML
<!-- #region DEBUG_MODE_PROBE <session_id> -->  HTML, Vue, Svelte
/* #region DEBUG_MODE_PROBE <session_id> */     CSS 및 C-스타일 블록 컨텍스트
-- #region DEBUG_MODE_PROBE <session_id> ...    SQL, Lua

Helpers (도우미)

브라우저 또는 프론트엔드 JavaScript의 경우, assets/browser-log-helper.js를 표준 도우미 템플릿으로 사용하세요. 이를 계측된 모듈 또는 스크립트에 복사하고 <session_id>와 <DEBUG_URL>을 바꾼 후 함수 이름 debugModeLog를 유지하세요.

Node.js 또는 서버사이드 JavaScript의 경우, assets/node-log-helper.js를 표준 도우미 템플릿으로 사용하세요. 이를 계측된 모듈 또는 스크립트에 복사하고 <session_id>와 <DEBUG_URL>을 바꾼 후 함수 이름 debugModeLog를 유지하세요.

타사 종속성이 없는 Python의 경우:

# #region DEBUG_MODE_PROBE <session_id> debug-log-helper
import json
import urllib.request

DEBUG_MODE_URL = "<DEBUG_URL>/log"

def debug_mode_log(event):
    try:
        payload = {"session": "<session_id>", **event}
        data = json.dumps(payload).encode("utf-8")
        req = urllib.request.Request(
            DEBUG_MODE_URL,
            data=data,
            headers={"content-type": "application/json"},
            method="POST",
        )
        urllib.request.urlopen(req, timeout=0.5).close()
    except Exception:
        pass
# #endregion DEBUG_MODE_PROBE <session_id>

Evidence Summary (증거 요약)

A 응답 후, 코드를 편집하기 전에 증거를 요약하세요:

H1 API 호출 전에 설정 상태가 손실됨
상태: CONFIRMED (확인됨)
증거: settings.beforePersist가 enabled=false를 기록한 반면 UI 이벤트는 enabled=true를 기록했습니다.

H2 API가 값을 거부함
상태: REJECTED (기각됨)
증거: 이번 재현에서 API 호출이 발생하지 않았습니다.

다음 조치: onToggle과 saveSettings 간의 로컬 상태 핸드오프를 수정합니다.

모든 가설이 REJECTED 또는 INCONCLUSIVE인 경우, 다른 하위 시스템에서 새 가설을 생성하고 더 좁은 프로브를 추가하세요. 감에 의존하여 패치하지 마세요.

Troubleshooting (문제 해결)

  • 빈 로그: 앱이 계측된 경로를 실행했는지, 세션 ID가 일치하는지, 엔드포인트에 /log가 포함되어 있는지 확인하세요.
  • 브라우저에서 차단된 요청: 혼합 콘텐츠, CSP connect-src, 확장 프로그램 격리 또는 콘텐츠 스크립트 컨텍스트를 확인하세요.
  • CORS/preflight 문제: 수집기가 OPTIONS를 처리합니다. 여전히 실패하면 navigator.sendBeacon, 동일 출처 개발 서버 프록시 또는 서버사이드 계측을 시도해 보세요.
  • 호스트 거부됨: 127.0.0.1, localhost 또는 ::1을 사용하세요. LAN이나 공용 인터페이스에 절대 바인딩하지 마세요.
  • 샌드박스가 리스너를 차단함: 이 루프백 수집기에 필요한 승인을 받아 한 번 재시도하세요. 승인이 거부되면 로컬 수집이 차단되었음을 설명하고 안전한 파일 기반 프로브 경로가 있는 경우에만 대체합니다.
  • 로그가 너무 많음: 잡음이 많은 프로브를 더 좁은 상태 변경 프로브로 교체하세요.
  • 재현 불가: 정확한 단계, 환경, 입력 데이터 또는 화면 녹화를 요청하세요. 수정을 임의로 만들지 마세요.

Cleanup Checklist (정리 체크리스트)

작업 완료를 선언하기 전에:

  • 원래 재현 또는 가장 가까운 사용 가능한 자동화 검사를 다시 실행하세요.
  • DEBUG_MODE_PROBE <session_id>로 표시된 모든 쌍 영역을 제거하세요.
  • 세션 ID, DEBUG_MODE_PROBE, #region DEBUG_MODE_PROBE 및 #endregion DEBUG_MODE_PROBE를 검색하세요.
  • 출력된 LOG_FILE에 있는 세션 NDJSON 로그를 제거하거나 로컬 증거로 보관해야 하는지 확인하세요.
  • 제품 수정 사항과 유용한 회귀 테스트만 유지하세요.

관련 스킬