Diagnose Failure - one entry for any failure evidence
One reported failure, four steps, the user holds the gate between them. This skill owns the
chain, the stops, the evidence accounting, and the fork at the end; the catalogues and the
seats do the specialist work. It is READ-ONLY from start to finish - no step here writes code,
so no approval stamp and no commit gate come into play.
Evidence tiers - name the tier, carry it as the confidence label
The tier is the first thing this skill establishes and the last thing its verdict is qualified
by. No source is a lower tier, never a blocker:
| Tier |
What you have |
What it buys |
| 1 |
stack trace / exception with a frame, or a failing test |
a symbol to start at |
| 2 |
a log window around the failure, a red CI run, a monitoring event |
a time-ordered sequence |
| 3 |
reproducible steps a human wrote down |
a repro you can run |
| 4 |
a screenshot, a single symptom line, a prose report from a client |
a behaviour to locate in code |
A tier-4 report is the DEFAULT case, not an edge case: most projects have no CI, no error
monitoring, and no retained logs. There, step 2 turns prose into an observable and works
code-first - locate the named behaviour, read the paths that could produce the symptom, try to
reproduce - and the verdict says plainly which tier it rests on. A conclusion drawn at tier 4
is labelled as such; it is never presented with tier-1 confidence.
Sources - what this skill can reach
- In reach, always: files and logs on disk, the repo's own history, anything the user pastes
into the chat, and the app itself when it can be run locally.
- In reach when the project has it: the
gh CLI for a red pipeline; an error-monitoring MCP
where the project registered one (the baseline comments out the MCPs a project does not need,
so it can simply be absent from your tool list here).
- Never in reach: a LINK. A monitoring-issue URL, a private dashboard, a ticket - if no tool
in this session can fetch it, say so in one line and ask the user to paste the event, rather
than guessing what it contained.
State - two layers, split by durability
- The findings file (
<docs-path>/diagnoses/<slug>.md) is the durable truth: the failure as
an observable, the evidence tier, every digest's key lines, the hypotheses with their verdicts,
the proven cause, and the stamps this run adds (Tier, Gathered, Cause, Outcome). On any
conflict with memory or the chat, the file wins.
- The serena note (
write_memory named <slug>__diagnosis) is the working cursor: current
step, chosen mode, resume pointer, the error signature and its proven fix once found - that
last part is the reusable half, keyed to the signature, never a dump of the log.
On invocation, resume before starting: list_memories -> read_memory the slug's note (or
an equivalent direct read of .serena/memories/) and read the findings file's stamps. A run
mid-flight resumes at its cursor - never re-run a step already stamped. A run between steps 2
and 3 looks like:
findings .claude/docs/diagnoses/orders-sync-disposed.md:
Observable: nightly order sync stops after the first batch; expected all batches
Tier: 1 (ObjectDisposedException, frame OrderSyncJob.ExecuteAsync) | Gathered: 2 sources agree
Cause: <pending>
note 'orders-sync-disposed__diagnosis': step 3 ROOT CAUSE - mode inline, 1 hypothesis open
Mode - ask at start
When dispatch is available, ask ONE question before the evidence pass, via AskUserQuestion -
gather through evidence-gatherer seats, or inline in this session? - unless a calling flow
already picked the run's mode, which is inherited, never re-asked. Recommend the seats when the
evidence is BIG or MANY (a multi-megabyte log, a CI dump, three sources to correlate): the
whole point of that seat is that the raw volume never lands in this context. Recommend inline
when a single command or a bounded grep settles it. An interrupted or declined ask is answered
by RE-ASKING, never by inference.
The stop contract
A stop IS one AskUserQuestion call: report one line of result and the artifact path, then put
the next move through the AskUserQuestion tool - EVERY stop, the plain step-done ones included.
There is no non-decision stop: 'what happens next' is itself the decision. The options are
concrete - the next step named, the route-back where a step surfaced gaps, the fresh-session
resume on a long run - the recommendation marked per that stop's own rule, free text always
available via the built-in Other. Where the harness has no such tool, list the same options in
plain text and END THE TURN. The selected answer is the go; silence is not, and a stop that
only narrates is not a stop. Once the run has crossed roughly 150k ctx per message or spans
hours, the fresh-session resume IS one of the next ask's options - a CONSTRUCTION check before
emitting each stop, not a memory: resume needs only the findings file plus the note.
The steps
Each step that names a catalogue INVOKES it via the Skill tool - and re-invokes it in a new
cycle in the same chat, even when an earlier cycle already loaded it.
- TRIAGE - read the evidence in whatever form it arrived (
Read opens a screenshot as
readily as a log), restate the failure as an OBSERVABLE - what happened, where, what should
have happened instead - and name the tier from the table above. Then load the signature
catalogue that matches the failure's origin, matched from YOUR skill list by what each skill
says it covers, never by a remembered name: the one covering local-runtime crash signatures
(null-reference, DI resolution, async deadlock, race, disposed lifecycle, config drift) for a
failure on your own machine, the one covering red-pipeline signatures (compile/restore,
green-locally-red-on-the-runner, quality gate, signing, workflow drift, infra flake) for a
red CI run. Nothing matching means this project installed no such catalogue - say so and
proceed on the method alone. A red pipeline is the one route that leaves this skill: CI
needs the gh log pull and the CI-versus-local environment delta, which is
ci-failure-diagnoser's specialty - offer that dispatch as the recommended option at this
stop rather than re-deriving it here. Write the findings file with the observable and
Tier: <n>. Stop.
- GATHER - per the mode: dispatch one evidence-gatherer per source (reproduce this path,
pull and grep that log window, capture that screen), several in parallel when several
hypotheses need confirming, and reason over the compact digests they return; or run the
bounded commands inline. Correlate multiple sources on a shared key - a correlation/trace id,
a timestamp window, a release version - and say which sources agreed and which did not. At
tier 4, with no source to pull, this step is code-first instead: locate the named behaviour
with serena per
.claude/rules/baseline-navigation.md, read the paths that could produce the
symptom, and attempt a repro. Never slurp a large log into this context - grep to the signal
and quote a bounded window. If it cannot be reproduced, say so with what you tried, and work
from the evidence and the code. Append the digests' key lines to the findings file and stamp
Gathered:. Stop.
- ROOT CAUSE - run the investigation through the hypothesis-and-test method
(
superpowers:systematic-debugging): form the fewest hypotheses the evidence supports, then
confirm or kill each against the located code and the reproduction - root cause before
symptom, never a plausible guess. Match the evidence to the catalogue's signature and isolate
where the signature points, which is almost never the line that threw. Hard cap: 2
investigation passes. If the cause stays ambiguous after 2, stop guessing and record the
surviving hypotheses RANKED with what would decide between each. Stamp Cause: with the
file + symbol and the evidence that proves it, or Cause: unproven - <n> hypotheses ranked.
Report a severity and an explicit P0-P3 priority when the ask was to level it rather than fix
it. This step ends at the fork below - it never continues into planning on its own.
- THE FORK - the step-3 stop asks ONE question whose options are the three real outcomes,
each named concretely. The recommendation is set by whether step 3 actually proved a cause -
proven recommends 4b, unproven recommends 4c - with the reason in the option's description:
- 4a. REPORT ('Write a report on the issue') - finish the findings file as a standalone
document: the observable, the evidence tier, the proven cause with its located symbol, the
blast radius and who it affects, severity + priority, and what a fix would have to change.
No task cards. This is the outcome when the fix is someone else's, or not now.
- 4b. PLAN TASKS ('Plan the fix as tasks') - decompose the minimal change per cause into
independent tasks, each with a contract: the files it owns, what it must not touch, its
acceptance criterion, and the
log_points the fix must leave behind at the seam that
failed. Name the target stack per task. The cards go into the findings file under a
## Tasks heading - the file is the handoff, not the chat. The build is the user's next
step, never yours: the close-out names /project-solve-task with the findings path as its
input (it is slash-only - a model Skill call is refused - and its DESIGN step turns these
cards into the gated plan). If the real fix is a redesign rather than a targeted change,
say so and make that stack's solution-designer the option's route instead of planning it
here; if it would change a shared contract, mark it BLOCKED_CONTRACT_CHANGE rather than
planning a silent edit.
- 4c. INSTRUMENT ('Add log points and re-run') - the outcome that turns 'no evidence' into
work instead of a guess: ONE task card carrying only the log points to add at the suspect
seam - the exact symbols, the levels, and the identifiers each line must carry - so the next
occurrence arrives one tier higher. Name the hypothesis each line is there to decide.
Stamp
Outcome: with the branch taken. Stop - and this close-out stop carries anything
pending: an unwritten task card, a source the user still has to paste, a sibling repo that
needs the same fix (that handoff is a FILE - a task card under <docs-path>/cross-project-tasks/
- never chat-only prose). Delete the serena cursor note; keep the signature-to-fix note if the
cause was proven, that is the reusable half.
Do not
- Never pass a stop without the user's explicit word, and never take the fork yourself - step 4
runs the branch the USER picked, and 'obviously they want the fix' is not an answer.
- Never end a stop's turn without its AskUserQuestion (or the plain-text fallback's option list).
- Never write code, edit a file under test, or run a destructive repro - one that applies a
migration against a real database, seeds or deletes tracked files, or commits. If the only
repro is destructive, say so and stop.
- Never present a tier-3 or tier-4 conclusion with tier-1 confidence, and never report a cause
you did not prove as the answer - an honest 'unproven, here is what would decide it' with the
4c instrumentation card beats a plausible guess that sends the fix at the wrong symbol.
- Never state a source was checked that you could not reach - an unfetchable link, an absent
monitoring MCP, and a log the project does not retain are each named, not silently skipped.
- Never keep run state only in chat: a stamp that is not in the findings file does not exist.
1---2name: project-diagnose-failure3description: Use to investigate a failure of any kind in THIS chat, from whatever evidence you actually have - a pasted Sentry event, one log file, several log sources at once, a red CI run, a stack trace, a screenshot, or nothing but a customer saying checkout is slow. Four gated steps: triage the evidence to a tier, gather (inline or evidence-gatherer seats), prove the root cause, then a user fork - write a report, plan the fix as contracted tasks, or add log points and re-run. Read-only throughout: it never writes the fix. Trigger on investigate this bug, diagnose this failure, what is causing this, look into this incident, triage this report. Not the fix build (project-solve-task takes the tasks from here), not a signature lookup you already have the answer for.4---56# Diagnose Failure - one entry for any failure evidence78One reported failure, four steps, the user holds the gate between them. This skill owns the9chain, the stops, the evidence accounting, and the fork at the end; the catalogues and the10seats do the specialist work. It is READ-ONLY from start to finish - no step here writes code,11so no approval stamp and no commit gate come into play.1213## Evidence tiers - name the tier, carry it as the confidence label1415The tier is the first thing this skill establishes and the last thing its verdict is qualified16by. No source is a lower tier, never a blocker:1718| Tier | What you have | What it buys |19|---|---|---|20| 1 | stack trace / exception with a frame, or a failing test | a symbol to start at |21| 2 | a log window around the failure, a red CI run, a monitoring event | a time-ordered sequence |22| 3 | reproducible steps a human wrote down | a repro you can run |23| 4 | a screenshot, a single symptom line, a prose report from a client | a behaviour to locate in code |2425A tier-4 report is the DEFAULT case, not an edge case: most projects have no CI, no error26monitoring, and no retained logs. There, step 2 turns prose into an observable and works27code-first - locate the named behaviour, read the paths that could produce the symptom, try to28reproduce - and the verdict says plainly which tier it rests on. A conclusion drawn at tier 429is labelled as such; it is never presented with tier-1 confidence.3031## Sources - what this skill can reach3233- **In reach, always:** files and logs on disk, the repo's own history, anything the user pastes34 into the chat, and the app itself when it can be run locally.35- **In reach when the project has it:** the `gh` CLI for a red pipeline; an error-monitoring MCP36 where the project registered one (the baseline comments out the MCPs a project does not need,37 so it can simply be absent from your tool list here).38- **Never in reach:** a LINK. A monitoring-issue URL, a private dashboard, a ticket - if no tool39 in this session can fetch it, say so in one line and ask the user to paste the event, rather40 than guessing what it contained.4142## State - two layers, split by durability4344- **The findings file** (`<docs-path>/diagnoses/<slug>.md`) is the durable truth: the failure as45 an observable, the evidence tier, every digest's key lines, the hypotheses with their verdicts,46 the proven cause, and the stamps this run adds (`Tier`, `Gathered`, `Cause`, `Outcome`). On any47 conflict with memory or the chat, the file wins.48- **The serena note** (`write_memory` named `<slug>__diagnosis`) is the working cursor: current49 step, chosen mode, resume pointer, the error signature and its proven fix once found - that50 last part is the reusable half, keyed to the signature, never a dump of the log.5152**On invocation, resume before starting:** `list_memories` -> `read_memory` the slug's note (or53an equivalent direct read of `.serena/memories/`) and read the findings file's stamps. A run54mid-flight resumes at its cursor - never re-run a step already stamped. A run between steps 255and 3 looks like:5657```58findings .claude/docs/diagnoses/orders-sync-disposed.md:59 Observable: nightly order sync stops after the first batch; expected all batches60 Tier: 1 (ObjectDisposedException, frame OrderSyncJob.ExecuteAsync) | Gathered: 2 sources agree61 Cause: <pending>62note 'orders-sync-disposed__diagnosis': step 3 ROOT CAUSE - mode inline, 1 hypothesis open63```6465## Mode - ask at start6667When dispatch is available, ask ONE question before the evidence pass, via AskUserQuestion -68gather through evidence-gatherer seats, or inline in this session? - unless a calling flow69already picked the run's mode, which is inherited, never re-asked. Recommend the seats when the70evidence is BIG or MANY (a multi-megabyte log, a CI dump, three sources to correlate): the71whole point of that seat is that the raw volume never lands in this context. Recommend inline72when a single command or a bounded grep settles it. An interrupted or declined ask is answered73by RE-ASKING, never by inference.7475## The stop contract7677A stop IS one AskUserQuestion call: report one line of result and the artifact path, then put78the next move through the AskUserQuestion tool - EVERY stop, the plain step-done ones included.79There is no non-decision stop: 'what happens next' is itself the decision. The options are80concrete - the next step named, the route-back where a step surfaced gaps, the fresh-session81resume on a long run - the recommendation marked per that stop's own rule, free text always82available via the built-in Other. Where the harness has no such tool, list the same options in83plain text and END THE TURN. The selected answer is the go; silence is not, and a stop that84only narrates is not a stop. Once the run has crossed roughly 150k ctx per message or spans85hours, the fresh-session resume IS one of the next ask's options - a CONSTRUCTION check before86emitting each stop, not a memory: resume needs only the findings file plus the note.8788## The steps8990Each step that names a catalogue INVOKES it via the Skill tool - and re-invokes it in a new91cycle in the same chat, even when an earlier cycle already loaded it.92931. **TRIAGE** - read the evidence in whatever form it arrived (`Read` opens a screenshot as94 readily as a log), restate the failure as an OBSERVABLE - what happened, where, what should95 have happened instead - and name the tier from the table above. Then load the signature96 catalogue that matches the failure's origin, matched from YOUR skill list by what each skill97 says it covers, never by a remembered name: the one covering local-runtime crash signatures98 (null-reference, DI resolution, async deadlock, race, disposed lifecycle, config drift) for a99 failure on your own machine, the one covering red-pipeline signatures (compile/restore,100 green-locally-red-on-the-runner, quality gate, signing, workflow drift, infra flake) for a101 red CI run. Nothing matching means this project installed no such catalogue - say so and102 proceed on the method alone. **A red pipeline is the one route that leaves this skill:** CI103 needs the `gh` log pull and the CI-versus-local environment delta, which is104 ci-failure-diagnoser's specialty - offer that dispatch as the recommended option at this105 stop rather than re-deriving it here. Write the findings file with the observable and106 `Tier: <n>`. *Stop.*1072. **GATHER** - per the mode: dispatch one evidence-gatherer per source (reproduce this path,108 pull and grep that log window, capture that screen), several in parallel when several109 hypotheses need confirming, and reason over the compact digests they return; or run the110 bounded commands inline. Correlate multiple sources on a shared key - a correlation/trace id,111 a timestamp window, a release version - and say which sources agreed and which did not. At112 tier 4, with no source to pull, this step is code-first instead: locate the named behaviour113 with serena per `.claude/rules/baseline-navigation.md`, read the paths that could produce the114 symptom, and attempt a repro. Never slurp a large log into this context - grep to the signal115 and quote a bounded window. If it cannot be reproduced, say so with what you tried, and work116 from the evidence and the code. Append the digests' key lines to the findings file and stamp117 `Gathered:`. *Stop.*1183. **ROOT CAUSE** - run the investigation through the hypothesis-and-test method119 (`superpowers:systematic-debugging`): form the fewest hypotheses the evidence supports, then120 confirm or kill each against the located code and the reproduction - root cause before121 symptom, never a plausible guess. Match the evidence to the catalogue's signature and isolate122 where the signature points, which is almost never the line that threw. **Hard cap: 2123 investigation passes.** If the cause stays ambiguous after 2, stop guessing and record the124 surviving hypotheses RANKED with what would decide between each. Stamp `Cause:` with the125 file + symbol and the evidence that proves it, or `Cause: unproven - <n> hypotheses ranked`.126 Report a severity and an explicit P0-P3 priority when the ask was to level it rather than fix127 it. **This step ends at the fork below - it never continues into planning on its own.**1284. **THE FORK** - the step-3 stop asks ONE question whose options are the three real outcomes,129 each named concretely. The recommendation is set by whether step 3 actually proved a cause -130 proven recommends 4b, unproven recommends 4c - with the reason in the option's description:131 - **4a. REPORT** ('Write a report on the issue') - finish the findings file as a standalone132 document: the observable, the evidence tier, the proven cause with its located symbol, the133 blast radius and who it affects, severity + priority, and what a fix would have to change.134 No task cards. This is the outcome when the fix is someone else's, or not now.135 - **4b. PLAN TASKS** ('Plan the fix as tasks') - decompose the minimal change per cause into136 independent tasks, each with a contract: the files it owns, what it must not touch, its137 acceptance criterion, and the `log_points` the fix must leave behind at the seam that138 failed. Name the target stack per task. The cards go into the findings file under a139 `## Tasks` heading - the file is the handoff, not the chat. The build is the user's next140 step, never yours: the close-out names `/project-solve-task` with the findings path as its141 input (it is slash-only - a model Skill call is refused - and its DESIGN step turns these142 cards into the gated plan). If the real fix is a redesign rather than a targeted change,143 say so and make that stack's solution-designer the option's route instead of planning it144 here; if it would change a shared contract, mark it BLOCKED_CONTRACT_CHANGE rather than145 planning a silent edit.146 - **4c. INSTRUMENT** ('Add log points and re-run') - the outcome that turns 'no evidence' into147 work instead of a guess: ONE task card carrying only the log points to add at the suspect148 seam - the exact symbols, the levels, and the identifiers each line must carry - so the next149 occurrence arrives one tier higher. Name the hypothesis each line is there to decide.150 Stamp `Outcome:` with the branch taken. *Stop* - and this close-out stop carries anything151 pending: an unwritten task card, a source the user still has to paste, a sibling repo that152 needs the same fix (that handoff is a FILE - a task card under `<docs-path>/cross-project-tasks/`153 - never chat-only prose). Delete the serena cursor note; keep the signature-to-fix note if the154 cause was proven, that is the reusable half.155156## Do not157158- Never pass a stop without the user's explicit word, and never take the fork yourself - step 4159 runs the branch the USER picked, and 'obviously they want the fix' is not an answer.160- Never end a stop's turn without its AskUserQuestion (or the plain-text fallback's option list).161- Never write code, edit a file under test, or run a destructive repro - one that applies a162 migration against a real database, seeds or deletes tracked files, or commits. If the only163 repro is destructive, say so and stop.164- Never present a tier-3 or tier-4 conclusion with tier-1 confidence, and never report a cause165 you did not prove as the answer - an honest 'unproven, here is what would decide it' with the166 4c instrumentation card beats a plausible guess that sends the fix at the wrong symbol.167- Never state a source was checked that you could not reach - an unfetchable link, an absent168 monitoring MCP, and a log the project does not retain are each named, not silently skipped.169- Never keep run state only in chat: a stamp that is not in the findings file does not exist.