Back to list
CLAUDE.md の規則が適用されていません。実際に機能するのはこちらです。
Your CLAUDE.md Rules Aren't Being Enforced. Here's What Actually Works.
Translated: 2026/3/21 4:01:47
Japanese Translation
GitHub のユーザーが、明確に書かれた CLAUDE.md に記述されたコスト制限を無視され、2 日間で約 30 ドルを支払いました。「バッチ操作には安価なモデルを使用してください」というルールは存在しましたが、Claude はそのルールを読み取り、対話において確認しました。しかし、コードレビューを行ったにもかかわらず、774 回の Sonnet API 呼び出しがフル価格で実行されるコードがリリースされてしまいました。このコードレビューエージェントもこれを警告しません。
これはバグではありません。カテゴリ的な誤りです。
CLAUDE.md のルールはシステムプロンプトの一部です。Claude はそれを読み取り、遵守しようとし、主にそれを行います。ただし、例外はあります。失敗モードは「Claude が CLAUDE.md を読み取らない」ことではありません。以下にあり得ます。
- 長会話を起こすことにより、初期の文脈が薄れ、最新のタスクの文脈が支配的になる
- 複雑な複数ステップの操作において、即座のサブタスクの遂行が背景のルールを凌駕する
- 構造と正しかつ、ポリシー文書とのクロス参照を行わないコードレビューエージェント
このように考えましょう:CLAUDE.md は会社の手引きに相当し、Hook はドアロックに相当します。手引きは「許可なくサーバールームに侵入しない」と言います。そして、ロックは実際にそれを防止します。
Claude Code の Hook は実行ライフサイクルの特定の時点においてシェルスクリプトを実行します。これらは、Claude が行うことを検査し、ゼロでない終了コードを返してそれをブロックできます。
主要な違いは以下の通りです:
| CLAUDE.md | Hook |
| :--- | :--- |
| Claude が「記憶」する場合 | Claude が「記憶」する場合 |
| 全ての回 | 全ての回 |
| 適用範囲 | 適用範囲 |
| Soft Enforcement (Claude が判断) | Hard Enforcement (スクリプトが判断) |
| 長会話を生存する | 衰える |
| 常にアクティブ |
| コードレビューを生存する | エージェントがそれを外す可能性あり |
| N/A (防止するだけでレビューしない) |
#!/bin/bash
# Edit と Write 用の PreToolUse Hook
CONTENT=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.new_string // .content // ""')
if echo "$CONTENT" | grep -qiE '(claude-sonnet\|claude-opus\|gpt-4-turbo)' && \
echo "$CONTENT" | grep -qiE '(for .* in\|while\|batch\|bulk\|\[[0-9]+)/'; then
echo "COST GUARD: Expensive model detected in bulk operation." >&2
echo "Rule: Use haiku/gpt-4o-mini for bulk. See CLAUDE.md." >&2
exit 1
fi
#!/bin/bash
# Bash 用の PreToolUse Hook
CMD=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // ""')
if echo "$CMD" | grep -q "community_detection\|pipeline\|batch_process" && \
! echo "$CMD" | grep -q "\-\-dry-run"; then
echo "BLOCKED: Production scripts must run with --dry-run first." >&2
exit 1
fi
#!/bin/bash
# Bash 用の PostToolUse Hook
OUTPUT=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // ""')
# API 呼び出しの追跡を行うカウンターファイル
COUNTER_FILE="/tmp/cc-api-call-counter"
COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
if echo "$OUTPUT" | grep -qiE 'sonnet\|opus\|gpt-4'; then
COUNT=$((COUNT + 1))
echo "$COUNT" > "$COUNTER_FILE"
if [ "$COUNT" -gt 50 ]; then
echo "WARNING: $COUNT expensive API calls this session." >&2
echo "Review costs before continuing." >&2
fi
fi
正しいアプローチは「Hook から CLAUDE.md への置き換え」ではありません。両方を併用することです:
- CLAUDE.md は何を、なぜ望んでいるかを描画し、Claude は不確実な状況での意思決定のためにこれを使います。
- Hook はハードリミックスを強制し、文脈に関わらず決して違反されるべきルールです。
真の后果(コスト超過、データ削除、プロダクションプッシュ、認証情報漏洩)があるものは何でも、Hook が強制層です。CLAUDE.md だけでは不十分です。
上記の Hook は claude-code-hooks からおり、140 時間以上の自律的な Claude Code 操作から抽出された 12 つのプロダクション用 Hook のコレクションです。
どの Hook も何かが失敗したことで存在します。コストガードはバッチ操作に高価なモデルを実行したことがありました。ブランチガードはメインにプッシュしたことがありました。エラーゲートは未解決のエラーを持つコードを公開したことがありました。
これらの Hook は Claude Code Ops Kit ($19) の一部です。これは 12 つの Hook + 6 つのテンプレート + 3 つのツールで、15 分で事前に設定され、プロダクションに準備されています。
Original Content
A user on GitHub spent ~$30 over two days because Claude Code ignored a cost rule written clearly in their CLAUDE.md.
The rule said "use cheap models for bulk operations." Claude read the rule, acknowledged it in conversation, ran a code review — and still shipped code that made 774 Sonnet API calls at full price. The code review agent didn't flag it either.
This isn't a bug. It's a category error.
CLAUDE.md rules are part of the system prompt. Claude reads them, intends to follow them, and mostly does — until it doesn't. The failure mode isn't "Claude refuses to read CLAUDE.md." It's:
Long sessions where early context fades and recent task context dominates
Complex multi-step operations where following the immediate subtask overrides background rules
Code review agents that check structure and correctness, not cross-reference against policy documents
Think of it this way: CLAUDE.md is like a company handbook. Hooks are like door locks. The handbook says "don't enter the server room without authorization." The lock actually prevents it.
Claude Code hooks run shell scripts at specific points in the execution lifecycle. They can inspect what Claude is about to do and block it by returning a non-zero exit code.
Here's the key difference:
CLAUDE.md
Hook
When it applies
When Claude "remembers"
Every single time
Enforcement
Soft (Claude decides)
Hard (script decides)
Survives long sessions
Degrades
Always active
Survives code review
Agent may miss it
N/A (prevents, doesn't review)
#!/bin/bash
# PreToolUse hook for Edit and Write
CONTENT=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.new_string // .content // ""')
if echo "$CONTENT" | grep -qiE '(claude-sonnet|claude-opus|gpt-4-turbo)' && \
echo "$CONTENT" | grep -qiE '(for .* in|while|batch|bulk|\[[0-9]+/)'; then
echo "COST GUARD: Expensive model detected in bulk operation." >&2
echo "Rule: Use haiku/gpt-4o-mini for bulk. See CLAUDE.md." >&2
exit 1
fi
#!/bin/bash
# PreToolUse hook for Bash
CMD=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // ""')
if echo "$CMD" | grep -q "community_detection\|pipeline\|batch_process" && \
! echo "$CMD" | grep -q "\-\-dry-run"; then
echo "BLOCKED: Production scripts must run with --dry-run first." >&2
exit 1
fi
#!/bin/bash
# PostToolUse hook for Bash
OUTPUT=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // ""')
# Track API calls in a counter file
COUNTER_FILE="/tmp/cc-api-call-counter"
COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
if echo "$OUTPUT" | grep -qiE 'sonnet|opus|gpt-4'; then
COUNT=$((COUNT + 1))
echo "$COUNT" > "$COUNTER_FILE"
if [ "$COUNT" -gt 50 ]; then
echo "WARNING: $COUNT expensive API calls this session." >&2
echo "Review costs before continuing." >&2
fi
fi
The right approach isn't "hooks instead of CLAUDE.md." It's both:
CLAUDE.md describes what you want and why — Claude uses this for decision-making in ambiguous situations
Hooks enforce hard constraints — the rules that must never be violated regardless of context
For anything with real consequences — cost overruns, data deletion, production pushes, credential exposure — hooks are the enforcement layer. CLAUDE.md alone isn't sufficient.
The hooks above are from claude-code-hooks, a collection of 12 production hooks extracted from 140+ hours of autonomous Claude Code operation.
Every hook exists because something went wrong without it. The cost guard exists because we ran expensive models on bulk operations. The branch guard exists because we pushed to main. The error gate exists because we published code with unresolved errors.
These hooks are part of the Claude Code Ops Kit ($19) — 12 hooks + 6 templates + 3 tools, pre-configured and production-ready in 15 minutes.