AI Team Playbook / Rule 3 of 12
Enforce the rules with settings and hooks
Any rule the agent must not break is enforced by a setting or a hook. A sentence in the instruction file is only advice.
September 16, 2026 · About 4 minutes
Why
An agent works toward finishing its task. If the instruction file says not to force push, the agent usually complies. A hook blocks the command every time. Anthropic’s own guidance for Claude Code is that the instruction file is advisory and hooks are deterministic [13], and its engineers run agents on remote machines whose outbound network access is limited to an allow list [12].
The same applies to “verify before saying done”. An agent can report success on a change whose tests fail. A hook can run the test command and send the agent back to work while the tests fail.
How
The settings file is committed and shared. It has three permission lists. Allow is what runs without asking: build, test, lint, read-only git. Ask is what a human confirms each time: commit, push, open a pull request, apply a migration. Deny is what never runs: reading .env and key files, force pushes, rm -rf, the common deploy commands. Add the project’s own deploy commands to it. Settings stack in a fixed order, and a deny anywhere in the stack wins, so a developer can add convenience locally but cannot remove protection. The sandbox setting limits network access to the package registries and the git host.
Secrets need two lists. A Read(...) deny rule stops the agent’s file tool. It does not stop a shell command, so cat .env would still work. The sandbox’s filesystem.denyRead list covers the shell. The kit ships both. Keep them in step: a path added to one goes into the other.
Three hooks ship in the kit. Each is a small shell script that receives what is about to happen as JSON, and its exit code decides what happens next.
block-destructive.shruns before every shell command and catches the variants the deny list misses: chained commands,sudo, flags in a different order or spelled out in full,--force-with-leaseand+branchpushes,git clean -f,dotnet ef database dropandkubectl delete. It matches flags as whole words, so a branch namedtask/142-fix-loginis not mistaken for-f. Exit code 2 blocks the command and the script’s message becomes the agent’s explanation.lint-on-edit.shruns after every file edit, formats the file, and never blocks. A problem it finds is printed, and the agent fixes it in its next step.stop-gate.shruns when the agent is about to say it has finished. If the project check fails, the agent keeps working with the failure as its next instruction. After three failed attempts in one session, it lets the agent stop with a message that the task is not done, so a human can take a look. CI runs the check again on the pull request either way.
CHECK="${PLAYBOOK_CHECK:-}" # set this to the project's real, fast check
MAX_BLOCKS=3
if [ -z "$CHECK" ]; then
status=1
out="The stop gate is not configured. Set CHECK in .claude/hooks/stop-gate.sh."
else
out="$(bash -c "$CHECK" 2>&1)"
status=$?
fi
if [ $status -eq 0 ]; then rm -f "$counter"; exit 0; fi
# $counter is a small file per session that counts the blocks
blocks=$(( $(cat "$counter" 2>/dev/null || echo 0) + 1 ))
if [ "$blocks" -gt "$MAX_BLOCKS" ]; then
rm -f "$counter"
echo "Stop gate: still failing after $MAX_BLOCKS attempts. The task is not done." >&2
exit 0
fi
echo "$blocks" > "$counter"
{
echo "Stop gate ($blocks of $MAX_BLOCKS): the project check failed. Fix it before finishing."
echo "$out" | tail -60
} >&2
exit 2
Install is two lines: make the scripts executable, and set CHECK in stop-gate.sh to the project’s real check. Until it is set, the gate blocks with a message that it is not configured, so an unconfigured gate is never mistaken for a passing one. Keep the check under a few minutes to run. The full suite belongs in CI.
Identity without privileges.
The settings bound what the agent may run. They do not, by themselves, bound who the agent is. When it runs as the developer, with the developer’s git credentials, cloud logins and files, everything it can reach is everything the developer can reach. The stronger version, which JPMorgan adopted for its engineers in 2026 and Anthropic uses for its own, gives the agent its own scoped identity, keeps it away from secrets and internal systems, and caps what it can spend [20, 12]. Appendix D is the checklist for that.
What this does not do. A developer can edit any of these files locally, or skip the tool altogether. The hooks guard against the agent. The pull request guards against the developer, which is rules 8, 9 and 10. Some rules are checked at the pull request, after the session. A change under contracts/ inside a task that is not a contract task is one: the reviewer agent, the automated first pass and the High tier all look for it. A team that wants the rule files themselves locked down follows appendix C.
References
- 12Anthropic, "How Anthropic secures its AI-native software development lifecycle", July 2026. claude.com/blog/how-anthropic-secures-its-ai-native-software-development-lifecycle
- 13Anthropic, Claude Code documentation, "Best practices for Claude Code". code.claude.com/docs/en/best-practices
- 20Business Insider, report on JPMorgan's Claude Code spending limits and its Devspace sandbox, September 2026. A 2,000 dollar monthly cap per engineer, a containerized environment on AWS, and CISO Pat Opet on agents with no entitlements. Paywalled; the figures here are as reported by the outlets that covered it. www.businessinsider.com/jpmorgan-claude-spending-limit-security-engineers-2026-9