Use Claude Code Hooks for Targeted .NET Verification
A Claude Code PostToolUse hook can run just the relevant xUnit tests right after the agent edits a file, moving verification from prompt reminders into the tool lifecycle. The article walks through an .claude/settings.json entry, the event JSON read from stdin and the meaning of each exit code on a sample Shipping solution. It is equally clear about limits: the hook cannot undo an edit, never sees files rewritten by Bash and does not replace CI.
Key points
- PostToolUse fires after a successful tool call; PreToolUse is the event to use when an action must be blocked before it runs.
- A project-level Edit|Write matcher in .claude/settings.json launches pwsh in exec form with args and a 120-second timeout.
- Command hooks get JSON on stdin; the handler reads tool_input.file_path and the event's cwd rather than arguments invented in the config.
- Exit 2 pushes stderr into Claude's context on PostToolUse, exit 0 returns hookSpecificOutput with additionalContext, and other exits count as non-blocking hook errors.
- The matcher never sees files rewritten by Bash or external tools, and a filter that matches zero tests still exits zero.
- The author exercised the handler with synthetic payloads only; the hook was never registered in a live Claude session.
A Claude Code PostToolUse hook can run a narrow check right after the agent edits a file, turning verification into part of the lifecycle instead of a reminder repeated in every prompt. The example adds an Edit|Write matcher to .claude/settings.json, launches pwsh in exec form with args, resolves the script through ${CLAUDE_PROJECT_DIR} and gives the handler a 120-second timeout.
The handler reads the event JSON from stdin, takes tool_input.file_path and runs dotnet test with a FullyQualifiedName filter only when one of two named files changed. Exit 0 returns additionalContext, exit 2 surfaces stderr to Claude, and neither can undo the edit. Files rewritten by Bash never hit the matcher, a filter that selects no tests proves nothing, and CI stays the authoritative evidence source.
Real-world use
- A solution where a single class holds pricing or shipping rules and its dedicated xUnit tests should run whenever the agent touches either file.
- A repository that forbids local builds and tests on developer machines, so the hook is enabled only inside a disposable validation container.
- A team experimenting with AGENTS.md-style instruction files that wants a real check instead of a reminder to run tests.
- A pipeline that keeps the full test run in CI and treats hook output as fast feedback rather than proof of correctness.
Why it matters
A targeted hook can shrink a full test run from minutes to seconds, but unless exit-code semantics and coverage limits are spelled out, a zero exit gets mistaken for proof that the change is correct.
Related stories
- Retrofitting existing xUnit.Net tests to BobcatJeremy D. Miller (The Shade Tree Developer)5 h ago
- Metalama 2027.0 adds interceptors to redirect method calls at build timeMetalama / PostSharp Blog4 d ago
- Writing executable specifications with Bobcat in C#Jeremy D. Miller (The Shade Tree Developer)5 d ago