v0.1.9 — git-guard PreToolUse hook
What's new
hooks/git-guard.sh — deterministic git deny-list enforcement
PreToolUse hook fired on every Bash invocation. Blocks destructive git operations at the tool boundary even when an agent uses bypass forms the classifier misses (git -C <path> reset, sh -c 'git reset', absolute paths to git binary).
Blocks: reset, checkout, stash, rebase, cherry-pick, revert, clean, reflog, filter-branch, gc, prune, fsck, branch -D/-d/-m/-M, config (write form), push --force, merge --abort, worktree remove on dirty/unpushed trees.
Allows: all read-only git, add, commit, push (without --force), worktree add, worktree remove on clean/pushed worktrees.
cli/jq.yaml — declared dependency
jq is required for correct JSON unescape of tool_input.command (sed alone misses \n, \", \\). agents pull will prompt to brew install jq when missing.
agents.yaml registration
Hook is wired for Claude, Codex, and Gemini under hooks.git-guard with matcher: Bash, events: [PreToolUse], timeout: 5.
Behavior
- Hot-path overhead: ~7ms for non-git Bash commands (fast-path), ~14ms for git commands (jq + segment scan).
- Coverage: handles multi-line, sh -c wrappers, absolute paths, quoted tokens, env-var prefixes,
git -Cpeeling. - Out of scope (documented in
hooks/git-guard.md):eval,xargs git,\$(...)subshells, base64-decoded payloads, sourced aliases.
Tested
23 test cases pass including bypass forms (git -C, sh -c, absolute /usr/bin/git).