/investigate
The debugging skill. Hypothesis-first, scientific-method approach: state what you observe, propose hypotheses, design a minimum repro, eliminate variables one at a time, name the root cause. No speculation, no guess-fix-rerun loops.
Distinct from /qa --no-fix: that one runs the suite and reports. This one zooms in on a single failure or anomaly and drives it to root cause.
When to use
- A test is failing and
/qa flagged it as product-logic
- Production logs show an anomaly and you need to understand why
- A user-reported bug needs root-cause analysis before a fix design
- A flake is recurring — investigate whether it's actually flake or a real race
When NOT to use
- The fix is obvious and trivial — just fix it
- You haven't reproduced the issue yet AND can't — use
/qa-only first to confirm it's real
- It's a UX issue, not a correctness issue — use
/design-review or /qa with browser
Inputs
- A failure description, error message, log excerpt, or test name (passed inline or via the latest
/qa-only report)
- Optional
--scope <file> — narrow code reading to a specific area
- Optional
--with-codex — invoke /codex mid-investigation for an outside opinion on the hypothesis set
Workflow
- State the observation precisely. What's the failure? Exact error, exact assertion, exact log line. No paraphrasing.
- Minimum repro. Smallest possible command/test/script that triggers the failure. If you can't reduce it: surface that as a finding.
- Hypothesis set. Generate 3-5 candidate explanations. Rank by probability. Include "no idea yet" if honest.
- Variable isolation. For each hypothesis, design ONE experiment that distinguishes it. Run it. Update the ranking.
- Iterate. Hypotheses survive or fall. New ones spawn from the experiments. Continue until one hypothesis is confirmed via direct evidence (not just elimination).
- Root cause statement. A single sentence: "X happens because Y, observable at Z." Cite file:line.
- Fix recommendation. NOT a fix. A recommendation — operator decides whether to fix here, escalate, or punt.
Report format
Investigation: <one-line failure description>
## Observation
Exact error: <verbatim>
Repro: <minimum command>
First seen: <commit or timestamp>
## Hypotheses (initial)
H1: <hypothesis> — probability: 0.5
H2: <hypothesis> — probability: 0.3
H3: <hypothesis> — probability: 0.2
## Experiments
[E1] Test H1 by <action>. Result: <observation>. Updates: H1 → 0.1, H2 → 0.7
[E2] Test H2 by <action>. Result: <observation>. CONFIRMED.
## Root cause
src/lib/dlxClient.ts:87 — fetch retries don't reset the AbortController, so the second attempt cancels itself.
## Fix recommendation
Minimal fix: reset controller in the retry path (5-line change).
Risk: low. No callers depend on the canceled-second-attempt behavior.
Recommend: fix here, add regression test.
Compliance integration
- Read-only mode. No code mutation in this skill. If investigation reveals a sec-issue (e.g. token in logs): surface as Layer 2 sanitization concern, do NOT fix in this skill.
- If repro requires customer-data: STOP. Use synthetic data, or escalate to operator for sanitized fixture.
Failure modes
- Cannot reproduce: name that as a finding. "Cannot reproduce in 50 attempts under conditions X, Y, Z" is data, not failure.
- No hypotheses survive after N experiments: generate a new hypothesis set. If still stuck: write up what's been ruled out, escalate to operator with
/codex for outside opinion.
- Repro requires production access: stop, escalate. Per Layer 2: production reads require explicit auth.
Examples
Quick win:
> /investigate "refund returns 200 instead of 100"
Observation: tests/billing/test_refund.py:42
Repro: pytest tests/billing/test_refund.py::test_partial_refund -x
H1: amount doubled in serialization (0.6)
H2: refund handler called twice (0.3)
H3: test fixture wrong (0.1)
[E1] Add print at serialize: amount=100 going in, 200 coming out.
ROOT CAUSE: src/lib/billing.ts:34 — `* 2` left over from a debug session.
Stuck:
> /investigate "auth flake in CI only"
After 4 experiments: cannot distinguish race vs. network.
Recommendation: enable CI artifact capture (har/trace) on next run, re-investigate.
See also
/qa — when fix is auto-applicable
/codex — for outside-voice hypothesis review
/careful — wrap investigation in extra rigor for prod-impact bugs
DebugForensics subagent — for parallel deeper trace analysis
1---2name: investigate3description: Use when something is broken and you don't yet know why — drives a hypothesis-led investigation that builds a minimum repro, eliminates variables, and isolates the root cause. Reach for it for "why is this failing?" before attempting a fix.4---56# /investigate78The debugging skill. Hypothesis-first, scientific-method approach: state what you observe, propose hypotheses, design a minimum repro, eliminate variables one at a time, name the root cause. No speculation, no guess-fix-rerun loops.910Distinct from `/qa --no-fix`: that one runs the suite and reports. This one zooms in on a single failure or anomaly and drives it to root cause.1112## When to use1314- A test is failing and `/qa` flagged it as product-logic15- Production logs show an anomaly and you need to understand why16- A user-reported bug needs root-cause analysis before a fix design17- A flake is recurring — investigate whether it's actually flake or a real race1819## When NOT to use2021- The fix is obvious and trivial — just fix it22- You haven't reproduced the issue yet AND can't — use `/qa-only` first to confirm it's real23- It's a UX issue, not a correctness issue — use `/design-review` or `/qa` with browser2425## Inputs2627- A failure description, error message, log excerpt, or test name (passed inline or via the latest `/qa-only` report)28- Optional `--scope <file>` — narrow code reading to a specific area29- Optional `--with-codex` — invoke `/codex` mid-investigation for an outside opinion on the hypothesis set3031## Workflow32331. **State the observation precisely.** What's the failure? Exact error, exact assertion, exact log line. No paraphrasing.342. **Minimum repro.** Smallest possible command/test/script that triggers the failure. If you can't reduce it: surface that as a finding.353. **Hypothesis set.** Generate 3-5 candidate explanations. Rank by probability. Include "no idea yet" if honest.364. **Variable isolation.** For each hypothesis, design ONE experiment that distinguishes it. Run it. Update the ranking.375. **Iterate.** Hypotheses survive or fall. New ones spawn from the experiments. Continue until one hypothesis is confirmed via direct evidence (not just elimination).386. **Root cause statement.** A single sentence: "X happens because Y, observable at Z." Cite file:line.397. **Fix recommendation.** NOT a fix. A recommendation — operator decides whether to fix here, escalate, or punt.4041## Report format4243```44Investigation: <one-line failure description>4546## Observation47Exact error: <verbatim>48Repro: <minimum command>49First seen: <commit or timestamp>5051## Hypotheses (initial)52H1: <hypothesis> — probability: 0.553H2: <hypothesis> — probability: 0.354H3: <hypothesis> — probability: 0.25556## Experiments57[E1] Test H1 by <action>. Result: <observation>. Updates: H1 → 0.1, H2 → 0.758[E2] Test H2 by <action>. Result: <observation>. CONFIRMED.5960## Root cause61src/lib/dlxClient.ts:87 — fetch retries don't reset the AbortController, so the second attempt cancels itself.6263## Fix recommendation64Minimal fix: reset controller in the retry path (5-line change).65Risk: low. No callers depend on the canceled-second-attempt behavior.66Recommend: fix here, add regression test.67```6869## Compliance integration7071- Read-only mode. No code mutation in this skill. If investigation reveals a sec-issue (e.g. token in logs): surface as Layer 2 sanitization concern, do NOT fix in this skill.72- If repro requires customer-data: STOP. Use synthetic data, or escalate to operator for sanitized fixture.7374## Failure modes7576- **Cannot reproduce:** name that as a finding. "Cannot reproduce in 50 attempts under conditions X, Y, Z" is data, not failure.77- **No hypotheses survive after N experiments:** generate a new hypothesis set. If still stuck: write up what's been ruled out, escalate to operator with `/codex` for outside opinion.78- **Repro requires production access:** stop, escalate. Per Layer 2: production reads require explicit auth.7980## Examples8182**Quick win:**83```84> /investigate "refund returns 200 instead of 100"85Observation: tests/billing/test_refund.py:4286Repro: pytest tests/billing/test_refund.py::test_partial_refund -x87H1: amount doubled in serialization (0.6)88H2: refund handler called twice (0.3)89H3: test fixture wrong (0.1)90[E1] Add print at serialize: amount=100 going in, 200 coming out.91ROOT CAUSE: src/lib/billing.ts:34 — `* 2` left over from a debug session.92```9394**Stuck:**95```96> /investigate "auth flake in CI only"97After 4 experiments: cannot distinguish race vs. network.98Recommendation: enable CI artifact capture (har/trace) on next run, re-investigate.99```100101## See also102103- `/qa` — when fix is auto-applicable104- `/codex` — for outside-voice hypothesis review105- `/careful` — wrap investigation in extra rigor for prod-impact bugs106- `DebugForensics` subagent — for parallel deeper trace analysis