Guardrails are the mechanisms that sit outside the model's own probabilistic judgment and enforce something deterministically — they exist precisely because a system prompt, no matter how carefully worded, describes intended behaviour rather than guaranteeing it. Hook-style interception points that run before or after a tool executes give you a place in the code, not the prompt, to enforce a policy: blocking a call outright before it runs, logging every consequential action for audit, redacting sensitive data from a tool result before it re-enters the model's context, or normalising inconsistent data formats. None of that depends on the model choosing correctly in the moment.
PreToolUse vs. PostToolUse: two different jobs
PreToolUse hooks run before a tool executes. They intercept the outgoing tool call and can block it, modify it, or redirect it — the underlying tool simply never runs if the hook decides to stop it. This is the only hook direction that can prevent a consequential action, because by definition nothing has happened yet.
PostToolUse hooks run after a tool executes but before the model processes the result. They're the right tool for normalising heterogeneous data formats, redacting sensitive fields, or logging what happened for audit — but they cannot undo an action that has already taken place. A PostToolUse hook that detects a policy violation after a refund has already been issued can flag it for review, but the money has already moved.
Confusing these two is one of the most common mistakes in guardrail design: reaching for a post-execution check to block something is structurally too late. If the requirement is "this must never happen," it belongs in a PreToolUse gate. If the requirement is "this must be clean, consistent, or logged after it happens," a PostToolUse hook is the correct and sufficient tool.
Exam trap: hook direction
The exam will present a PostToolUse hook as a plausible way to prevent a policy-violating action from executing. This is wrong by construction - PostToolUse fires after the tool has already run, so the non-compliant action has already occurred by the time the hook sees it. Only a PreToolUse (pre-execution) hook can actually block something.
The enforcement spectrum: hooks vs. prompts
A useful framing: if a requirement must be followed 100% of the time (a compliance check before an international transfer, a hard dollar threshold that always triggers approval, a rule that customer PII is never written to an external log), enforce it with a hook — deterministic, code-level, cannot be talked around. If a requirement is a preference where occasional deviation is tolerable (format responses as markdown, prefer concise answers), a prompt instruction is sufficient and a hook would be needless overhead. The dividing line isn't "how important does this feel" — it's "would a single failure cause real harm (financial, legal, safety) that the business cannot absorb." If yes, that's a hook, every time.
Where human-in-the-loop earns its cost
A human approval step adds latency and friction, so it should be reserved for genuinely high-consequence, hard-to-reverse actions — not sprinkled everywhere out of general caution. Two properties together determine whether an action deserves a human gate:
- Consequence. How much damage does a wrong instance of this action cause — financial loss, data exposure, legal exposure, reputational harm?
- Reversibility. Can the action be cleanly undone if it turns out to be wrong? A draft that hasn't been sent, a staged database write behind a transaction, a proposed change awaiting merge — these are cheap to catch after the fact. A sent email, an executed wire transfer, a deleted production record — these are not.
An action that's both high-consequence and hard-to-reverse is exactly where a human gate earns its cost. An action that's low-consequence, or that's high-consequence but trivially reversible (a draft sitting in an approval queue), usually doesn't need one. Gating everything regardless of this distinction trains reviewers to click "approve" without really looking — approval fatigue is a real failure mode, and once it sets in, the human gate stops providing any actual safety margin; it becomes a rubber stamp with extra latency.
Pair human-in-the-loop with the least-privilege scoping from Lesson 6.2: fewer actions need a human gate at all once the agent's raw capability is already tightly scoped. An agent that structurally cannot call a payment tool needs zero approval gates on payments; an agent that can, but only up to a small threshold, needs a gate only above that threshold.
Synchronous vs. asynchronous approval, and tiered thresholds
Human-in-the-loop doesn't have to mean "the agent halts entirely and waits." Two common patterns:
- Synchronous (blocking) approval. The agent's execution pauses at the PreToolUse gate until a human explicitly approves or denies; used for genuinely irreversible, high-stakes single actions like a large wire transfer.
- Tiered thresholds. Rather than one blanket gate, different amounts or risk levels route to different handling — a refund under $50 auto-approves, one between $50 and $500 requires any team member's sign-off, one above $500 requires a manager. This keeps friction proportional to actual risk instead of applying the same gate uniformly regardless of severity.
The specific mechanism matters less than the underlying discipline: the gate location and threshold should be a deliberate design decision tied to consequence and reversibility, not a default reflex applied uniformly to every tool in the system.