auto modeでCLAUDE.mdとhooksが無視される問題と回避策
Auto modeのBash優先指示により、ネストしたCLAUDE.mdと.claude/rulesがReadツール以外では読み込まれない仕組みを、GitHub issueの実測データから確認します。
Auto modeが有効なセッションでは、ファイル操作をBashツール経由で行うよう誘導する指示がシステムプロンプトに追加されます。この指示に従うと、サブディレクトリのCLAUDE.mdや.claude/rulesのパス限定ルールは、Readツールでしか読み込まれないという既存の仕様と正面から衝突します。GitHub issue #90450は2026年8月28日に報告され、27通りのアクセス方法とパス限定ルールの実測、サブエージェントへの継承、実運用での発生頻度が積み上がっています。2026年9月25日の最新コメント以降、解決を報告する投稿はありません。
Auto modeがネストしたCLAUDE.mdと.claude/rulesを読み込ませなくする仕組み
CLAUDE_CODE_THRIFTY_SONICという環境変数の値やバージョン別の挙動は、CLAUDE_CODE_THRIFTY_SONICとはで扱っています。本記事はこの指示が具体的にどの読み込み経路を止めているかを、ネストしたCLAUDE.mdとパス限定ルールに絞って検証します。auto mode自体を選択肢から消す設定は別物です。詳しくはClaude CodeのdisableAutoMode設定にまとめています。
issueの本文には、ライブセッションから抜き出したという指示文が逐語で引用されています。
Do your work through the Bash tool wherever it can accomplish the job: read files with
cat,head, orsed -n, search withgrepandfind, and make file changes withsed, heredocs, or short scripts, rather than using the dedicated Read, Edit, or Write tools. Fall back to a dedicated tool only when Bash genuinely cannot do the job.
公式ドキュメントのCLAUDE.mdは、サブディレクトリのファイルについて「Claudeがそのディレクトリのファイルを読んだときに読み込まれる」とだけ説明しています。ツールの種類は問わない書き方です。ところがissueの計測では、この「読む」を満たすのはReadツールだけでした。auto-mode-configのドキュメントも「分類器はClaude自身が読み込むのと同じCLAUDE.mdの内容を読む」と書くだけで、Bash優先の指示そのものには触れていません。どちらのページにも「auto mode」という語は登場せず、この衝突を予告する記述はありません。
27通りのアクセス方法を検証した結果 — Readツールだけが読み込む
issueの報告者は、一意のセンチネル文字列を仕込んだCLAUDE.mdを使い、27通りのアクセス方法をそれぞれ独立したディレクトリで検証しています。
| 分類 | 検証数 | 結果 |
|---|---|---|
Readツール(絶対パス・相対パス・2階層下・存在しないファイル) | 検証数4 | 結果読み込む(唯一のトリガー) |
Readツール(同一ディレクトリの2つ目のファイル) | 検証数1 | 結果読み込まない(ディレクトリ単位でセッション中1回のみ) |
ネイティブツール(Grep・Glob・Write・Edit) | 検証数4 | 結果読み込まない |
POSIXシェル(cat・head・sed -n・grep -n・find・sed -i・heredoc・tail・awk・python・ls -la) | 検証数11 | 結果読み込まない |
PowerShell(Get-Content系・Select-String・Get-ChildItem・Set-Content・[IO.File]::ReadAllText) | 検証数6 | 結果読み込まない |
cmd.exeのtype | 検証数1 | 結果読み込まない |
Auto modeの指示が名指しするcat・head・sed -n・grep・find・sed・heredocの7つの動詞は、すべてPOSIXシェルの行に含まれています。指示に忠実に従うほど、ネストしたCLAUDE.mdから遠ざかる構造です。
存在しないファイルへのRead呼び出しでも、ディレクトリのCLAUDE.mdは読み込まれたと報告されています。エラーは返しつつメモリは注入される挙動です。トリガーが実際の内容ではなく、Readツールのfile_path引数を解決した事実そのものだと確かめる根拠になっています。Grepツールがファイルの中身を返しながら何も注入しなかった結果も、内容がコンテキストに届くことがトリガーではないという反証です。
パス限定ルール(.claude/rules)への影響とその範囲
.claude/rulesのパス限定ルールでも同じ検証が行われています。こちらは4パターンとも、陰性を確認したあとにReadで発火させ、ルールが生きていることを確かめる手順です。
paths:スコープ | 陰性側の確認方法 | Read後の結果 |
|---|---|---|
.claude/agents/** | 陰性側の確認方法PowerShellのGet-Content | Read後の結果3ルールが読み込まれた |
.claude/skills/** | 陰性側の確認方法Grepツール | Read後の結果1ルールが読み込まれた |
.claude/rules/** | 陰性側の確認方法Bashのawk(全10ルールファイル) | Read後の結果2ルールが読み込まれた |
plugins/** | 陰性側の確認方法Bashのhead -5 | Read後の結果3ルールが読み込まれた |
パス限定ルールは、公式ドキュメントが「CLAUDE.mdが肥大化したときの対策」として案内している仕組みです。その対策自体がAuto modeの下では効かなくなる点は、影響の大きさを見るうえで無視できません。ルールはルールごとにセッション中1回だけ読み込まれる仕様です。早い段階でReadによって一度発火したルールは、後から対象ファイルに触れても再度は主張されません。
この読み込みの失敗は、セッションの作業ディレクトリの内側に限られます。作業ディレクトリの外に置いたファイルでは、Read・Bashのどちらでアクセスしてもメモリは注入されなかったという追試結果があります。共有ルールを1階層上に置く運用では、この境界を踏まえておく必要があります。
なお、EditやWriteに絞ったPreToolUse・PostToolUseフックのマッチャーが発火しなくなる副作用もあります。こちらはBash経由の編集そのものが原因の別系統の問題で、前述のCLAUDE_CODE_THRIFTY_SONICの記事で扱われています。
モデル別の割り当てとサブエージェントへの継承
Bash優先の指示が付くかどうかは、セッションごとに1回だけ決まる割り当てです。トップレベルのセッションが使っているモデルに左右されます。
| トップレベルセッションのモデル | 割り当て |
|---|---|
| Fable 5.1 | 割り当てforced(常に付く) |
| Opus 5 | 割り当てcohort(A/Bテストの割り当て次第) |
| それ以外のモデル | 割り当てnone(付かない) |
この割り当てで見落とされやすいのは、サブエージェントが親セッションの割り当てをそのまま引き継ぐ点です。CLAUDE_CODE_SUBAGENT_MODELでサブエージェントだけclaude-sonnet-5に切り替えても効果はありません。親セッションがforced割り当てのモデルであれば、そのサブエージェントもBash優先の指示を受け取ります。レビュー役・計画役・実装役をサブエージェントに分けるマルチエージェント構成では影響が大きくなります。親が割り当て対象なら全員が同時にこの影響を受けるうえ、親は各サブエージェントの要約しか見ないため、気づく手段がさらに乏しくなります。
回避策として環境変数を使う場合は、ユーザースコープの~/.claude/settings.jsonに置くと、サブエージェントにも同じ設定が引き継がれます。
実際の編集作業でどれだけ起きているか
ここまでは意図的な再現実験でしたが、issueには実運用データも投稿されています。対象はGo製バックエンドとTypeScript/Vue製フロントエンドを持つ本番モノレポです。.claude/rulesに9本のパス限定ルールを運用した約3か月分、Claude Code 2.1.231〜2.1.282のセッションが対象になっています。ファイルへのEdit・Writeごとに、対応するルールが事前に読み込まれていたかを突き合わせた集計です。対象セッションは主にbypassPermissionsモードで、一部はautoモードです。Bash優先の指示は両方のモードに現れるため、Auto modeに限った現象ではないとも報告されています。
| 変更の種類 | 対象件数 | マッチするルールが1つも読み込まれていなかった件数 |
|---|---|---|
Edit | 対象件数608件 | マッチするルールが1つも読み込まれていなかった件数407件(67%) |
Write | 対象件数152件 | マッチするルールが1つも読み込まれていなかった件数119件(78%) |
| トランスクリプトごとの最初の変更 | 対象件数375件 | マッチするルールが1つも読み込まれていなかった件数293件(78%) |
ルールが漏れていた変更を、対象ファイルをどう見ていたかで内訳を取ると、漏れの原因はほぼ一つに絞れます。
| 見た方法 | Editでの件数(407件中) | Writeでの件数(119件中) |
|---|---|---|
Bash(cat・sed -n・grepなど)のみ | Editでの件数(407件中)391件 | Writeでの件数(119件中)26件 |
| 一度も見ていない(新規作成など) | Editでの件数(407件中)4件 | Writeでの件数(119件中)92件 |
| 自分で書いたことがあるだけ | Editでの件数(407件中)12件 | Writeでの件数(119件中)1件 |
Readツール | Editでの件数(407件中)0件 | Writeでの件数(119件中)0件 |
Readツールで読んだあとにルールが漏れていた変更は0件でした。ルール別の漏れ率は41%から81%まで幅があり、あるGo向けテストルールでは81%に達しています。この数字をもとに、ReadだけでなくEdit・Writeの対象パスにもpaths:条件を評価する変更案が、別issue(#38487)で提案されています。この実測データでは、その変更だけで漏れの526件すべてをカバーできたはずだとされています。
CLAUDE_CODE_THRIFTY_SONIC=falseは何を止め、何を止めないか
CLAUDE_CODE_THRIFTY_SONICをfalseに設定すると、Bash優先の指示自体が挿入されなくなります。この動作は複数の利用者によって独立に確認されています。macOS・Windows双方で再現し、settings.jsonのenvに書く方法が使われています。
{
"env": {
"CLAUDE_CODE_THRIFTY_SONIC": "false"
}
}この環境変数は公式の環境変数リファレンスには掲載されておらず、issueのコメントで見つかったものです。検証は推測ではありません。セッションのトランスクリプト(~/.claude/projects/**/<session-id>.jsonl)に記録される、auto_modeという種類の添付データを直接読む方法で行われています。なおCLAUDE_CODE_THRIFTY_SONICとはで扱っている別のissueでは、値を"0"にする方法が確認されています。受け付ける文字列は複数ある可能性があるため、どちらの値を使った場合でも、設定後は同じ方法でトランスクリプトを確認しておくと安全です。
grep -o '"type":"auto_mode"[^}]*}' ~/.claude/projects/*/*.jsonl | tail -1この添付データにはbashFirstという真偽値とbashFirstSteerという強度の値が入っています。環境変数を設定していないセッションではbashFirst":trueが記録され、CLAUDE_CODE_THRIFTY_SONIC=falseのセッションでは添付データ自体が現れないと報告されています。もう一つの未文書化の変数にCLAUDE_CODE_COZY_TEAPOTがあり、strict(既定)とrelaxedを切り替えられます。ただしrelaxedは指示の言い回しを和らげるだけで、catやsed -nへ誘導する動詞自体は変わりません。衝突を解消するのはCLAUDE_CODE_THRIFTY_SONICだけだと結論づけられています。似た名前の公式変数にCLAUDE_CODE_AUTO_MODE_SERVERがありますが、こちらはサーバー側レビューを止めるための、まったく別の公式設定です。
環境変数の扱いにはもう一つ注意点があります。CLAUDE_CODE_THRIFTY_SONICは値が設定されているかどうかで判定されるため、明示的なfalseが意味を持ちます。一方で似た仕組みの姉妹変数の一部は、値の真偽だけを見て判定されます。falseを渡しても偽と評価されて既定値に落ちるとも指摘されており、同じ書き方がどの変数にも通用するとは限りません。
InstructionsLoadedフックで検知する
CLAUDE_CODE_THRIFTY_SONICは根本原因を止める設定です。ただし「実際にどのルールが読み込まれ、どれが漏れたか」を確認する手段は別に必要です。公式のhooksドキュメントには、CLAUDE.mdや.claude/rulesが読み込まれるたびに発火するInstructionsLoadedイベントが用意されています。load_reasonがsession_start・path_glob_match・nested_traversal・include・compactのいずれかを識別できます。matcherにはこの値を使い、遅延読み込みだけを対象にすることもできます。
{
"hooks": {
"InstructionsLoaded": [
{
"matcher": "path_glob_match|nested_traversal",
"hooks": [
{ "type": "command", "command": "python3 ~/.claude/hooks/log-loaded.py" }
]
}
]
}
}このイベント自体は決定や遮断を持たず、観測専用です。hooksでテストを自動実行するで扱っているような他のフックと組み合わせれば活用の幅が広がります。「ネストしたCLAUDE.mdがあるのに、一度もnested_traversalが記録されないままセッションが終わった」ことを、ログから発見できるようになります。
issueのコメントには、PreToolUseフックにはadditionalContextが使えないため、漏れたルールをフック側から差し戻すことはできないという説明もありました。ただし公式のhooksドキュメントを直接確認すると、PreToolUseはadditionalContextを返せるイベントの一つとして明記されています。この機能自体は2026年1月のバージョンで追加され、4月には「ツール呼び出しが失敗したときに値が消える」という別の不具合が修正された記録も残っています。ここは筆者自身の実装検証ではありません。ただ公式の記載を素直に読む限り、ネストしたCLAUDE.mdの内容をPreToolUseフックがadditionalContextとして差し戻す設計は、成立しそうに見えます。
まとめ
Auto modeのBash優先指示は、ネストしたCLAUDE.mdとパス限定ルールがReadツールでしか読み込まれないという既存仕様と正面から衝突します。issue #90450は未解決のまま、複数の実測データが積み上がっている状態です。安全に関わるルールを入れ子のCLAUDE.mdに置いている場合は対策が要ります。CLAUDE_CODE_THRIFTY_SONIC=falseをユーザースコープの設定に加えるか、そのルールを一度ルート直下のCLAUDE.mdに移すことを検討する価値があります。InstructionsLoadedフックでログを取っておけば、実際にどのルールが読み込まれずに終わったセッションかを後から確認できます。
関連する記事
Claude Code をもっと見る →Claude Code(クロードコード)とは — できること・料金・使い方・CLIから8つの拡張機構まで
Claude Codeベストプラクティス — Anthropicが示す自走エージェントの設計原則と運用パターン
Claude CodeとKiroを比較 — 仕様駆動開発の思想差とCLI/IDE使い分け
Agent SDK settingSources — Claude Codeの機能をどこまで制御できるか
Claude Code SkillsとMCPの違い — サブエージェント・hooksを含む4機構の使い分け
Claude Code設定ガイド — settings.jsonの主要フィールド・環境変数・実戦レシピ