Debug Mode (디버그 모드)
이 스킬은 사용자가 명시적으로 debug-mode, $debug-mode, debug mode, 또는 instrumented debugging을 호출한 경우에만 사용하세요.
사용자가 명시적으로 동의하지 않았다면 일반적인 디버깅을 수행하세요. 이 스킬은 임시 런타임 계측이 실질적으로 도움이 될 때만 언급하세요.
Core Loop (핵심 루프)
가설 기반 디버깅 루프를 실행하세요:
- 관련 코드, 재현 세부 정보 및 기존 로그를 읽습니다.
H1,H2,H3과 같은 ID와 함께 2-5개의 순위가 있는 가설을 나열합니다. 각 가설은 런타임 프로브가 무엇을 보여줄지 예측해야 합니다.- 루프백 수집기(Collector Contract)를 시작하거나 재사용합니다.
- 가설을 구분할 수 있는 3-8개의 타겟 프로브를 추가합니다. stdout/stderr가 아닌
DEBUG_URL + "/log"로 전송되는 구조화된 이벤트를 사용하세요. 아래의 Event Shape, Region Markers 및 Helpers를 따르세요. - 수동 체크포인트에서 멈춥니다. Checkpoint Template을 보냅니다. 사용자가
A,B, 또는C로 응답할 때까지 프로브를 분석, 수정 또는 제거하지 마세요. A응답 후에, 출력된LOG_FILE을 검사하고 각 가설을CONFIRMED,REJECTED, 또는INCONCLUSIVE로 분류한 다음, 로그가 근본 원인을 설명하는 경우에만 최소한의 수정을 가합니다. 아래의 Evidence Summary를 따르세요.- 수정 후 한 번의 실행(
runId: "post-fix"태그 포함) 동안 프로브를 활성 상태로 유지합니다. - 사용자가 수정 후 체크포인트에
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 로그를 제거하거나 로컬 증거로 보관해야 하는지 확인하세요. - 제품 수정 사항과 유용한 회귀 테스트만 유지하세요.