Debug Mode — Hypothesis-Driven Debugging with Runtime Log Instrumentation
You are now in Debug Mode. This is a structured, disciplined debugging workflow. You will NOT guess at fixes. You will hypothesize, instrument, observe, and fix based on evidence.
Iron Laws
These rules are non-negotiable. Violating them will produce bad outcomes.
- Never skip phases. Every phase exists for a reason. Do not jump from "understand" to "fix."
- Never declare victory. Only the USER confirms a fix works. You propose, they verify.
- Never remove instrumentation early. Debug logs stay until the user confirms the fix, then cleanup removes everything via
git restore .
- Never dump raw logs. Always use
read_logs with filtering. Never cat or Read log files directly — this floods the context window.
- Never run long processes synchronously. If you need to start a server or watcher, use
nohup ... & or run it in the background. Never hang the terminal.
- Respect the iteration limit. After 3 instrumentation rounds, stop and escalate to the user. Do not loop forever.
- Never instrument without a hypothesis. Every log statement must be tagged with a hypothesis ID. Untargeted logging is noise.
Your Tools
Every tool named in this document lives on the debug MCP server, bundled with this plugin and started automatically. Its tools appear as mcp__plugin_rasad_debug__<tool> — call them by the short names used below.
The 12 tools: detect_stack, start_session, get_status, add_hypothesis, update_hypothesis, set_phase, get_log_templates, clear_logs, read_logs, next_iteration, end_session, abort_session.
If these tools are not available, the MCP server is not connected. Stop and tell the user to run /mcp to check rasad, then /reload-plugins or restart Claude Code. Do NOT fall back to ad-hoc console.log debugging — the whole workflow depends on these tools.
Phase 0: Safety Setup
Goal: Create a safe environment where instrumentation can be freely added and cleanly removed.
Call start_session with the path to the file or directory being debugged.
- This auto-detects the language, framework, and stack (monorepo-aware).
- It creates a git safety stash if there are uncommitted changes.
- It starts the HTTP log collection server.
- It initializes the
.debug/ directory.
Note the returned logServerPort and stack info — you'll need these.
Call set_phase with phase "setup".
Phase 1: Understand
Goal: Build a complete picture of the bug before forming any hypotheses.
Ask the user (or read from their initial message):
- What is the expected behavior?
- What is the actual behavior?
- Any error messages or stack traces?
- What are the reproduction steps?
- When did this start happening? (regression? always broken?)
Read the relevant source code. Follow the code path from the entry point to where the bug manifests.
Check recent git history for related changes (git log --oneline -20).
Call set_phase with phase "understand".
Phase 2: Hypothesize
Goal: Generate multiple testable theories about the root cause.
Generate 3-5 hypotheses. Consider both obvious and non-obvious causes:
- The obvious: wrong variable, missing null check, off-by-one
- The subtle: race condition, stale cache, framework quirk, environment difference
- The framework-specific: use the detected stack to think about common pitfalls
(e.g., React re-render loops, Django ORM N+1, Go goroutine leaks, Next.js SSR/client mismatch)
For each hypothesis, call add_hypothesis with:
- A short ID:
H1, H2, H3, etc.
- A clear description of what you think might be wrong
Rank hypotheses by likelihood. Start instrumentation with the most likely.
Call set_phase with phase "hypothesize".
Phase 3: Instrument
Goal: Add targeted logging to test your hypotheses.
Call get_log_templates for each hypothesis you want to test. This returns:
- HTTP snippet (preferred): Sends structured logs to the debug server
- File snippet (fallback): Appends to a log file
- Region markers:
#region DEBUG / #endregion DEBUG for your language
Inject log statements at key points in the code:
- Wrap each block in region markers so they're clearly identifiable
- Tag every log with the hypothesis ID
- Log the minimum needed: variable values, branch taken, timing
- Place logs at decision points, function entries/exits, and data transformations
Example instrumentation pattern:
// #region DEBUG
fetch('http://127.0.0.1:PORT/log', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
hypothesis: 'H1',
message: 'cart items at checkout',
data: { items: cart.items, total: cart.total }
})
}).catch(() => {});
// #endregion DEBUG
Call set_phase with phase "instrument".
Phase 4: Reproduce
Goal: Collect runtime data by having the user trigger the bug.
Call clear_logs to start with a clean slate.
Always ask the user to reproduce the bug. Provide specific instructions:
- "Please trigger the bug by doing X, Y, Z"
- "Run the failing test with:
npm test -- --grep 'test name'"
- "Navigate to the page and click the button that causes the error"
Wait for the user to confirm they have reproduced the bug.
Call set_phase with phase "reproduce".
Phase 5: Analyze
Goal: Map runtime evidence to hypotheses and identify the root cause.
Call read_logs to read the collected data:
- First, read all logs to get an overview
- Then filter by each hypothesis ID to examine evidence per theory
For each hypothesis, determine:
- Confirmed: The logs clearly show this is the cause
- Eliminated: The logs show this is NOT the cause (values are correct, path not taken)
- Inconclusive: Not enough data to decide
Call update_hypothesis for each hypothesis with the appropriate status.
Decision point:
- If a hypothesis is confirmed → proceed to Phase 6 (Fix)
- If all hypotheses are eliminated/inconclusive:
- Call
next_iteration
- If under the limit → go back to Phase 2 (new hypotheses) or Phase 3 (deeper logging)
- If at the limit → present your findings to the user and ask for guidance
Call set_phase with phase "analyze".
Phase 6: Fix
Goal: Apply a minimal, targeted fix based on evidence.
Based on the confirmed hypothesis and log evidence, implement the smallest possible fix.
- Do NOT refactor surrounding code
- Do NOT add unrelated improvements
- Fix exactly what is broken and nothing more
Keep all instrumentation in place. The debug logs stay so we can verify the fix works.
Explain to the user:
- What the root cause is (with evidence from logs)
- What the fix does
- Why this fix is correct
Call set_phase with phase "fix".
Phase 7: Verify
Goal: Confirm the fix works by having the user test again.
Call clear_logs to clear old data.
Ask the user to reproduce the original scenario again:
- "Please try the same steps that triggered the bug before"
- "The fix is in place along with the debug logging. Please test it."
After the user tests:
- If fixed → proceed to Phase 8 (Cleanup)
- If not fixed → call
next_iteration, go back to Phase 3
- The logs from this run will show whether the fix addressed the right code path
Call set_phase with phase "verify".
Phase 8: Cleanup
Goal: Remove all instrumentation, leaving only the clean fix.
Before cleanup, note exactly what the fix was (file, lines changed, what was changed). You'll need to re-apply it after git restore.
Call end_session. This will:
- Run
git restore . to remove ALL changes (instrumentation AND fix)
- Stop the log server
- Remove the
.debug/ directory
- Restore any stashed changes
Re-apply only the fix — the minimal change that resolves the bug.
Present the final diff to the user. It should be clean: just the fix, no debug artifacts.
Call set_phase with phase "done".
Error Recovery
- If something goes wrong at any point, call
abort_session to emergency-cleanup.
- If the user wants to stop debugging, call
end_session.
- If the log server is unavailable, use file-based logging templates instead.
- If git restore fails, manually remove
#region DEBUG / #endregion DEBUG blocks.
Context Window Protection
- Never read log files with the Read tool or cat command. Always use
read_logs.
- Never run commands that produce unbounded output without piping through
head or grep.
- When running the user's code, redirect verbose output to files and query them surgically.
- Use
get_status to check state instead of re-reading session files.
1---2name: debug-this3description: Use this skill when the user asks to debug a bug, investigate a runtime error, diagnose a failing test, trace a regression, or says /debug-this. Activates hypothesis-driven debugging with runtime log instrumentation. This skill is for genuinely difficult bugs — not typos or obvious syntax errors.4---56# Debug Mode — Hypothesis-Driven Debugging with Runtime Log Instrumentation78You are now in **Debug Mode**. This is a structured, disciplined debugging workflow. You will NOT guess at fixes. You will hypothesize, instrument, observe, and fix based on evidence.910## Iron Laws1112These rules are non-negotiable. Violating them will produce bad outcomes.13141. **Never skip phases.** Every phase exists for a reason. Do not jump from "understand" to "fix."152. **Never declare victory.** Only the USER confirms a fix works. You propose, they verify.163. **Never remove instrumentation early.** Debug logs stay until the user confirms the fix, then cleanup removes everything via `git restore .`174. **Never dump raw logs.** Always use `read_logs` with filtering. Never `cat` or `Read` log files directly — this floods the context window.185. **Never run long processes synchronously.** If you need to start a server or watcher, use `nohup ... &` or run it in the background. Never hang the terminal.196. **Respect the iteration limit.** After 3 instrumentation rounds, stop and escalate to the user. Do not loop forever.207. **Never instrument without a hypothesis.** Every log statement must be tagged with a hypothesis ID. Untargeted logging is noise.2122## Your Tools2324Every tool named in this document lives on the **`debug` MCP server**, bundled with this plugin and started automatically. Its tools appear as `mcp__plugin_rasad_debug__<tool>` — call them by the short names used below.2526The 12 tools: `detect_stack`, `start_session`, `get_status`, `add_hypothesis`, `update_hypothesis`, `set_phase`, `get_log_templates`, `clear_logs`, `read_logs`, `next_iteration`, `end_session`, `abort_session`.2728**If these tools are not available**, the MCP server is not connected. Stop and tell the user to run `/mcp` to check `rasad`, then `/reload-plugins` or restart Claude Code. Do NOT fall back to ad-hoc `console.log` debugging — the whole workflow depends on these tools.2930## Phase 0: Safety Setup3132**Goal:** Create a safe environment where instrumentation can be freely added and cleanly removed.33341. Call `start_session` with the path to the file or directory being debugged.35 - This auto-detects the language, framework, and stack (monorepo-aware).36 - It creates a git safety stash if there are uncommitted changes.37 - It starts the HTTP log collection server.38 - It initializes the `.debug/` directory.39402. Note the returned `logServerPort` and `stack` info — you'll need these.41423. Call `set_phase` with phase `"setup"`.4344## Phase 1: Understand4546**Goal:** Build a complete picture of the bug before forming any hypotheses.47481. Ask the user (or read from their initial message):49 - What is the **expected** behavior?50 - What is the **actual** behavior?51 - Any **error messages** or stack traces?52 - What are the **reproduction steps**?53 - When did this **start happening**? (regression? always broken?)54552. Read the relevant source code. Follow the code path from the entry point to where the bug manifests.56573. Check recent git history for related changes (`git log --oneline -20`).58594. Call `set_phase` with phase `"understand"`.6061## Phase 2: Hypothesize6263**Goal:** Generate multiple testable theories about the root cause.64651. Generate **3-5 hypotheses**. Consider both obvious and non-obvious causes:66 - The obvious: wrong variable, missing null check, off-by-one67 - The subtle: race condition, stale cache, framework quirk, environment difference68 - The framework-specific: use the detected stack to think about common pitfalls69 (e.g., React re-render loops, Django ORM N+1, Go goroutine leaks, Next.js SSR/client mismatch)70712. For each hypothesis, call `add_hypothesis` with:72 - A short ID: `H1`, `H2`, `H3`, etc.73 - A clear description of what you think might be wrong74753. Rank hypotheses by likelihood. Start instrumentation with the most likely.76774. Call `set_phase` with phase `"hypothesize"`.7879## Phase 3: Instrument8081**Goal:** Add targeted logging to test your hypotheses.82831. Call `get_log_templates` for each hypothesis you want to test. This returns:84 - **HTTP snippet** (preferred): Sends structured logs to the debug server85 - **File snippet** (fallback): Appends to a log file86 - **Region markers**: `#region DEBUG` / `#endregion DEBUG` for your language87882. Inject log statements at key points in the code:89 - **Wrap each block** in region markers so they're clearly identifiable90 - **Tag every log** with the hypothesis ID91 - **Log the minimum needed**: variable values, branch taken, timing92 - Place logs at decision points, function entries/exits, and data transformations93943. Example instrumentation pattern:95 ```96 // #region DEBUG97 fetch('http://127.0.0.1:PORT/log', {98 method: 'POST',99 headers: {'Content-Type': 'application/json'},100 body: JSON.stringify({101 hypothesis: 'H1',102 message: 'cart items at checkout',103 data: { items: cart.items, total: cart.total }104 })105 }).catch(() => {});106 // #endregion DEBUG107 ```1081094. Call `set_phase` with phase `"instrument"`.110111## Phase 4: Reproduce112113**Goal:** Collect runtime data by having the user trigger the bug.1141151. Call `clear_logs` to start with a clean slate.1161172. **Always ask the user** to reproduce the bug. Provide specific instructions:118 - "Please trigger the bug by doing X, Y, Z"119 - "Run the failing test with: `npm test -- --grep 'test name'`"120 - "Navigate to the page and click the button that causes the error"1211223. **Wait for the user to confirm** they have reproduced the bug.1231244. Call `set_phase` with phase `"reproduce"`.125126## Phase 5: Analyze127128**Goal:** Map runtime evidence to hypotheses and identify the root cause.1291301. Call `read_logs` to read the collected data:131 - First, read all logs to get an overview132 - Then filter by each hypothesis ID to examine evidence per theory1331342. For each hypothesis, determine:135 - **Confirmed**: The logs clearly show this is the cause136 - **Eliminated**: The logs show this is NOT the cause (values are correct, path not taken)137 - **Inconclusive**: Not enough data to decide1381393. Call `update_hypothesis` for each hypothesis with the appropriate status.1401414. **Decision point:**142 - If a hypothesis is **confirmed** → proceed to Phase 6 (Fix)143 - If all hypotheses are eliminated/inconclusive:144 - Call `next_iteration`145 - If under the limit → go back to Phase 2 (new hypotheses) or Phase 3 (deeper logging)146 - If at the limit → present your findings to the user and ask for guidance1471485. Call `set_phase` with phase `"analyze"`.149150## Phase 6: Fix151152**Goal:** Apply a minimal, targeted fix based on evidence.1531541. Based on the confirmed hypothesis and log evidence, implement the **smallest possible fix**.155 - Do NOT refactor surrounding code156 - Do NOT add unrelated improvements157 - Fix exactly what is broken and nothing more1581592. **Keep all instrumentation in place.** The debug logs stay so we can verify the fix works.1601613. Explain to the user:162 - What the root cause is (with evidence from logs)163 - What the fix does164 - Why this fix is correct1651664. Call `set_phase` with phase `"fix"`.167168## Phase 7: Verify169170**Goal:** Confirm the fix works by having the user test again.1711721. Call `clear_logs` to clear old data.1731742. Ask the user to **reproduce the original scenario** again:175 - "Please try the same steps that triggered the bug before"176 - "The fix is in place along with the debug logging. Please test it."1771783. After the user tests:179 - If **fixed** → proceed to Phase 8 (Cleanup)180 - If **not fixed** → call `next_iteration`, go back to Phase 3181 - The logs from this run will show whether the fix addressed the right code path1821834. Call `set_phase` with phase `"verify"`.184185## Phase 8: Cleanup186187**Goal:** Remove all instrumentation, leaving only the clean fix.1881891. **Before cleanup**, note exactly what the fix was (file, lines changed, what was changed). You'll need to re-apply it after git restore.1901912. Call `end_session`. This will:192 - Run `git restore .` to remove ALL changes (instrumentation AND fix)193 - Stop the log server194 - Remove the `.debug/` directory195 - Restore any stashed changes1961973. **Re-apply only the fix** — the minimal change that resolves the bug.1981994. Present the final diff to the user. It should be clean: just the fix, no debug artifacts.2002015. Call `set_phase` with phase `"done"`.202203## Error Recovery204205- If something goes wrong at any point, call `abort_session` to emergency-cleanup.206- If the user wants to stop debugging, call `end_session`.207- If the log server is unavailable, use file-based logging templates instead.208- If git restore fails, manually remove `#region DEBUG` / `#endregion DEBUG` blocks.209210## Context Window Protection211212- **Never** read log files with the Read tool or cat command. Always use `read_logs`.213- **Never** run commands that produce unbounded output without piping through `head` or `grep`.214- When running the user's code, redirect verbose output to files and query them surgically.215- Use `get_status` to check state instead of re-reading session files.