Using Agent Hooks for Complex Verification in Claude Code: A Complete Guide

Agent hooks in Claude Code spawn sandboxed sub-agents capable of multi-step reasoning and tool execution to perform complex verification tasks, returning structured JSON decisions that can block or approve workflow steps.

Claude Code supports four distinct hook types—command, http, prompt, and agent—each designed for different automation scenarios. According to the luongnv89/claude-howto repository, agent hooks are uniquely powerful because they launch full-featured sub-agents with access to the complete toolset, making them ideal for implementing automated security reviews, architectural compliance gates, and end-to-end functional validation directly within your development workflow.

How Agent Hooks Work

Agent hooks operate through a five-step lifecycle that integrates seamlessly with Claude Code's event system:

  1. Event Triggering – Claude emits a hook event such as PostToolUse immediately after tools like Write or Edit complete, as documented in [/06-hooks/README.md#L150-L156](https://github.com/luongnv89/claude-howto/blob/main/06-hooks/README.md#L150).

  2. Sub-agent Spawning – When the hook configuration contains "type": "agent", Claude spawns an isolated sub-agent using the provided prompt parameter. The configuration structure is defined in [/06-hooks/README.md#L126-L133](https://github.com/luongnv89/claude-howto/blob/main/06-hooks/README.md#L126).

  3. Tool Execution – The sub-agent operates with the same toolset available to the main session, including Read, Grep, Bash, and others. It can fetch files, execute linters, query repositories, and perform complex investigations as shown in [/04-subagents/code-reviewer.md#L1-L6](https://github.com/luongnv89/claude-howto/blob/main/04-subagents/code-reviewer.md#L1).

  4. Structured Response – The sub-agent must return a JSON payload containing fields such as continue, stopReason, systemMessage, and optional hookSpecificOutput. Claude interprets these fields identically to prompt hooks, per [/06-hooks/README.md#L38-L46](https://github.com/luongnv89/claude-howto/blob/main/06-hooks/README.md#L38).

  5. Workflow Control – Based on the returned payload, the agent can block the workflow using "decision": "block" or allow progression with "decision": "approve", enabling automated quality gates at any pipeline stage [/06-hooks/README.md#L57-L62](https://github.com/luongnv89/claude-howto/blob/main/06-hooks/README.md#L57).

When to Use Agent Hooks for Complex Verification

Agent hooks excel in scenarios requiring multi-step analysis that single-command hooks cannot handle:

  • Security Reviews – After any Write or Edit operation, a sub-agent can run static analysis, secret-scanning, and policy compliance checks before allowing the change to persist.

  • Architectural Compliance – Verify that new modules follow naming conventions, directory structures, or design patterns by having the sub-agent read files and compare them against canonical documentation.

  • End-to-End Functional Validation – Execute unit tests, integration tests, or API health checks. The sub-agent can invoke test runners, parse results, and block the session if any verification fails.

  • Cross-Tool Coordination – After a Bash deployment command, verify service health by querying endpoints, parsing responses, and blocking if the deployment is unhealthy.

Configuring Agent Hooks in Claude Code

Configure agent hooks in your user settings (~/.claude/settings.json) or project-level configuration (.claude/settings.json). Each hook requires a matcher to specify which events trigger it, a type set to "agent", and a prompt that defines the sub-agent's behavior.

Minimal Agent Hook for Code Review

This example fires after every Write or Edit operation, spawning a security and style reviewer:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "agent",
            "prompt": "You are a code-reviewer sub-agent. Run a thorough security and style review of the file that was just written/edited. Return a JSON decision:\n{ \"decision\": \"approve\"|\"block\", \"reason\": \"…\" }",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

The sub-agent leverages the code-reviewer definition found in 04-subagents/code-reviewer.md to perform comprehensive analysis before returning its verdict.

Agent Hook for Custom Deployment Verification

For post-deployment health checks, wrap existing scripts in an agent hook that interprets their output:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "agent",
            "prompt": "Run the health-check script and evaluate its JSON output. If the service is unhealthy, return {\"decision\":\"block\",\"reason\":\"Health check failed\"}. Otherwise return {\"decision\":\"approve\"}.",
            "timeout": 90
          }
        ]
      }
    ]
  }
}

