Pre-commit scanner that detects strings in your repository that could trigger hidden AI routing, extra billing, or data exposure — before they reach a server.
Includes ClawRoute Inspector — a PR and pre-commit report that scans commit messages, branch names, AI instruction files, README text, docs, and dependency manifests for terms that may cause coding assistants to refuse work, burn quota, or route to more expensive paths.
Inspired by two real-world incidents:
- The HERMES.md incident, where the string
HERMES.mdin a git commit message caused Claude Code to silently route API requests to "extra usage" billing, burning $200+ in credits. - The OpenClaw incident, where commits containing the competitor name
OpenClawcaused Claude Code to refuse requests or route to extra usage billing — just two days after HERMES.md.
pip install -e .
billguard check # scan staged changes and recent commits
billguard clawroute # PR report: scan for refusal/routing/billing risks
billguard install # add pre-commit + commit-msg hooksbillguard check # pre-commit: staged changes + last 5 commits
billguard check --message "text" # scan a specific message
billguard check --json # JSON output for CI
billguard report # full scan: all files, history, agent logs, blame
billguard report --json
billguard clawroute # PR report: branches, README, docs, deps (Markdown table)
billguard clawroute --json # JSON output
billguard clawroute --output report.md # write report to file
billguard install # install git hooks (pre-commit + commit-msg)
billguard install --force # overwrite existing hooks
billguard init # generate .billguard.yml template
billguard rules # list all active rules
Skip any check by setting the environment variable:
BILLGUARD_SKIP=1 git commit -m "message"billguard clawroute produces a Markdown table report designed to be posted as a PR comment. It scans for terms that may trigger coding-assistant refusal, policy routing, quota burn, or client-data exposure.
Basic PR report (stdout):
billguard clawrouteWrite to file for CI integration:
billguard clawroute --output clawroute-report.mdJSON output for programmatic use:
billguard clawroute --json## ClawRoute Inspector Report
> **Mode:** `clawroute` | **Findings:** 0 CRITICAL, 2 ERROR, 5 WARN
### [BLOCKED] Action Required
Blocking issues found. These may cause coding assistants to **refuse work**,
**burn quota**, or **route to extra billing**. Resolve before merging.
| # | Risky Text | File Path | Tool Affected | Consequence | Safer Rewrite | Owner |
|---|------------|-----------|---------------|-------------|---------------|-------|
| 1 | [ERR] `extra billing` | `README.md` | Claude Code / Copilot | Routing Change / Refusal | Remove billing/routing control language... | alice |
| 2 | [WARN] `OpenClaw` | `docs/design.md` | Claude Code | Refusal / Extra Billing | Remove 'OpenClaw' reference. Use... | bob |
| 3 | [WARN] `@anthropic-ai/sdk` | `package.json` | Claude Code / Cursor | Refusal / Routing Change | Check if this dependency triggers... | — || Target | Examples |
|---|---|
| Commit messages | Full history (billguard report mode) |
| Branch names | Current branch via git rev-parse --abbrev-ref HEAD |
| AI instruction files | CLAUDE.md, .cursorrules, AGENTS.md, .windsurfrules, etc. |
| README files | README.md, README, README.rst, README.txt |
| Documentation | docs/**/*.md, doc/**/*.md, all *.md files |
| Dependency manifests | package.json, requirements.txt, pyproject.toml, Cargo.toml, go.mod, Gemfile, Pipfile, composer.json, pom.xml, etc. |
| Config files | .env, .yml, .json, .toml, .ini |
| Level | Behavior | Example |
|---|---|---|
| CRITICAL | Blocks commit | HERMES.md routing trigger, API key in logs |
| ERROR | Blocks commit | Anti-abuse trigger phrases, routing directives |
| WARN | Warns only | Model downgrade triggers, competitor names, subagent patterns |
CRITICAL and ERROR findings cause exit code 1. WARN findings display but pass.
| ID | Rule | Scans |
|---|---|---|
| BG001 | HERMES.md in commit messages |
commits |
| BG002 | HERMES.md in instruction/config |
instruction, config, logs |
| BG003 | Anthropic API key (sk-ant-api03-...) |
logs, instruction, config |
| BG004 | OpenAI API key (sk-...) |
logs, instruction, config |
| BG005 | GitHub PAT (ghp_...) |
logs, instruction, config |
| BG006 | AWS/GCP credentials (AKIA..., AIza...) |
logs, instruction, config |
| ID | Rule | Scans |
|---|---|---|
| BG101 | Anti-abuse trigger: hermes-agent |
commits, instruction, config |
| BG102 | Billing routing override phrases | instruction, config |
| BG103 | Agent identity env var manipulation | config |
| BG104 | AI instruction filenames in commits | commits |
| BG105 | SSRF-like model routing directives | instruction, config |
| ID | Rule | Scans | Tool Affected |
|---|---|---|---|
| BG301 | Competitor name: OpenClaw |
commits, instruction, config | Claude Code |
| BG302 | Competitor assistant names (Cursor AI, Copilot, Codeium, etc.) | commits, instruction, config | Claude Code / Cursor / Copilot |
| BG303 | Branch name with competitor reference | commits | Claude Code / Cursor |
| BG304 | Model-routing override in instruction file | instruction, config | Claude Code / Copilot / Cursor |
| BG305 | Refusal-trigger keywords (jailbreak, bypass, guardrail) | commits, instruction, config | Claude Code / Copilot |
| BG306 | README competitor comparison language | instruction, config | Claude Code / Cursor / Copilot |
| BG307 | Competitor AI SDK in dependency manifest | config | Claude Code / Copilot / Cursor |
| BG308 | Agent instruction filename in non-instruction file | instruction, config | Claude Code / Cursor / Copilot / Cody |
| BG309 | AI agent detection variable in docs | instruction, config | Claude Code / Copilot |
| BG310 | Quota-bypass language in content | commits, instruction, config | Claude Code |
| BG311 | AI agent benchmark comparison in docs | instruction, config | Claude Code / Cursor / Copilot |
| BG312 | API key in documentation (data exposure) | instruction, config | Claude Code / Cursor / Copilot |
| ID | Rule | Scans |
|---|---|---|
| BG201 | Model routing downgrade triggers | instruction, config, logs |
| BG202 | Subagent trigger patterns | instruction, config |
| BG203 | Agent detection strings | instruction, config |
| BG204 | MCP config with sensitive routing | config |
- Commit messages — staged commit + recent history (last 5 for
check, up to 100 forreport) - AI instruction files —
CLAUDE.md,AGENTS.md,HERMES.md,.cursorrules,.cursor/rules/*,.github/copilot-instructions.md,.windsurfrules,.claude/* - Branch names — current branch (clawroute mode)
- README & docs —
README.md,docs/**, all*.mdfiles (clawroute mode) - Dependency manifests —
package.json,requirements.txt,pyproject.toml,Cargo.toml,go.mod, etc. (clawroute mode) - Config files —
.env,.yml,.yaml,.json,.toml,.ini, etc. - Agent logs — Claude Code (
~/.claude/projects/), Cursor, GitHub Copilot, Cody (report mode only)
- name: BillGuard ClawRoute Inspector
run: |
pip install -e .
billguard clawroute --output clawroute-report.md
- name: Post PR comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('clawroute-report.md', 'utf8');
github.rest.issues.createComment({
...context.repo,
issue_number: context.issue.number,
body: report,
});billguard install adds hooks to .git/hooks/:
billguard install # repo-local hooks
billguard install --force # overwrite existing hooksCreate .billguard.yml in your repo root:
version: 1
# Custom rules extend built-in detection
rules:
- id: "CUSTOM001"
name: "My custom rule"
severity: "ERROR"
pattern: "dangerous-string"
targets: [commits, instruction]
suggestion: "Remove the dangerous string"
description: "Why this is risky"
tool_affected: "Claude Code"
consequence: "Refusal"
# Enable/disable scanners
scanners:
commits: true
instruction: true
config: true
logs: true
# Additional AI instruction files
instruction_files:
- "docs/ai-prompts.md"
# Exclude patterns
exclude:
- "node_modules/**"
- "vendor/**"
- ".git/**"
# Minimum severity to report
min_severity: "WARN"
# Git blame
blame:
enabled: true
max_commits: 100
# Agent log path overrides (empty = auto-discovery)
agent_logs:
claude_code: ""
cursor: ""
copilot: ""
cody: ""billguard check targets sub-1-second execution:
- No network calls
- Only scans last 5 commits + staged message
- Skips agent log scanning and git blame
- All regex patterns compiled at load time
- Files larger than 1 MB are skipped
billguard clawroute performs a comprehensive scan including all markdown files, dependency manifests, and git blame. It is designed for PR CI pipelines and runs in a few seconds.
billguard report performs a full scan including agent logs and git blame. It will be slower by design.
In April 2026, a GitHub issue revealed that the exact, case-sensitive string HERMES.md in git commit messages caused Claude Code to route API requests to "extra usage" billing instead of plan quota. The user's Max plan had 87% of quota remaining, yet $200.98 in extra usage credits was consumed.
Two days later, the HN thread #47963204 exposed that commits containing OpenClaw — a competitor product name — caused similar refusal and billing routing behavior, generating 707 comments.
The root cause across both incidents: AI coding assistants inject git history and repo content into their context, and server-side rules parse this user-controlled content to make routing, billing, and behavioral decisions — a class of vulnerability known as PROMISQROUTE.
BillGuard exists to catch these patterns before they leave your machine.
- Python >= 3.11
- Git
MIT