# Diagnose

> Diagnose and fix failing tests. Failure classification, root-cause analysis (never retry blindly), then the reproduce → isolate → fix → retest → regression loop. Use when: 'why does this fail', 'this test is failing', 'fix the failing tests', 'why is this test flaky', visible test failures, stack traces, or flaky tests; for authoring new tests use /testing:write, for running the suite /toolchain:check.

- Skill: `melodic-software/diagnose` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add melodic-software/diagnose`
- Raw SKILL.md: https://api.skillmd.com/api/skills/melodic-software/diagnose/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: melodic-software (https://skillmd.com/u/melodic-software)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/melodic-software/diagnose

---


## Repository context. Gather first

Collect these with **individual** Bash calls, one command per call, never combined into a single
invocation:

- Current branch, `git branch --show-current`
- Working tree status (empty = clean), `git status --porcelain | head -20`

The pipe is the bound and belongs in the command. A read-time cap ("read only the first 20 entries")
bounds nothing: the Bash tool returns the command's complete output into context before there is
anything to decide about.

Treat a failure (not a repository, git unavailable) as an unknown value and carry on. Keep these as
separate body Bash calls rather than pre-compute lines: the harness runs a skill's whole pre-compute
block as one shell invocation, and a worktree-isolated session refuses a compound command that
contains git. The dated record for that composition claim is the worktree skill's
[reference/gather-block.md](https://raw.githubusercontent.com/melodic-software/claude-code-plugins/main/plugins/source-control/skills/worktree/reference/gather-block.md),
"The pre-compute block runs as one shell invocation".

## Purpose

The failure half of testing: understand WHY a test fails, then prove the fix. Never dismiss a failure, never retry blindly. "Probably a timing issue" is not a diagnosis; even intermittent failures have deterministic root causes. Repo-specific shared-state workarounds and framework traps live in the consuming project's testing conventions. Consult them before diagnosing.

## Redact

Diagnosis surfaces commands, test output, stack traces, and CI logs. Redact every secret before showing it. Write `<REDACTED>` in its place. Reproductions that need credentials read them from env vars, so the secret never lands in a command line, a fixture, or the regression test you commit. Captured output carries auth headers. Quote only the lines carrying the diagnostic signal; if that is not enough to diagnose, say so and ask.

## Arguments

`$ARGUMENTS`, optional failure description or `loop` to enter the fix cycle directly for an already-diagnosed bug.

## Step 0: Route

| Signal | Phase | Context file |
|--------|-------|-------------|
| Failure needs diagnosis. Stack trace, assertion mismatch, flaky test | **investigate** | [context/investigate.md](context/investigate.md) |
| Root cause known, fix needed. Reproduce → isolate → fix → retest → regression | **loop** | [context/loop.md](context/loop.md) |

Default entry is **investigate**; it chains into **loop** once the root cause is found. Read the relevant context file before proceeding.

## Handoff

| After phase | Suggest |
|-------------|---------|
| `investigate` | Enter the `loop` phase if a fix is needed, or report root cause. Root cause in test infrastructure → fix the test, not production code. Genuine bug → document, then fix via `/implementation:implement fix` |
| `loop` | `/verification:confirm fix` (when the `verification` plugin is installed) when all green after the regression pass (routes fix-confirmation to the `fix` criterion. Symptom resolved + no regression) |

## Integration with /implementation:implement

When `/implementation:implement` hits a test failure during its TDD cadence it chains here for the reproduce→fix→retest cycle, then resumes after the loop exits green. Invoked standalone, the loop drives the full cycle including code edits and suggests `/verification:confirm` afterwards.

## What this skill does NOT do

- **Does not run the suite wholesale**. `/toolchain:check` is SSOT for CLI invocation; this skill runs targeted reproductions
- **Does not author new feature tests**. `/testing:write` (the loop's reproduce step writes only the failing test capturing the bug)

## Gotchas

- Framework traps. .NET examples: under the Microsoft Testing Platform runner, `--nologo` is not a platform option and an unrecognized option exits 5 (an invalid-argument exit, not a zero-test result, which is exit 8 or 9); the banner switch there is `--no-banner`, and the native xUnit v3 spelling is `-noLogo`. In that runner `dotnet test` takes `--project`, `--solution`, or `--test-modules` and no positional path, and `--project` defaults to the current directory rather than being required. The runner is selected by `global.json`, and the classic runner remains the default, so confirm which one the project uses before reading any of this as its behavior. Parallel-execution races are the third trap. Check the consuming project's own gotcha notes before diagnosing. Verified 2026-09-06 against the vendor's testing-platform CLI options, troubleshooting, and `dotnet test` reference pages; recheck when the platform option list gains `--nologo` or the runner-selection default changes
- Process-global singleton symptoms ("frozen", "already initialized"). Usually a shared-state fixture problem; check the consuming project's fixture conventions for the named pattern before inventing a workaround

