This lesson is being recorded

Every video of this course is being uploaded to my YouTube channel. Subscribe so you do not miss it.

Bruno AshfordBruno Ashford @brunoashfordSubscribe

Module 10 · Lesson 10.3 · 12 min

Hooks: Automatic Triggers and Guardrails

Add hooks that run automatically before and after the agent's actions, to log changes and block anything your policy forbids.

Module 10
Agents That Work While You Sleep

Schedules, headless runs, hooks and one-word commands

Bruno Ashford
Bruno Ashford · Module 1001 / 12
The problem
A routine that depends on your memory is not a routine.
Bruno Ashford
Bruno Ashford · Module 1002 / 12
Lesson 10.1

Three ways to schedule

OptionRuns whereBest when
Cloud routine (/schedule)Anthropic cloudLaptop closed, sources are connectors or GitHub
Desktop scheduled taskYour computerYou use the Claude desktop app
launchd, cron, Task SchedulerYour computerFiles live locally, full control

Cloud routines are a research preview; check your plan's limits.

Bruno Ashford · Module 1003 / 12
Lesson 10.2

Headless, in one line

claude -p runs the work without the conversation.

  • Nobody is there to approve
  • Decide permissions in advance
  • dontAsk plus a short allowlist
  • Redirect output to a dated file
Bruno Ashford · Module 1004 / 12
Lesson 10.2

Safe defaults for unattended runs

  1. 1Read onlyStart with the Read tool
  2. 2dontAskAnything else is denied
  3. 3Right folderLoads your CLAUDE.md
  4. 4Never skip checksOnly in isolated containers
Bruno Ashford · Module 1005 / 12
Lesson 10.3
Instructions guide the agent. Hooks enforce the rules.
Bruno Ashford
Bruno Ashford · Module 1006 / 12
Lesson 10.3

Hooks you will actually use

EventWhen it runsUse it to
PreToolUseBefore an actionBlock risky commands
PostToolUseAfter an actionKeep an audit log
NotificationWhen Claude needs youGet a desktop alert
StopWhen Claude finishesRun a final check
Bruno Ashford · Module 1007 / 12
Lesson 10.4

One word, same result

Commands and skills are now the same thing.

  • Name becomes the slash command
  • $ARGUMENTS passes in the details
  • Manual-only for client-facing work
  • Share the .claude folder
Bruno Ashford · Module 1008 / 12
Lesson 10.5

The morning brief

  1. 1Yesterday in numbersSales, leads, cash
  2. 2RisksOverdue and at risk
  3. 3Needs youMessages only you can answer
  4. 4TodayMeetings and top three priorities
Bruno Ashford · Module 1009 / 12
Illustrative example, not research

One partner's mornings

50 to 12minutes to get oriented
6:45ambrief ready
1missed deadline caught in week one
Bruno Ashford · Module 1010 / 12
Project

Seven days in production

Trust is built with evidence, not hope.

  • One routine, scheduled
  • Hooks tested and firing
  • One log line per run
  • Improve the prompt on day seven
Bruno Ashford · Module 1011 / 12
Recap
The best automation is the work you find already done, checked and logged when you sit down.
Bruno Ashford
Bruno Ashford · Module 1012 / 12
01 / 12

Use ← → to move. The marker highlights text and the pencil draws on the slide; navigation locks while you annotate. Undo removes the last mark, Esc exits.

1Know where hooks live

Hooks are configured in a settings file: .claude/settings.json in your project (shared with your team) or ~/.claude/settings.json for your own machine. Each hook has an event name, a matcher for which tools it applies to, and the command to run. The /hooks command inside Claude Code shows what is configured.

Prompt for Claude
/hooks
2Add an audit log of every file change

This PostToolUse hook records every file the agent edits or writes into logs/agent-edits.log. It needs the small jq tool (included with recent macOS versions, or install it with Homebrew). You now have a record of what changed, even for runs that happened overnight.

Terminal
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{tool: .tool_name, file: .tool_input.file_path}' >> \"$CLAUDE_PROJECT_DIR\"/logs/agent-edits.log"
          }
        ]
      }
    ]
  }
}
3Block risky commands before they run

A PreToolUse hook on Bash receives the command as JSON. If your script exits with code 2, the command is blocked and the message you print is shown to Claude. The recipes file has a ready script that blocks deletions, pushes to your live site and outgoing POST requests.

Terminal
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-risky.sh"
          }
        ]
      }
    ]
  }
}
4Ask Claude to help, then test it yourself

You can ask Claude to write or adapt a hook, but always test it by deliberately trying the blocked action. A guardrail you have never seen fire is a guardrail you are only hoping works.

Prompt for Claude
Add a PreToolUse hook to .claude/settings.json that runs .claude/hooks/block-risky.sh for every Bash command. Create the script so it blocks any command containing rm -rf, git push or curl with POST or DELETE, prints a clear reason, and exits with code 2. Make the script executable. Then tell me exactly how to test that it works.
5Combine hooks with permission rules

Hooks and permission rules work together. Use deny rules in settings for simple, absolute bans (for example reading .env files) and hooks for checks that need logic, like looking inside a command. Module 11 goes deeper into both.

Instructions in CLAUDE.md are like telling a new employee the rules. They will usually follow them. Usually is not good enough for sending money, deleting files or pushing to your live website. Hooks are different: they are small commands that Claude Code itself runs at fixed moments, whatever the model decides.

A PreToolUse hook runs before an action and can block it. A PostToolUse hook runs after an action, perfect for keeping an audit log. There are also hooks for when a session starts, when Claude stops, and when it sends a notification. You do not need to be a developer to use them: you copy a tested example and change one line.

Key points

  • Instructions guide the agent; hooks enforce the rules.
  • PreToolUse can block, PostToolUse can record.
  • Exit code 2 blocks the action and tells Claude why.
  • Test every guardrail by trying to break it.

Avoid

  • Relying on CLAUDE.md alone for rules that must never be broken.
  • Writing a hook and never testing that it actually blocks.
  • Putting a personal hook in the shared project settings, or the reverse.
  • Making hooks so strict that normal work is blocked and people disable them.
Real-world example: a marketing agency

A London agency lets Claude Code update client landing pages in a staging folder. The owner's fear was an agent pushing unreviewed changes to a live client site. A PreToolUse hook now blocks any git push and any upload command, with the message: publishing needs a human. A PostToolUse hook logs every edited file. In the first month the hook fired six times, each time on a perfectly reasonable request that simply needed a person to sign off.

Bruno Ashford Subscribe