---
name: dotnet-doctor
description: Check, diagnose, format, clean up, and repair scoped .NET changes in this repository using dotnet format, analyzer-enabled builds, TUnit tests, and JetBrains command-line tools. Use when the user asks to run .NET Doctor, inspect or fix C#/.NET changes, prepare .NET work for a commit or PR, or when AGENTS.md requires the deferred pre-commit .NET verification gate. Do not trigger for conceptual .NET questions that do not change or inspect repository files.
---

# .NET Doctor

Use deterministic repository tooling before judgment-based fixes. Keep the requested scope separate from unrelated pending work.

## Gate timing

Do not invoke the Doctor workflow after each edit, milestone, or conversational turn. Defer it until implementation is complete and one of these conditions applies:

- the agent is about to commit or create a pull request;
- the agent is explicitly handing the changes off as ready to commit;
- the user explicitly requests the Doctor or verification.

Run the pre-commit or pre-PR gate once in fix mode, then rerun the automatic check tier to verify the result. The gate owns formatting, cleanup, the analyzer-enabled build, and relevant tests; do not duplicate those commands before or after the workflow. If no agent-driven commit, pull request, or explicit ready-to-commit handoff occurs, remind the user to invoke `$dotnet-doctor` in fix mode immediately before a manual commit instead of running it automatically.

If .NET-relevant files change after a passing gate, the result is stale and the gate must run again before commit. Earlier test runs are appropriate only for explicit test-driven development, active diagnosis, or a direct user request.

## Load the project guidance

Read [references/repository.md](references/repository.md) before selecting targets or commands. Read [references/tooling.md](references/tooling.md) before running formatters, JetBrains tools, or tests.

## Select one mode

### Automatic check

Use for read-only scoped verification when explicitly requested. The `AGENTS.md` pre-commit gate uses fix mode instead.

- Check only files changed by the current task and the projects they affect.
- Use `Debug`.
- Verify formatting, build with configured analyzers, and run directly relevant non-explicit tests.
- Do not modify source or configuration files.
- Do not run InspectCode.

### Explicit check

Use when the user asks to check, analyze, inspect, validate, or run the Doctor without asking for modifications.

- Remain read-only.
- Honor the user's explicit file, project, solution, or pending-change scope.
- Use the automatic check tier unless the user requests a deep check.

### Deep check

Use when the user explicitly requests a deep or full Doctor. An ordinary request to prepare changes for a commit or pull request uses fix mode followed by the automatic check tier unless the user specifically asks for deep verification.

- Use `Release`.
- Restore tools and packages explicitly.
- Verify formatting, build with analyzers, run JetBrains InspectCode, and run the broader relevant non-explicit test set.
- Analyze the entire solution only when the scope or a shared configuration change requires it.

### Fix

Use when `AGENTS.md` invokes the final pre-commit or pre-PR gate, or when the user explicitly asks to fix, format, clean up, remediate, or resolve findings.

1. Record the baseline and establish diagnostics.
2. Run scoped `dotnet format`.
3. Run scoped CleanupCode with `Built-in: Reformat & Apply Syntax Style` unless the user names another profile.
4. Apply small targeted manual fixes for remaining verified findings.
5. Inspect the diff and rerun the applicable check tier.

Do not run `Built-in: Full Cleanup` unless the user explicitly requests it.

## Resolve scope

Use this precedence unless the user says otherwise:

1. Explicit files supplied by the user.
2. Files changed by the current agent task.
3. Pending Git changes.
4. A named project or solution.
5. The entire solution.

For agent-task scope, maintain the set of files created, edited, renamed, or deleted during the task. Do not substitute all pending changes when unrelated work existed beforehand.

For pending-change scope, combine staged, unstaged, renamed, deleted, and relevant untracked files. Exclude generated and output paths such as `bin/`, `obj/`, `artifacts/`, `TestResults/`, generated migrations, and generated service references unless explicitly requested.

Map every scoped source file to each project that compiles it. Expand verification when shared build configuration, package management, source generators, public contracts, or analyzer settings affect multiple projects. Explain every expansion.

If no applicable .NET source or configuration files remain, report an empty scope. Do not silently switch to the whole solution.

## Preserve the worktree

Before running tools:

1. Record `git status` and the relevant staged and unstaged diffs.
2. Separate pre-existing changes from current-task changes.
3. Record the selected mode, direct file set, affected projects, test targets, exclusions, and scope expansions.

After every modifying tool, inspect the complete changed-file set. Preserve pre-existing user changes and revert only tool-created changes that are proven unrelated. Never use a destructive reset or blanket checkout to constrain formatter output.

## Run the workflow

1. Work from the Git root for Git discovery, then run .NET commands from the workspace resolved in the repository reference.
2. Verify the SDK and tool availability according to the restore policy in the repository reference.
3. Run formatting verification in check modes, or the fix sequence in fix mode.
4. Build every affected project, or the solution when impact cannot be bounded safely.
5. Run relevant tests according to the repository test policy.
6. Run InspectCode only for deep checks or when explicitly requested.
7. Deduplicate overlapping compiler, Roslyn, Sonar, and JetBrains findings by cause.
8. Inspect the final diff and report honestly.

Treat restore, build, analyzers, source generators, and tests as repository-controlled code execution. Run them only in a trusted repository.

## Remediation boundaries

Modify only scoped files by default. Change a supporting file only when required for a correct verified fix, and explain the expansion.

Do not:

- suppress or lower diagnostics merely to pass;
- weaken `.editorconfig`, analyzer, Sonar, or JetBrains settings;
- edit generated code;
- update the SDK or dependencies solely to remove a warning;
- change public APIs for style alone;
- repair unrelated repository debt;
- run unscoped cleanup for a narrow request;
- discard pre-existing work;
- claim success when a required check failed, was skipped, or could not run.

## Classify results

Classify findings as:

- `Scoped`: located in the effective file set;
- `Introduced`: caused by the current task;
- `Blocking`: outside scope but prevents reliable build, analysis, or tests;
- `Existing debt`: unrelated and demonstrably pre-existing;
- `Configuration impact`: caused by a scoped configuration change with broader effect;
- `Verification limitation`: a required check that could not complete reliably.

Fail the gate for formatting drift, build or test failures, and unresolved scoped, introduced, blocking, or configuration-impact findings. Use `PASS WITH EXISTING DEBT` only when scoped work is clean and unrelated debt remains.

## Report

For an automatic successful check, report compactly:

- `PASS` or `PASS WITH EXISTING DEBT`;
- direct scope and affected projects;
- checks run and tests selected;
- remaining debt or limitations.

For deep checks, failures, or fix mode, include:

- status: `PASS`, `PASS WITH EXISTING DEBT`, or `FAIL`;
- mode, files, projects, exclusions, and scope expansions;
- each check as passed, failed, or not run;
- files changed and cleanup profile in fix mode;
- unresolved findings with classification, tool, rule ID, file, line, and remediation state;
- existing debt and verification limitations in separate sections.

Never state that code is clean when a required check was skipped or unavailable.
