Telling a coding agent "run the tests after you change something" works most of the time. A hook makes it work every time, and it costs about a dozen lines. Claude Code fires PostToolUse hooks after a tool call finishes. If you match on the file-editing tools, you get a reliable "after every edit" moment where you can run a fast check and hand the result straight back to the agent.

The Hook Mechanism

The core of this approach is a lightweight Python script that listens for file-editing events. By matching against tools like Edit, Write, or MultiEdit, the hook triggers a subprocess call to run the test suite. The script filters for relevant source files, such as .ts, .tsx, or .py, to avoid wasting cycles on documentation or lockfiles. If the tests fail, the script outputs the last 1500 characters of stdout to stderr and exits with status code 2, which signals a blocking error back to the agent.

Configuration and Performance

Integrating this workflow requires minimal configuration in the .claude/settings.json file. The hook is defined under the PostToolUse key, specifying the matcher and the command to execute. Crucially, performance is paramount; developers are advised to swap in their fastest test commands, such as pytest -x -q or npm test --silent --bail, and ensure the check completes quickly. If the verification step takes longer than the edit itself, the agent session stalls, negating the efficiency gains of automated coding.

Why Hooks Beat Instructions

The primary advantage of hooks over project instructions is reliability. The agent sees the failing output immediately, in the same turn, instead of discovering it three edits later. Furthermore, hooks do not suffer from context window limitations or attention drift in long sessions. This approach also keeps project instruction files concise, as the enforcement logic lives in code rather than prose, reducing the cognitive load on the model.

Keep the List Short

Two or three hooks is plenty: a pre-edit guard for dangerous commands, a post-edit test run, and maybe a formatter. Past that, every edit gets slow and noisy.

Key Takeaways

  • PostToolUse hooks provide deterministic enforcement of testing after edits, eliminating agent forgetfulness.
  • Configuration is handled in .claude/settings.json, matching specific tools like Edit, Write, and MultiEdit.
  • Hook scripts must be fast; using silent, fail-fast commands like npm test --silent --bail prevents session latency.
  • Exiting with status code 2 blocks the agent and returns error details directly to the model for immediate remediation.
  • Limiting the number of active hooks to two or three prevents the editing process from becoming slow and noisy.

The Bottom Line

Stop gambling on the LLM's memory. Code is deterministic, instructions are not; if you want reliable test execution in agentic workflows, you must enforce it via hooks, not prose.