Guardrails, Verification & Keeping Agents on Track
The Capstone: Autonomy Without Regret
You can now make Claude run unattended, on a schedule, through a multi-step workflow. That's a lot of power — and power pointed at your files, your accounts, and your customers needs a steering wheel and brakes.
Here's the uncomfortable truth this lesson exists to handle:
Autonomy + write access = real blast radius. An agent that can act without you can also act wrongly without you. The whole game is shrinking the damage a mistake can do.
When you're sitting in an interactive session, you are the guardrail — you see each action and approve it. The moment you step away, that safety net is gone. This lesson is about replacing it with deliberate, designed safeguards so you can sleep while your agents work.
We'll cover six, from outermost to innermost: permissions, blast-radius thinking, dry-runs, hooks, verification loops, and human checkpoints.
1. Permissions: Hand Over Only the Keys You Must
The first and most important guardrail is never giving an agent more capability than its job requires. In an interactive session Claude asks before doing risky things. In headless mode there's no one to ask — so you decide its powers in advance, with flags.
# Allow ONLY reading and writing files — no running shell commands, nothing else
claude -p "Summarize new entries in data.csv into report.md" --allowedTools "Read" "Write"
| Flag | What it does |
|---|---|
--allowedTools | A whitelist — Claude may use only these tools (the safe default mindset) |
--disallowedTools | A blacklist — block specific tools while allowing the rest |
--permission-mode | Sets how permissions are handled for the run (e.g. a planning-only mode that takes no actions) |
There is also a flag that turns all permission checks off. It exists for fully isolated sandboxes, and you should treat it the way you'd treat a chainsaw with no guard:
# DANGER: bypasses every safety check. Only in a throwaway, offline sandbox.
claude -p "..." --dangerously-skip-permissions
The name is a warning, not a suggestion. For real automation, whitelist with --allowedTools and grant the minimum. A read-only summarizer should never have permission to run shell commands or delete files — even if you "trust" it, the point is to make a bad outcome impossible, not unlikely.
2. Blast-Radius Thinking
Before you automate anything, ask one question:
"If this agent did the worst plausible wrong thing, how bad would it be — and could I undo it?"
That's blast radius. It's the single best lens for deciding how much autonomy to grant. Sort every action into a mental tier:
| Blast radius | Examples | How much autonomy? |
|---|---|---|
| Tiny / reversible | Reading files, writing to a log, drafting | Full autonomy is fine |
| Medium / annoying to undo | Editing project files, moving things around | Autonomy + verification + good logs |
| Large / hard or impossible to undo | Deleting data, sending emails, posting publicly, anything involving money | Keep a human in the loop — always |
The skill isn't "make the agent never fail." It's "arrange things so that when it fails, the failure is cheap." Give your agent a sandbox folder instead of your whole disk. Run it against a copy of the data, not the original. Use a test account before a real one. Shrink the blast radius first; then turn up the autonomy.
3. Dry-Runs: Look Before You Leap
A dry-run is asking the agent to tell you what it would do without actually doing it. It's the cheapest possible safety check and you should use it constantly while developing an automation.
"Plan how you'd reorganize this folder and list every file you'd move and where — but do not move anything yet. Just show me the plan."
You read the plan. If it's sane, you run it for real. If Claude was about to do something dumb, you caught it for free. Build every new automation in this order: dry-run until the plan is reliably correct → then let it act. A planning-only permission mode is the formal version of this — Claude analyzes and proposes but is structurally unable to make changes.
4. Hooks: Automatic Guardrails on Every Action
Permissions decide what an agent can do. Hooks let you run your own checks around what it does — automatically, on every relevant action. A hook is a command Claude Code runs when a specific event happens, configured in a settings.json file.
The events you'll care about most:
| Hook event | Fires… | Use it to… |
|---|---|---|
PreToolUse | Before Claude uses a tool | Inspect and block a dangerous action before it happens |
PostToolUse | After a tool succeeds | Auto-format, log, or run a check on what just changed |
Stop | When a turn finishes | Run a final verification or send a "done" notification |
A PreToolUse hook is the powerful one: it can veto an action. Here's the shape of a hook config that inspects every shell command before it runs:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "~/scripts/check-command-is-safe.sh" }
]
}
]
}
}
Your check-command-is-safe.sh could, for example, refuse anything containing rm -rf by exiting with a failure code — and Claude's action is blocked before it can run. Hooks are how you encode a rule like "never let this agent delete things, no matter what it decides" as an unbreakable wall rather than a polite request in a prompt.
5. Verification Loops: Trust, but Check
Autonomy without verification is just hoping. A verification loop means the agent (or you) confirms the work actually succeeded before calling it done.
Bake verification right into the prompt:
"After writing the report, re-read the file you created and confirm it contains all five sections. If any section is missing, fix it and check again. Then output 'VERIFIED' or 'FAILED' as the last line."
That last line is gold for automation: a downstream step can check for VERIFIED and only proceed (or only stay quiet) if the work passed. The principle from earlier modules — ask Claude to critique and check its own output — becomes a structural safety feature when no human is watching. Where a real tool can confirm success (a test suite, a build, a status code), prefer that over Claude's self-report; an objective check beats a confident opinion.
6. Human-in-the-Loop Checkpoints
The final guardrail is the oldest one: for anything in the "large blast radius" tier, a human approves before it happens. You met this in the last lesson as "draft, don't send." Generalize it:
- Claude prepares; you approve. (Draft the email, stage the change, propose the deletion list.)
- The agent notifies and waits instead of acting. ("3 items ready to publish — reply YES to proceed.")
- Risky steps require a manual trigger rather than running on the schedule.
This isn't a failure of automation — it's good automation. You've still offloaded the gathering, the analysis, and the drafting. You've kept only the irreversible decision, which is exactly where a human belongs.
Logging: The Guardrail That Makes the Others Useful
Underneath all of this: log everything your agents do. Every run should leave a trail — what it looked at, what it decided, what it did, whether it verified.
claude -p "..." --allowedTools "Read" "Write" >> ~/logs/agent-$(date +%Y-%m-%d).log 2>&1
Logs are how you answer "what on earth did it do at 3am?" — for debugging, for trust, and for catching a problem on day two instead of day twenty. An unlogged agent is one you're flying blind with.
Putting It Together: A Safety Checklist
Before you let any agent run unattended, walk this list:
- Permissions — does it have only the tools its job needs? (
--allowedTools) - Blast radius — if it does the worst wrong thing, is it cheap and reversible?
- Dry-run — have I watched it plan correctly before letting it act?
- Hooks — is anything truly forbidden walled off, not just discouraged?
- Verification — does it confirm its own work and report pass/fail?
- Human checkpoint — is every irreversible action behind my approval?
- Logging — will I be able to see exactly what it did?
Run an agent that passes this checklist and you get the best of both worlds: real work happening while you're away, with the damage from any single mistake kept small on purpose.
Summary
- Autonomy + write access = blast radius. Guardrails exist to make a mistake cheap, not just unlikely.
- Permissions first: grant the minimum with
--allowedTools; treat--dangerously-skip-permissionsas a chainsaw for isolated sandboxes only. - Blast-radius thinking sorts actions by how bad-and-irreversible they are, and sets autonomy accordingly — sandbox folders, copies, and test accounts shrink it.
- Dry-runs preview what an agent would do; hooks (
PreToolUse,PostToolUse,Stop) enforce rules automatically and can block dangerous actions. - Verification loops make the agent confirm its own work (or an objective tool confirm it); human checkpoints keep every irreversible action behind your approval.
- Log everything — an unlogged agent is one you're trusting blind. Run the 7-point checklist before going unattended.