`permissions.deny` の `Bash(...)` ルールは**コマンド先頭のプレフィックスマッチ**でしか効かない。
```
Bash(claude -p:*) → claude -p ... 止まる
→ ssh shadow '... claude -p ...' **素通り**(先頭が ssh)
```
コマンド文字列全体を検査したいなら **PreToolUse hook が本体**になる。
## 実例(2026-07-28)
`billing-constitution.md` には以前から「`permissions.deny` で素の `claude -p` をブロック」と
書かれていたが、**実際の settings.json に該当ルールは1つも存在しなかった**。
そのためトークン計測で `ssh shadow '... claude -p ...'` を7回実行しても全て素通りした。
**教訓: ガードは「書いてある」ではなく「実際に発火する」ことを実測で確かめる。**
## 確認方法
`echo claude -p dummy` を打つ。hook が効けば deny され、効かなければ echo が走るだけで安全。
settings.json への hook 追加は**再起動不要で即時反映**された。
## 実装
`~/.claude/hooks/guard_claude_billing.py`(全ホスト配備済み・main で追跡)。
Bash/PowerShell のコマンド文字列全体を検査し、素の `claude -p` `--print` と
`ANTHROPIC_API_KEY=` を deny。同一コマンド内に `ANTHROPIC_BASE_URL=` がある 9router 経由のみ通す。
`settings.json` は .gitignore(ホスト固有)なのでリポで直接配れない。
共通部分は `settings.shared.json` + `scripts/apply-shared-settings.py` で冪等マージする。
Windows では `python3` が Microsoft Store のスタブなので `python` を使うこと。
instinct: permissions.deny は先頭マッチのみ・ssh経由は PreToolUse hook でしか止められない