Last updated June 28, 2026 · 4 min
Claude Code Hooks: Hardcoded Guardrails and Automation for AI Agents
Why standard prompts aren't enough. Learn how to use hardcoded hooks to enforce strict boundaries and build reliable automation for your AI agents

Writing "Do not modify production files" or "Always check the project context" in CLAUDE.md is merely guidance. Claude might obey it, or it might hallucinate and forget it entirely.
If you want a guarantee, you need Hooks.
Hooks are programmable checkpoints that intercept an AI agent's execution flow before or after an action occurs. They don't rely on the LLM's judgment. They rely on the actual code you write.
Here is a practical guide to understanding the Hook mental model and how we apply it at Sloop to build robust, multi-agent workflows.
The Mental Model: Guidance vs. Enforcement
Think of your agent's execution pipeline in three distinct layers:
CLAUDE.md(Guidance): Gives the agent context, rules, and coding style. This is "soft" control.- Skills (Workflow): Organizes the agent into reliable workflows and toolsets.
- Hooks (Guardrails & Automation): Acts as the strict boundary. It runs actual native code at key lifecycle events to validate payloads, block actions, or inject dynamic context.
When Claude attempts to use a tool, start a session, or change state, a Hook intercepts that event. Your script evaluates it and returns a JSON decision (allow, deny, or ask), or simply performs a background task like logging.
Crucial Detail for Blocking: To block an agent, your script must exit with code
0and return a JSON payload like{"decision": "deny"}. Usingexit 1will not block the agent; Claude will treat it as a transient environment error and try to bypass it.

Two Real Hooks Worth Studying (The Sloop Way)
Instead of generic examples, let's look at how we use Hooks to power Sloop's core features. These cases demonstrate how Hooks can do much more than just block files: they can bridge your AI agent to external systems.
Case 1: Context-Inject Hooks (Sloop Memory Vault)
Event: SessionStart
The Problem: Portable context today is static (AGENTS.md). Every time you start a new session, the agent forgets the decisions made in the last one. If you want the agent to learn, you shouldn't have to manually edit context files.
The Hook Solution: Sloop's Memory feature uses a SessionStart hook to dynamically inject a "2nd brain" vault into the agent. Instead of rewriting the agent's internal prompt, Sloop registers a read-only hook:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear",
"hooks": [
{
"type": "command",
"command": "sloop context emit"
}
]
}
]
}
}
How it works: When a session starts, Claude pauses and runs sloop context emit. Sloop selects the most relevant memory slices (based on recency and workspace) and prints them to stdout. Claude ingests this output as initial context.
Insight: Hooks don't always have to block; sometimes bringing the right dynamic information in at the exact right moment is the entire job.
Case 2: Status Observability Hooks (Sloop ps)
Event: Lifecycle transitions (PostToolUse, UserPromptSubmit, Stop)
The Problem: When you run multiple agents across a fleet, external tools have no idea what the agents are doing (waiting, working, or idle).
The Hook Solution: Sloop uses lifecycle hooks to emit status updates, allowing sloop ps to track agent states in real-time.
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "sloop hooks emit idle"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "sloop hooks emit working"
}
]
}
]
}
}
How it works (and respects privacy): Every time Claude starts thinking or stops to wait for the user, these non-blocking hooks silently run the sloop hooks emit <state> command. It simply updates a local marker file (~/.sloop/state).
Insight: This creates a perfect observability bridge without ever reading the prompt or the model's response. The hook acts purely on the event trigger, keeping your session entirely private.

5 Things to Remember About Hooks
- Hooks are not prompts. They are code. They run regardless of the model's state.
exit 1does nothing. Useexit 2for system errors. Useexit 0 + JSONfor policy decisions.- Events are siblings.
PreToolUseandPermissionRequestfire independently. One does not cause the other. - Strictest result wins. When multiple hooks conflict, one
denyfrom any layer blocks the operation. Allowing requires everyone to agree. - Privacy by construction. Hooks like Sloop's Status Hook prove you can build powerful cross-agent observability without ever scraping the user's actual prompts or session data.
By isolating guidance (CLAUDE.md) from enforcement and automation (Hooks), you build a robust environment where AI agents can operate autonomously without compromising system control.