Root cause analysis skill — diagnose bugs systematically before fixing. Iron Law: no fix without a confirmed hypothesis. Uses scope lock, 3-strike escalation, and structured debug reports.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add shenxingy/Clade --skill investigate --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Investigate?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/shenxingy-investigate-9aa5e13e)More formats (shields.io, HTML) on the badges page.
---
name: investigate
description: "Root cause analysis skill — diagnose bugs systematically before fixing. Iron Law: no fix without a confirmed hypothesis. Uses scope lock, 3-strike escalation, and structured debug reports."
---
# Clade for Codex
This workflow runs **directly in Codex**. Do not launch the `claude` CLI or
delegate the workflow to Clade's MCP bridge.
Codex compatibility rules:
- Plugin skills are namespaced. Invoke this workflow explicitly as
`$clade:investigate`; a bare `$name` does not select the installed Clade plugin.
- Read the nearest `AGENTS.md` files for repository instructions. If a project
has only `CLAUDE.md`, treat it as legacy project guidance and read it too.
- Store new Clade working state under `.clade/` (or `~/.clade/` for personal
state). Existing legacy Claude state may be read for migration, but do not
create new vendor-specific state.
- A `/skill-name` reference means the corresponding Codex
`$clade:skill-name` plugin skill, or the same workflow invoked naturally when
explicit skill invocation is not available.
- Use Codex web, file, shell, image, and subagent capabilities when the source
workflow names a vendor-specific tool. If a capability is unavailable, use
the documented fallback instead of spawning another agent CLI.
- Paths such as `<plugin-root>/...` are relative to the installed Clade plugin
containing this `SKILL.md`; resolve that root before invoking a helper.
## Canonical Clade workflow
You are the Investigate skill. You diagnose bugs and failures systematically using root cause analysis.
## Iron Law
**No fix without a confirmed root cause hypothesis.**
Fixing symptoms wastes time and creates new bugs. Understand why something is broken before touching the code.
---
## Phase 1: Collect Symptoms
Re-ground on context before diving in:
```bash
git branch --show-current
git log --oneline -10
```
Gather what's known:
- What exactly is failing? (error message, stack trace, unexpected behavior)
- Is it reproducible? On every run or intermittent?
- When did it start? Check recent commits:
```bash
git log --oneline -20 -- <affected-files>
```
- What changed recently that could have introduced this?
If the symptom description is vague, ask the user ONE specific question before continuing (not a list — one question at a time):
> **Re-ground:** [project + branch + task]
> **Question:** [single concrete question]
> **Why:** I need this to narrow down where to look.
---
## Phase 2: Code Path Tracing
Read the relevant code. Don't guess — trace the actual execution path:
1. Identify the entry point (route, function call, script invocation)
2. Use Grep to find where the error originates
3. Read the files in the call chain — follow imports, not assumptions
4. Check recent changes to the affected files:
```bash
git log --oneline -20 -- <file>
git show HEAD~1 -- <file> # what changed in last commit?
```
**Output a root cause hypothesis** at this point — a specific, testable claim:
```
Root cause hypothesis: <file>:<line> — <what is wrong and why>
Example: "auth.py:142 — token expiry check uses UTC naive datetime but DB stores UTC+8, causes
valid tokens to appear expired during 00:00–08:00 window"
```
---
## Phase 3: Scope Lock
Once you have a hypothesis, identify the minimum scope needed to fix it:
```bash
echo "<affected-directory>/" > .clade/freeze-dir.txt
```
This is a commitment: all edits should stay within this scope. If the fix expands significantly beyond it, re-evaluate whether you've found the right root cause.
---
## Phase 4: Hypothesis Testing
**Before writing any fix**, verify the hypothesis with evidence:
- Add a temporary log/assertion to confirm the exact failure point
- Run the failing scenario
- Does the log confirm your hypothesis?
**3-strike rule:** If your hypothesis is wrong, form a new one. After 3 failed hypotheses, stop and ask:
> **Context:** [project + branch + what was tried]
> **RECOMMENDATION:** Option A — add instrumentation and let it fail naturally in the next real occurrence, because shotgun debugging without data is counterproductive.
>
> A. Add observability (log + metric) and wait for next occurrence `Completeness: 8/10` (human: ~15min / Codex: ~20min)
> B. Escalate to a more senior debugger / fresh pair of eyes `Completeness: 7/10` (human: ~30min / Codex: N/A)
> C. Continue investigating with a different approach `Completeness: 5/10` (human: ~1h / Codex: ~45min)
---
## Phase 5: Known Pattern Analysis
Check if this matches a known failure pattern:
| Pattern | Signals |
|---|---|
| Race condition | Works in isolation, fails under load or with concurrent ops |
| Null propagation | `NoneType`, `undefined`, `null pointer` errors deep in call chain |
| State corruption | Correct on first run, wrong after repeated use / restart |
| Integration failure | Works in unit tests, fails with real dependencies |
| Config drift | Works on one machine/env, fails on another |
| Stale cache | Old data persists after state change |
| Off-by-one | Fencepost errors, wrong range boundaries |
| Timezone/encoding | Works locally, fails with different locale/TZ |
If the pattern is recognized, reference it explicitly in your hypothesis.
---
## Phase 6: Implement Fix
Fix the **root cause**, not the symptom.
Rules:
- **Minimal diff** — touch only what's necessary to fix the root cause
- **No refactoring** — if you see unrelated issues, note them but don't fix them now
- **Write the regression test first** — a test that fails WITHOUT the fix and passes WITH it
- Remove any temporary debugging logs
**Blast radius gate:** If the fix requires changes to more than 5 files, stop and ask:
> **Context:** [project + branch]
> **This fix touches N files — broader than expected.**
> **RECOMMENDATION:** Option A — confirm this is the right root cause before proceeding, because wide blast radius often signals we're fixing the wrong layer.
>
> A. Confirm root cause + proceed with full fix `Completeness: 9/10` (human: ~10min / Codex: ~30min)
> B. Find a narrower fix at a higher layer `Completeness: 7/10` (human: ~20min / Codex: ~20min)
> C. Split into two commits: fix + refactor `Completeness: 8/10` (human: ~15min / Codex: ~25min)
---
## Phase 6b: Root Cause Is in a Dependency
If tracing landed in a third-party package (not this codebase), the Iron Law still applies — and a recording law joins it: **a dependency bug handled silently is a bug planted for the next person.**
1. **Isolate a minimal repro** — strip the project away until the bug reproduces against the dependency alone. Save it as `.clade/repro/<dep>-<issue>.py` (or as an xfail/skipped test in `tests/` referencing the upstream issue).
2. **Search the upstream tracker** — `gh search issues --repo <upstream> "<symptom>"` or web search. It may already be reported, fixed in a newer release, or have a documented workaround.
3. **Resolve in strict preference order:**
- **a. Upstream patch PR** — fix it at the source; link the PR in your commit body
- **b. Pin the version + linked issue** — pin to the last good version, add a TODO.md entry with the upstream issue URL and an unpin condition ("unpin when ≥ X.Y.Z ships the fix")
- **c. Documented workaround** — code-level workaround with a comment naming the upstream issue URL, plus a TODO.md entry
4. **Never silent.** Whichever branch you take, the upstream link must appear in a code comment, TODO.md, or the commit body — an unrecorded workaround becomes permanent and unexplainable.
5. **Never monkey-patch the installed copy** — edits inside `.venv/` or `node_modules/` evaporate on the next install.
---
## Phase 7: Verify & Report
Run the full test suite after fixing:
```bash
# Run project tests
# (check AGENTS.md for the test command)
```
Then output the structured debug report:
```
DEBUG REPORT
════════════════════════════════════════
Symptom: [what the user observed]
Root cause: [specific file:line — what was wrong and why]
Fix: [file:line — what was changed]
Evidence: [test output or log showing the fix works]
Regression test: [file:line of new test]
Related: [any TODOS.md items or related issues discovered]
════════════════════════════════════════
```
---
## Completion Status
End every run with one of:
- ✅ **DONE** — root cause found, fix applied, regression test written, report output
- ⚠ **DONE_WITH_CONCERNS** — fix applied but hypothesis confidence is medium; monitor in production
- ❌ **BLOCKED** — cannot reproduce or hypothesis exhausted; details written to `.clade/blockers.md`
- ❓ **NEEDS_CONTEXT** — not enough information to proceed; specific question asked
**3-strike rule:** After 3 failed hypotheses, always switch to BLOCKED — don't keep guessing.
---
## What NOT to do
- Fix before forming a hypothesis
- Change multiple things at once to "see what works"
- Skip the regression test
- Leave debugging logs in the code
- Treat a passing test as proof — verify the specific failure scenario
---
## Deep-Dive Mode (optional)
For complex bugs requiring multi-file execution tracing, spawn the `debug-specialist` subagent:
```
Use a Codex subagent when available with subagent_type="debug-specialist":
"Trace the root cause of: [symptom]. Entry point: [file:function]. Known context: [what you've already found]"
```
The subagent reads code and forms hypotheses but cannot modify files. Merge its root cause finding into your Phase 6 fix.
---
## Error Handling
| Scenario | Action |
|----------|--------|
| Cannot reproduce the bug | Ask user for exact reproduction steps (ONE specific question). Do not guess. |
| Symptom is too vague ("it's slow", "it crashes sometimes") | Ask for a concrete example: specific error message, specific input, specific timing |
| Files implicated are very large (>2000 lines) | Use Grep to locate the specific section before reading; use offset/limit on Read |
| Bug is in a dependency (not this codebase) | Go to Phase 6b: minimal repro → upstream patch > pin-with-linked-issue > documented workaround. Never patch the installed copy in-place. |
| Hypothesis requires runtime data not visible in code | Suggest specific logging/assertion to add. Output as NEEDS_CONTEXT with exact location and what to log. |
| 3 hypotheses exhausted, still no root cause | Output BLOCKED — write to `.clade/blockers.md` with what was tried and what's needed |
## Delivery completion
If this workflow changes files or external state:
- Inspect the real final state before responding, including `git status` for a
repository task.
- Never report `DONE` while task-owned changes are uncommitted. Use or continue
`$clade:delivery` and create a repository-compliant checkpoint or preserve
the work when committing is unavailable.
- When the user request or trusted repository policy makes publication,
deployment, or live verification part of the task, do not silently downgrade
the result to local-only work.
- If a required delivery transition lacks authority, credentials, a destination,
or reachable external state, report `BLOCKED` or `NEEDS_CONTEXT` rather than
appending a "not committed/pushed/deployed" caveat after `DONE`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!