Prompt file imported from adrian-d-hidalgo/nestjs-mcp-server (
.claude/commands/debug.md). Fill in{{arguments}}before use. Copyright stays with the author.
In every route the debugger agent is the executor of the deep RCA — you do not replicate
its work; you invoke the agent. You load the bug-diagnosis skill as the process guide (the
deprecation check, evidence before assertion, the reproduction ladder, the certainty bar) and the
github-issues skill for the Mode B shape and the authorization contract.
Always propose; never create or comment without authorization.
Rows 5 and 6 are the pair most often confused. The test: does something exist and behave wrongly (bug), or does it not exist (capability)?
- Symptom route: what fails, which export or decorator, which transport, expected vs actual.
- Issue route: reproduction steps, the three versions (
@nestjs-mcp/server,@nestjs/common,@modelcontextprotocol/sdk), the transport, expected vs actual. If a critical piece is missing → propose asking in the issue's comments and do not advance to the RCA until it is answered. - Failing-test route: the full failure output, not the first line.
Once the musts are met, continue and run the diagnosis (via the agent). Never invent or
assume a cause, a reproduction, a duplicate, or a fix. CLAUDE.md: "A fix grounded in
[Inference] is not done — get the evidence or say you couldn't and stop."
Issue route — an existing GitHub issue.
0. Check the workspace — .project/tasks/issue-<N>/notes.md. If it exists, read it before
investigating. It records what was already tried and ruled out; re-running a dead end is the
specific waste it exists to prevent. If spec.md exists too, this issue already has an approved
analysis — say so, because a new RCA may invalidate it.
- Read the issue and its comments (
issue_read,getthenget_comments) — what the reporter describes, in their words. The comments usually carry the versions and the "it also happens when…" that the body lacks. - Judge report sufficiency against the Musts. If a critical piece is missing → propose a
comment asking for it (
add_issue_comment, under authorization — commenting on a public issue is a mutation) and do NOT advance to the RCA until it is answered. Never assume the missing facts. - Light discovery.
search_issuesfor another issue on the same symptom, open and closed. A match → STOP and raise it with a recommendation (add evidence to the existing one vs open a new one); a closed match means a regression — a new issue linking back, never a reopen. Then continue at the Shared close.
Failing-test route — a red spec or CI run.
- Capture the full output verbatim — Jest's assertion diff usually names the broken invariant directly.
- Establish whether it is a product defect or a test defect. A spec asserting behaviour the SPEC never promised is a test bug, and saying so is the finding.
- Light discovery as above, then continue at the Shared close.
Symptom route — a raw symptom, a stack trace, or a diagnostic.
- Capture verbatim (Phase 0 of
bug-diagnosis) — the exact string, the versions, the transport, expected vs actual. Ask for anything missing rather than filling it in. - Light discovery —
search_issuesfor the same symptom before investigating, open and closed. If one exists → raise it with a recommendation; do not open a parallel. Then continue at the Shared close.
Shared close — every route ends here.
3. The debugger agent runs the read-only RCA. Invoke it via Task. It runs the deprecation
check first, builds the smallest reproduction that fails (climbing the ladder: unit spec → e2e →
MCP Inspector → example), traces the cause with codegraph, and attributes it correctly
(first-party vs @modelcontextprotocol/sdk vs consumer misuse). The deep investigation is the
debugger's — never done inline by a coordinator.
-
Preserve the investigation before judging it. An RCA is expensive and, until now, evaporated whenever it did not end in an issue — which is most of the interesting outcomes below. When the signal is an existing issue
#N, append the finding to.project/tasks/issue-<N>/notes.md(creating the directory and file if needed), per thetask-workspaceskill: what was tried, what it ruled out, and any surprising SDK behaviour. Append — never rewrite; the dead ends are the point.For a symptom with no issue behind it there is no workspace to write to. Say so, and if the finding is worth keeping, that is itself an argument for opening the issue.
-
Judge the outcome before proposing anything. Not every RCA ends in an issue:
- Path deprecated / already fixed on
main→ report that, with the version that fixed it. No issue. - Consumer misuse the types already reject → that is a documentation gap (Mode D), not a bug. Propose accordingly.
- Upstream SDK bug → the issue here records the wrapping decision (pin / override / wrap / wait) and links the upstream report. Say which, with its consequence.
- Not reproducible → say so, with the routes tried and the settings used. An honest
Not reproducibleis a valid outcome; a plausible guess is not. - Cause proven → propose the bug issue.
- Path deprecated / already fixed on
-
On a proven cause, propose the issue per the
github-issuesskill (Mode B,templates/bug.md), carrying the RCA'sRoot causewith its confidence tag, the reproduction outcome state verbatim, the affectedfile:line, and acceptance criteria including a regression test that fails without the fix. -
Authorization gate. Present the full drafted issue — exact title, complete body, exact labels — and wait for explicit OK, per the
github-issuesskill's<Authorization>contract. Create or comment only on authorization. -
After creating, close the loop (the skill's
<PostCreate>): report#<N>with its URL and the branch name the fix will use (bugfix/issue-<N>-<desc>). If a call failed — a label rejected, a comment not posted — report the failure rather than the number alone.
