Block No Verify Hook

作者 wshobson46891e7e60da無授權條款收錄於 2026年10月8日更新於 2026年10月8日

Configure a PreToolUse hook to prevent AI agents from skipping git pre-commit hooks with --no-verify and other bypass flags. Use when setting up Claude Code projects that enforce commit quality gates.

AI 產生的概覽

設定 Claude Code 的 PreToolUse 掛鉤,攔截 --no-verify、--no-gpg-sign 等 git 繞過參數。

功能
提供寫入 .claude/settings.json 的 PreToolUse 掛鉤設定,用來檢查 Bash 工具呼叫並拒絕含有 git 繞過參數的指令。掛鉤以 grep 比對 command 欄位,用結束碼 2 阻擋呼叫並輸出錯誤訊息。文件也說明依專案或全域安裝、驗證方式,以及如何擴充比對更多參數。
適用情境
適合需要強制提交品質閘門的 Claude Code 專案,避免代理跳過 pre-commit 掛鉤、程式碼檢查、測試或 GPG 簽章。也適合記錄或擴充既有掛鉤設定時使用。
執行需求
支援掛鉤的 Claude Code 以及 .claude/settings.json 檔案;掛鉤依賴 grep 與 POSIX shell。此技能未附帶任何指令碼。

Block No-Verify Hook

PreToolUse hook configuration that intercepts and blocks bypass-flag usage before execution, ensuring AI agents cannot skip pre-commit hooks, GPG signing, or other git safety mechanisms.

Overview

AI coding agents (Claude Code, Codex, etc.) can run shell commands with flags like --no-verify that bypass pre-commit hooks. This defeats the purpose of linting, formatting, testing, and security checks configured in pre-commit hooks. The block-no-verify hook adds a PreToolUse guard that rejects any tool call containing bypass flags before execution.

Problem

When AI agents commit code, they may use bypass flags to avoid hook failures:

bash
# These commands skip pre-commit hooks entirelygit commit --no-verify -m "quick fix"git push --no-verifygit commit --no-gpg-sign -m "unsigned commit"git merge --no-verify feature-branch

This allows:

  • Unformatted code to enter the repository
  • Linting errors to bypass checks
  • Security scanning to be skipped
  • Unsigned commits to bypass signing policies
  • Test suites to be circumvented

Solution

Add a PreToolUse hook to .claude/settings.json that inspects every Bash tool call and blocks commands containing bypass flags.

Configuration

Add the following to your project's .claude/settings.json:

json
{  "hooks": {    "PreToolUse": [      {        "matcher": "Bash",        "hooks": [          {            "type": "command",            "command": "if grep -qE '\"command\"[[:space:]]*:[[:space:]]*\"([^\"\\\\]|\\\\.)*(--no-(ver|g)|commit([^\"\\\\]|\\\\.)*([[:space:]]|\\\\[tn])-[a-zA-Z]*n)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"          }        ]      }    ]  }}

How It Works

  1. Matcher: The hook targets only Bash tool calls, so it does not interfere with other tools (Read, Edit, Grep, etc.).
  2. Inspection: Claude Code sends the tool call to the hook as JSON on stdin and sets no $TOOL_INPUT variable. The hook searches the command value in that JSON with grep -E, so it needs no jq or node, and text in other fields, such as cwd or the tool call's description, can't trigger it. It blocks --no-verify, --no-gpg-sign, and any shorter prefix of them that git accepts, e.g., --no-veri. It also blocks a short option group with n that follows commit in the same command, e.g., -n or -nm, because -n is the short form of --no-verify. The hook doesn't look for the word git, so it also catches if git ..., sudo git ..., and g=git; $g commit --no-verify. A false match, such as a commit message that mentions a flag, blocks the call, which is the safe way to fail.
  3. Blocking: If a bypass flag is found in a git command, the hook exits with code 2 and prints an error message. Exit code 2 signals Claude Code to reject the tool call entirely.
  4. Pass-through: If no bypass flag is found, the hook exits with code 0 and the command executes normally.
  5. Limits: The hook checks text, so it stops an agent that reaches for a bypass flag out of habit. It doesn't stop an agent that sets out to evade it, e.g., by building the flag from pieces or by running git -c core.hooksPath=/dev/null commit.

Exit Codes

CodeMeaning
0Allow the tool call to proceed
1Error (tool call still proceeds, warning shown)
2Block the tool call entirely

Blocked Flags

FlagPurposeWhy Blocked
--no-verifySkips pre-commit and commit-msg hooksBypasses linting, formatting, testing, security checks
--no-gpg-signSkips GPG commit signingBypasses commit signing policy

Installation

Per-Project Setup

Create or update .claude/settings.json in your project root:

bash
mkdir -p .claudecat > .claude/settings.json << 'EOF'{  "hooks": {    "PreToolUse": [      {        "matcher": "Bash",        "hooks": [          {            "type": "command",            "command": "if grep -qE '\"command\"[[:space:]]*:[[:space:]]*\"([^\"\\\\]|\\\\.)*(--no-(ver|g)|commit([^\"\\\\]|\\\\.)*([[:space:]]|\\\\[tn])-[a-zA-Z]*n)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"          }        ]      }    ]  }}EOF

Global Setup

To enforce across all projects, add to ~/.claude/settings.json:

bash
mkdir -p ~/.claudecat > ~/.claude/settings.json << 'EOF'{  "hooks": {    "PreToolUse": [      {        "matcher": "Bash",        "hooks": [          {            "type": "command",            "command": "if grep -qE '\"command\"[[:space:]]*:[[:space:]]*\"([^\"\\\\]|\\\\.)*(--no-(ver|g)|commit([^\"\\\\]|\\\\.)*([[:space:]]|\\\\[tn])-[a-zA-Z]*n)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"          }        ]      }    ]  }}EOF

Verification

Test that the hook blocks bypass flags:

bash
# This should be blocked by the hook:git commit --no-verify -m "test"
# This should succeed normally:git commit -m "test"

Extending the Hook

Adding More Blocked Flags

To block additional flags (e.g., --force), extend the grep pattern:

json
{  "hooks": {    "PreToolUse": [      {        "matcher": "Bash",        "hooks": [          {            "type": "command",            "command": "if grep -qE '\"command\"[[:space:]]*:[[:space:]]*\"([^\"\\\\]|\\\\.)*(--no-(ver|g)|commit([^\"\\\\]|\\\\.)*([[:space:]]|\\\\[tn])-[a-zA-Z]*n|git([[:space:]]|\\\\t)([^\"\\\\]|\\\\.)*--force)'; then echo 'BLOCKED: Bypass flags are not allowed.' >&2; exit 2; fi"          }        ]      }    ]  }}

Combining with Other Hooks

The block-no-verify hook works alongside other PreToolUse hooks:

json
{  "hooks": {    "PreToolUse": [      {        "matcher": "Bash",        "hooks": [          {            "type": "command",            "command": "if grep -qE '\"command\"[[:space:]]*:[[:space:]]*\"([^\"\\\\]|\\\\.)*(--no-(ver|g)|commit([^\"\\\\]|\\\\.)*([[:space:]]|\\\\[tn])-[a-zA-Z]*n)'; then echo 'BLOCKED: Bypass flags not allowed.' >&2; exit 2; fi"          }        ]      },      {        "matcher": "Bash",        "hooks": [          {            "type": "command",            "command": "if grep -qE 'rm[[:space:]]+-rf[[:space:]]+/'; then echo 'BLOCKED: Dangerous rm command.' >&2; exit 2; fi"          }        ]      }    ]  }}

Best Practices

  1. Commit the settings file -- Add .claude/settings.json to version control so all team members benefit from the hook.
  2. Document in onboarding -- Mention the hook in your project's contributing guide so developers understand why bypass flags are blocked.
  3. Pair with pre-commit hooks -- The block-no-verify hook ensures pre-commit hooks run; make sure you have meaningful pre-commit hooks configured.
  4. Test after setup -- Verify the hook works by intentionally triggering it in a test commit.

來源與署名

來源:wshobson/agents位於plugins/block-no-verify/skills/block-no-verify-hook提交46891e7

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架