addguard: stop an AI agent running git add .¶
The problem¶
An AI coding agent finishes a change and runs git add -A && git commit. It
stages everything else in the folder too: scratch notes, an exported chat, a
.env nobody ignored. If the repo deploys on push, those files are now public.
.gitignore only covers files you thought of in advance.
The method¶
Agent tools such as Claude Code call a hook with each shell command before running it. Exit 2 and the command is refused and the hook's message goes back to the model, so the agent is told what to do instead: stage files by name.
The check splits the line the way a shell does, not with a regex. A regex
blocks a commit whose message mentions git add . and misses
git -c x=y add . or sh -c "git add -A". Parsed properly, quoted text stays
one word, and each simple command is read past NAME=value prefixes,
wrappers (env, sudo), git's own options and into sh -c strings. It
blocks add or stage with -A, --all or a whole-tree path (., :/,
*). git add -u and named files pass.
Sample¶
lex = shlex.shlex(cmd, posix=True, punctuation_chars=";&|()")
lex.whitespace_split = True
# split tokens on ; && || | into simple commands, then for each:
# skip FOO=1 and env/sudo, skip git -C dir / -c k=v, and if the
# subcommand is add/stage with -A, --all, '.', ':/' or '*': exit 2
Hook it into Claude Code's settings.json:
{"hooks": {"PreToolUse": [{"matcher": "Bash",
"hooks": [{"type": "command", "command": "/path/to/addguard"}]}]}}
Limits¶
- It reads the command, not its effect:
$CMD,eval, scripts, git aliases andxargs git addget through. A seatbelt, not a wall. git add somedir/passes, though it stages new files insomedir.- Pair it with a pre-commit hook that refuses new files by name or size.
Code¶
methods/addguard/ in the methods repository: the script (Python standard
library), a README and a 31-check test.