🎯 Problem
The MERGE RULE (never merge, tag, or push main without Dean's explicit per-action consent) lives only in prompt text and assistant memory. Every builder/reviewer subagent has Bash; nothing mechanical stops gh pr merge or git tag.
✅ Fix
Add a PreToolUse hook on Bash to .claude/settings.example.json and the active settings.local.json:
{ "matcher": "Bash", "hooks": [{ "type": "command",
"command": "c=$(jq -r '.tool_input.command // empty'); case \"$c\" in *'gh pr merge'*|*'git push'*origin*main*|*'git tag'*) echo 'refuse: merge/tag/push-main needs Dean per-action consent (MERGE RULE)' >&2; exit 2;; esac; exit 0" }] }
Exit 2 blocks the call and feeds the message back to the model. Dean lifts it per action by running the command himself or temporarily editing the hook.
Depends on the hooks fix (stdin JSON, not $CLAUDE_FILE_PATHS).
📎 Source
docs/AI_TOOLKIT_AUDIT_CLAUDE.md F2b.
🎯 Problem
The MERGE RULE (never merge, tag, or push
mainwithout Dean's explicit per-action consent) lives only in prompt text and assistant memory. Every builder/reviewer subagent hasBash; nothing mechanical stopsgh pr mergeorgit tag.✅ Fix
Add a
PreToolUsehook onBashto.claude/settings.example.jsonand the activesettings.local.json:{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "c=$(jq -r '.tool_input.command // empty'); case \"$c\" in *'gh pr merge'*|*'git push'*origin*main*|*'git tag'*) echo 'refuse: merge/tag/push-main needs Dean per-action consent (MERGE RULE)' >&2; exit 2;; esac; exit 0" }] }Exit 2 blocks the call and feeds the message back to the model. Dean lifts it per action by running the command himself or temporarily editing the hook.
Depends on the hooks fix (stdin JSON, not
$CLAUDE_FILE_PATHS).📎 Source
docs/AI_TOOLKIT_AUDIT_CLAUDE.mdF2b.