Everything so far has been advice the model can ignore. A hook is where the harness stops asking.
Hook
Also called Agent hook, PreToolUse hook
A script the harness runs at a set moment, such as just before a tool runs or when the agent tries to stop. It can block the action. The model has no say in whether it runs.
A line in AGENTS.md saying "never run rm -rf" can be ignored. A hook that blocks it can't, as long as the hook recognises the command. A script looking for rm -rf will wave through rm -r -f, and in Claude Code, by default, the only exit code that blocks is 2.
Say it to your agent
“Add a PreToolUse hook on Bash in .claude/settings.json. It reads tool_input.command from stdin and exits 2, with the reason on stderr, if the command is rm with both -r and -f in any form. Test it on rm -rf, rm -r -f and rm -fr.”