`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` を使うこと。