Skip to content

Instantly share code, notes, and snippets.

@dprkh
Created September 13, 2026 00:41
Show Gist options
  • Select an option

  • Save dprkh/8fd2fa16037daf5f32682795fb5f9450 to your computer and use it in GitHub Desktop.

Select an option

Save dprkh/8fd2fa16037daf5f32682795fb5f9450 to your computer and use it in GitHub Desktop.
debug-mode.md
name diagnose-bug
description Hypothesis-driven bug diagnosis workflow for unclear or intermittent failures. Use when the user asks to debug, diagnose, reproduce, instrument, trace, or investigate a bug whose root cause is unknown and evidence should be gathered before fixing. Do not use for straightforward errors with obvious fixes.

Diagnose Bug

Use an evidence-first workflow. Do not jump to fixes.

Workflow

1. Understand the bug

Capture the expected behavior, actual behavior, reproduction steps, and error messages.

Read the relevant source code before changing anything. Understand the call chain and data flow.

2. Generate hypotheses

Produce numbered, testable hypotheses:

Based on my analysis, here are my hypotheses:

1. [H1] What might be wrong and why
2. [H2] What might be wrong and why
3. [H3] What might be wrong and why

Include obvious and non-obvious causes such as race conditions, stale state, timing issues, type coercion, and off-by-one errors.

3. Instrument minimally

Add the smallest amount of temporary instrumentation needed to confirm or rule out the hypotheses.

Write all debug output to an absolute log path:

  • Preferred path: {project_root}/.codex/diagnose-bug/debug.log
  • Fallback path for non-writable or remote environments: /tmp/codex-diagnose-bug/debug.log

Infer project_root from known file paths in the task. Hardcode it in the instrumentation. Do not detect it dynamically with process.cwd(), __dirname, path.resolve(), or similar runtime helpers.

Before each reproduction:

  1. Create .codex/diagnose-bug/ if needed.
  2. Clear debug.log.

Server-side instrumentation:

  • Append directly to the log file with file APIs such as fs.appendFileSync.

Browser-side instrumentation:

  • Create {project_root}/.codex/diagnose-bug/debug-server.js.
  • Start it in a long-lived exec_command session so it keeps running.
  • Record the returned session_id.
  • Send browser logs to http://localhost:9999/debug-log.
  • Stop the server during cleanup with write_stdin and Ctrl-C.

Use this Bun template when Bun is available:

const LOG_FILE = "{project_root}/.codex/diagnose-bug/debug.log";
const CORS = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "POST, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type",
};

Bun.serve({
  port: 9999,
  async fetch(req) {
    if (req.method === "OPTIONS") {
      return new Response(null, { headers: CORS });
    }

    if (req.method === "POST" && new URL(req.url).pathname === "/debug-log") {
      const { message } = await req.json();
      const existing = await Bun.file(LOG_FILE).text().catch(() => "");
      await Bun.write(Bun.file(LOG_FILE), `${existing}${message}\n`);
      return new Response("ok", { headers: CORS });
    }

    return new Response("not found", { status: 404 });
  },
});

If Bun is unavailable, use another installed runtime to expose the same POST /debug-log endpoint.

If the frontend has a Content Security Policy, temporarily allow localhost:9999 and remove that allowance during cleanup.

Wrap all temporary instrumentation in removable debug markers:

// #region DEBUG
...debug code...
// #endregion DEBUG

Language-specific variants are fine as long as the marker text stays #region DEBUG / #endregion DEBUG.

4. Reproduce and wait

After instrumenting, ask the user to reproduce the bug and stop.

5. Analyze the evidence

Check the log size first. If it is large, use targeted reads such as tail or rg "[DEBUG H" instead of reading the whole file.

Map each log line back to the hypotheses and classify them as confirmed or ruled out.

Present the diagnosis in this shape:

## Diagnosis

Root cause: explanation backed by evidence

Evidence:
- [H1] Ruled out: why
- [H2] Confirmed: what the log proved

If the evidence is inconclusive, create new hypotheses, re-instrument, clear the log, and repeat.

6. Fix and verify

Implement the fix, but keep the debug instrumentation in place.

Clear debug.log, ask the user to verify the fix, and stop.

7. Clean up

If the fix is confirmed:

  • Remove all #region DEBUG blocks.
  • Delete .codex/diagnose-bug/debug.log.
  • Delete .codex/diagnose-bug/debug-server.js if it was created.
  • Stop any long-lived debug server session.

If the fix is not confirmed:

  • Read the new logs.
  • Ask what the user observed.
  • Return to hypothesis generation.

Rules

  • Never skip the diagnosis and instrumentation phases.
  • Never remove instrumentation before the user confirms the fix.
  • Never use console.log, print, or stdout/stderr for debug output.
  • Always include hypothesis IDs such as [DEBUG H1] in log messages.
  • Always clear the log before each reproduction.
  • Always wait for the user after asking them to reproduce or verify.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment