block-no-verify-hook
wshobson/agents
Block AI agents from bypassing git pre-commit hooks with --no-verify and similar flags.
What is block-no-verify-hook?
Configures a PreToolUse hook that intercepts and rejects bash commands containing git bypass flags like --no-verify and --no-gpg-sign before execution. Use this when setting up Claude Code projects that enforce commit quality gates and need to prevent agents from circumventing linting, formatting, testing, or security checks.
- Inspects all Bash tool calls before execution via PreToolUse hook
- Blocks commands containing --no-verify and --no-gpg-sign flags in git operations
- Rejects tool calls with exit code 2 to prevent bypass attempts
- Allows normal git commits without bypass flags to proceed unaffected
- Works alongside other PreToolUse hooks without interference
- Supports per-project and global configuration
How to install block-no-verify-hook
npx skills add https://github.com/wshobson/agents --skill block-no-verify-hook- Project with .claude/settings.json configuration file or global ~/.claude/settings.json
- Git repository with pre-commit hooks already configured
- Claude Code or compatible AI agent tool
How to use block-no-verify-hook
- 1.Create or navigate to your project's .claude directory
- 2.Add the PreToolUse hook configuration to .claude/settings.json with the provided Bash matcher and grep command
- 3.Commit .claude/settings.json to version control so all team members use the hook
- 4.Test the hook by attempting a git commit with --no-verify flag (should be blocked)
- 5.Verify normal commits without bypass flags proceed successfully
Use cases
- Enforce pre-commit hook execution in Claude Code projects to prevent unformatted code commits
- Block agents from skipping GPG signing policies on commits
- Prevent security scanning and linting checks from being bypassed
- Ensure test suites run before code is committed to the repository
- Maintain code quality standards across team projects using AI agents
- Teams using Claude Code or other AI coding agents
- Projects with strict pre-commit hook and code quality requirements
- Organizations enforcing commit signing policies
- Development teams needing to prevent quality gate circumvention
block-no-verify-hook FAQ
Exit code 0 allows the tool call to proceed, exit code 1 shows a warning but allows execution, and exit code 2 blocks the tool call entirely. The hook uses exit code 2 to reject bypass flags.
Yes. Modify the grep regex pattern to include additional flags like --force or --force-with-lease. The pattern uses alternation (|) to match multiple flags.
No. The hook only targets Bash tool calls and specifically checks for git commands with bypass flags. Other tools and commands pass through unaffected.
Yes. Add the hook configuration to ~/.claude/settings.json to enforce it globally, or place it in .claude/settings.json for per-project enforcement.
The hook intercepts the command before execution, prints a blocking error message, and exits with code 2, which causes Claude Code to reject the tool call entirely.
Full instructions (SKILL.md)
Source of truth, from wshobson/agents.
name: block-no-verify-hook description: 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.
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:
# These commands skip pre-commit hooks entirely
git commit --no-verify -m "quick fix"
git push --no-verify
git 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:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; 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
- Matcher: The hook targets only
Bashtool calls, so it does not interfere with other tools (Read, Edit, Grep, etc.). - Inspection: The
$TOOL_INPUTenvironment variable contains the full command the agent is about to execute. The hook usesprintfto safely pass input (avoidingechopitfalls with special characters) and checks for--no-verifyor--no-gpg-signflags only when preceded by agitcommand. - 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.
- Pass-through: If no bypass flag is found, the hook exits with code 0 and the command executes normally.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Allow the tool call to proceed |
| 1 | Error (tool call still proceeds, warning shown) |
| 2 | Block the tool call entirely |
Blocked Flags
| Flag | Purpose | Why Blocked |
|---|---|---|
--no-verify | Skips pre-commit and commit-msg hooks | Bypasses linting, formatting, testing, security checks |
--no-gpg-sign | Skips GPG commit signing | Bypasses commit signing policy |
Installation
Per-Project Setup
Create or update .claude/settings.json in your project root:
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; 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:
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; 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:
# 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:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign|force-with-lease|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:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: Bypass flags not allowed.' >&2; exit 2; fi"
}
},
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE 'rm\\s+-rf\\s+/'; then echo 'BLOCKED: Dangerous rm command.' >&2; exit 2; fi"
}
}
]
}
}
Best Practices
- Commit the settings file -- Add
.claude/settings.jsonto version control so all team members benefit from the hook. - Document in onboarding -- Mention the hook in your project's contributing guide so developers understand why bypass flags are blocked.
- Pair with pre-commit hooks -- The block-no-verify hook ensures pre-commit hooks run; make sure you have meaningful pre-commit hooks configured.
- Test after setup -- Verify the hook works by intentionally triggering it in a test commit.
Related skills
More from wshobson/agents and the wider catalog.

tailwind-design-system
Build production-ready design systems with Tailwind CSS v4, design tokens, and component libraries.

typescript-advanced-types
Master TypeScript's advanced type system: generics, conditional types, mapped types, and utility types for type-safe applications.

nodejs-backend-patterns
Build production-ready Node.js backends with Express/Fastify, middleware patterns, auth, and database integration.

python-performance-optimization
Profile and optimize Python code using cProfile, memory profilers, and performance best practices.

brand-landingpage
Brand-first landing page designer with guided interviews and Stitch-powered iteration.

python-testing-patterns
Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development.