Inside your verification script (e.g., ~/.claude/hooks/verify-deployment.sh), emit JSON that the agent can parse. The LLM prompt then transforms that output into the final blocking or approval decision.

Agent Hook for Full Test Suite Validation

Execute comprehensive test suites and block on any failure:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "agent",
            "prompt": "Execute `pytest -q` in the repository root. If any test fails, return {\"decision\":\"block\",\"reason\":\"Tests failed\"}. Otherwise return {\"decision\":\"approve\"}.",
            "timeout": 300
          }
        ]
      }
    ]
  }
}

The sub-agent invokes the Bash tool to run pytest, captures stdout and stderr, and applies reasoning to determine whether the test results warrant blocking the workflow.

Key Architectural Considerations

When implementing agent hooks for complex verification, understand these critical architectural constraints:

Isolation – Each agent hook runs in its own isolated context. Tool usage within the sub-agent does not affect the main session's tool state, ensuring clean separation between verification logic and primary development work.

Parallelism – Multiple matching hooks fire in parallel across all types. However, agent hook results are awaited before the workflow proceeds, ensuring verification completes before potentially destructive operations continue.

Timeout Configuration – The default timeout is 60 seconds, configurable per hook via the timeout field. Long-running verification tasks, such as full test suites or complex security scans, should explicitly increase this value to prevent premature termination.

Output Format Requirements – Sub-agents must emit valid JSON on stdout and exit with code 0. A non-zero exit code (particularly 2) signals a blocking error to Claude Code, immediately halting the workflow.

Reference the Hook Events table in 06-hooks/README.md (lines 146-160) for the complete list of 25 supported events, including which events support blocking behavior.

Summary

  • Agent hooks are the only hook type in Claude Code capable of spawning full-featured sub-agents with complete tool access.
  • They execute on events like PostToolUse or Stop, enabling verification gates after specific operations.
  • Sub-agents return structured JSON decisions (approve or block) that control workflow progression.
  • Configuration resides in ~/.claude/settings.json or project-level .claude/settings.json using the "type": "agent" specification.
  • Critical implementation details include 60-second default timeouts, strict JSON output requirements, and exit code 0 for successful validation.
  • Example implementations include security reviews (04-subagents/code-reviewer.md), deployment health checks, and automated test validation.

Frequently Asked Questions

What is the difference between agent hooks and command hooks in Claude Code?

Command hooks execute external scripts or binaries directly, receiving input via environment variables and returning decisions through exit codes. Agent hooks spawn a sandboxed LLM sub-agent that can use tools like Read, Grep, and Bash to perform multi-step investigation before returning a structured JSON decision. Agent hooks are necessary when verification requires reasoning, file analysis, or complex conditional logic that static scripts cannot handle.

How do I prevent an agent hook from blocking the workflow indefinitely?

Set an explicit timeout value in your hook configuration (specified in seconds). The default is 60 seconds, but you should increase this for long-running verification tasks like full test suites. If the sub-agent exceeds the timeout, Claude Code treats it as a failure. For critical blocking operations, ensure your prompt instructions include clear completion criteria so the agent terminates promptly after reaching a decision.

Can agent hooks access the same files and tools as the main Claude session?

Yes. According to the luongnv89/claude-howto source code, sub-agents run with the same toolset as the main session, including Read, Grep, Bash, and others. However, they operate in an isolated context, meaning their tool usage does not interfere with the main session's state. The sub-agent can read files, execute commands, and query the repository to perform comprehensive verification before returning its decision.

Where can I find reference implementations for agent hook validation logic?

The repository provides two key reference files: 06-hooks/validate-prompt.py demonstrates reading JSON from stdin and returning structured decisions, serving as a template for custom agent-hook logic. Additionally, 06-hooks/auto-adapt-mode.py shows complex post-tool hook implementations that modify user settings, illustrating how hooks can perform side-effects beyond simple pass/fail decisions. The 04-subagents/code-reviewer.md file contains a complete sub-agent definition optimized for security and style review tasks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →