| name | diagnostic-loop |
| description | Use when diagnosing a reported failure, regression, or unexpected behavior — before proposing any fix, when a fix attempt has just failed, or when the evidence in hand is secondhand (a user report, a log summary, an assumption about what a library or platform does). |
Diagnostic Loop
Find the true cause, then fix it — never the other way around. Diagnose from
evidence in this order, never skipping ahead:
- Reproduce against the real system. Drive the actual code path, real DOM,
real command — not a toy, not a mock, unless your human partner says so. A
report describes a symptom; the reproduction is your first real evidence.
- Observe at the point of failure. Capture the actual output/DOM/logs where
it breaks. In multi-component flows, instrument the boundaries: show what
enters and exits each layer, so the failing layer identifies itself.
- ONE hypothesis at a time, stated as "I think X because Y." Prove or kill
it with the smallest possible probe before proposing any change. A ranked
list of suspects is fine for orientation — but probe them one at a time;
patching several in parallel destroys the evidence trail.
- Fix only after the cause is proven — at the root, in the shared path
(one guard in the shared function, not N guards in every caller).
- Two failed fixes → STOP. The mental model is wrong. Re-read the relevant
code top-down, question the architecture, and propose something materially
different. Never try a third variant of the same idea.
Platform behavior is the usual trap
When a step depends on what a library, framework, or platform does (redirect
handling, event ordering, caching, selector semantics), prove it with a
throwaway probe — a 5-line script against the real thing — rather than
asserting it from memory. Memory of platform behavior is where confident wrong
fixes come from.
What a diagnostic turn reports
- What was reproduced and how (the real command/path).
- What the evidence showed — the raw output/DOM/log, not a paraphrase.
- The proven root cause — and, if the obvious fix turned out wrong, why.
- The fix plan: root-cause location, smallest safe change, the tests that
fail before it, blast radius, and any debt left behind.
Rationalization table
| Excuse | Reality |
|---|
| "The cause is obvious" | Obvious causes are hypotheses. The probe is the cheapest step — run it. |
| "Reproducing is expensive" | A fix without a reproduction is a guess; a wrong guess costs a second debugging round plus the fake fix's cleanup. |
| "I'll patch the 2–3 likely suspects" | Parallel patching means you never learn which one it was — and two of the three patches are now unexplained code. |
| "The library definitely does X" | Prove it with a probe. Platform behavior is the most common source of confidently wrong fixes. |
| "Third attempt, slightly different" | Two failures already falsified the model. Stop and re-derive it. |
When the loop shortens (never disappears)
A trivially evident bug — a failing test naming the exact line, a typo — can be
fixed directly; the reproduction already exists. Even then: verify after the
fix, and state the cause. If "trivial" turns out wrong once, re-enter the loop
at step 1.
See PROVENANCE.md for sources.