# A Guardrail Hook — Advanced Agent Workflows and Skills

Source: https://www.geekswithgeeks.com/en/agent-workflows/hooks-guardrail

> Block dangerous commands before they run and format files after edits.

## Check, then allow or block

A **pre-tool** hook sees the tool call before it executes and can reject it, with a message the model reads and adapts to. A **post-tool** hook can run formatters or tests after an edit. Together they enforce rules without extra prompting.

## Block force pushes

This script reads the hook JSON, and exits with code 2 to block the call and show the reason. The exact JSON fields and exit-code behaviour are defined by your agent's hook documentation, so check them for your version.

```bash
#!/usr/bin/env bash
# .claude/hooks/block-force-push.sh
cmd=$(jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -Eq 'git push.*(--force|-f)'; then
  echo "Blocked: force pushes are not allowed. Use a normal push." >&2
  exit 2
fi
```

## Block with a reason

A bare "denied" leaves the model guessing. A message that says what to do instead lets it fix the plan on the next turn.

**Quiz:** Why should a blocking hook print a reason?

- [ ] Reasons are required by Linux
- [x] So the model can adjust its plan
- [ ] To slow the agent down
- [ ] Hooks cannot block otherwise

*Answer:* So the model can adjust its plan. The message is fed back to the model, which can then choose a safe alternative.
