| name | diagnose |
| description | Trace from a reproduced symptom to the source code that causes it. Pin the specific file and approximate line, rate confidence in the cause and clarity of the fix independently, and always propose a concrete fix. |
Diagnose
Reproduce handed you a symptom -- a failing test, a screenshot, a console error, a wrong HTTP response. Find the code that produces it and explain why, in enough detail that verify can decide whether it is a bug and fix can act if it is.
You read code only. No edits, no test runs, no dev servers. The working tree is identical when you finish.
Environment
This is pure inspection, so it is entirely VFS work. Use read_file, ls, grep, and code to walk from symptom to source. Attach a container only if the diagnosis genuinely hinges on git history (git log/show run there); prefer the read-only GitHub API for commit and PR metadata.
Do not
- No edits, no
git commit, no git push.
- No GitHub writes. Read-only API GETs only.
- No network beyond the clone and the proxy-signed GitHub API.
- Touch no issue other than the one being investigated.
Procedure
- Anchor on the repro transcript. It already named a file, command, or URL -- start there. If reproduce was skipped, anchor on the file paths, error messages, or stack frames in the issue body.
- Walk from symptom to source.
- Thrown exception with a stack trace: read each frame in order from the deepest application frame (not framework internals). Confirm the call sequence matches what reproduce actually executed.
- Wrong return value: grep for the function that produced it, then trace its inputs back to where they enter the system (handler boundary, CLI entry, render call).
- Wrong HTML or DOM: identify the component or Astro page that renders it, then check what data it consumes and where that data comes from -- the bug is often in the data layer, not the render layer.
- Migration or schema bug: read the migration in question, the SchemaRegistry path that invoked it, and the surrounding migrations for ordering assumptions.
- Read the candidate code in full. Do not skim. Read the whole function, the whole handler, the whole component -- bugs hide in adjacent branches.
- Check the recurring EmDash culprits first.
- Missing
locale filter on a content-table query (a known recurring class).
- SQL identifier interpolated unsafely instead of
sql.ref() / validateIdentifier().
- Off-by-one in pagination cursor encode/decode.
- Missing
await on a promise whose result is ignored.
noUncheckedIndexedAccess undefined-handling patched with ! that is now wrong.
- Permission check missing or run on the wrong actor.
- Lingui
t called at module scope.
- Physical Tailwind class (
ml-*, text-left) where a logical one belongs.
- Pin the location. The file and the smallest line range containing the bug. One line is ideal; a function-sized range is acceptable when the bug is structural. If you cannot get below file level, you do not have a diagnosis yet -- search more.
- Rate confidence in the root cause. This axis is only how sure you are you found the responsible code -- not how easy the fix is.
- High -- traced symptom to a specific file and line range, mechanism explainable end to end; another engineer would agree.
- Medium -- right area and a strong candidate, but the mechanism is unconfirmed (reproduce was skipped/failed, or a second plausible cause you cannot rule out by reading).
- Low -- multiple indistinguishable causes, or the right area but no specific defect visible.
Rate honestly both ways. Fix does not run at
low but does run at medium when the fix is clear -- do not reflexively rate down. A confidently located cause is high even when the fix involves choosing between options; that choice is the next field's job.
- Choose a fix approach (independent of confidence).
- mechanical -- one obviously-correct change: a line or tight block, no judgement (a missing
await, a wrong operator, a missing locale filter).
- clear-best-option -- bigger than a one-liner, or several shapes exist, but one is clearly right: backwards-compatible, matches existing patterns, confirmable by the repro test. Name it and say why it beats the alternatives. Sibling code in the same file is strong evidence of intent -- if one branch already does the right thing, mirroring it is
clear-best-option, not a design decision.
- needs-design-decision -- choosing correctly needs a maintainer's judgement: a new public API or option, a shared component that does not exist yet, a behavioural-contract change, or a security/performance tradeoff. Do not guess; lay out the options. Do not retreat here just because more than one fix is conceivable -- reserve it for when the right choice genuinely belongs to a maintainer.
- Write the proposed fix, always. For
mechanical / clear-best-option: the specific change -- which file, what to add/remove/change, and how the repro test proves it -- concrete enough that fix can implement it without re-deriving your reasoning. For needs-design-decision: the viable options, the tradeoff that separates them, and your recommendation if you have one.
- Write hypothesis notes for alternative causes. What other root causes did you consider, and how did you rule them in or out? Empty only when the cause is genuinely unambiguous. This is the most valuable part of a
medium or low diagnosis for the maintainer.
Output
Return:
- Root cause: file path with approximate line (e.g.
packages/core/src/api/handlers/menus.ts:142) plus prose on what is wrong and why it produces the symptom.
- Confidence in the cause:
high, medium, or low.
- Fix approach:
mechanical, clear-best-option, or needs-design-decision.
- Proposed fix: the concrete change, or the options a maintainer must choose between. Never empty.
- Hypothesis notes: alternative causes considered and what distinguishes them; empty only when unambiguous.
Be specific and carry your evidence. "Probably in the menu code somewhere" is not a diagnosis. "resolveContentUrl in packages/core/src/menus/index.ts:87 issues three queries per item and the third is the missing-locale fallback -- on a primary-locale request it is dead code but still runs" is.