Claude Code は兄弟リポジトリのCLAUDE.mdを読んでいなかった——横断ワークスペース運用の実測18件
はじめに
複数のプロジェクトを1つのAIアシスタントで横断して作業している。起動したディレクトリだけでなく、他のプロジェクトのディレクトリも「追加の作業ディレクトリ」として登録してあり、どこから起動していても、登録済みのどのプロジェクトでも読み書きできる。この運用そのものは事前に方針として確定しており、揺らいでいない。
問題は別のところにあった。各プロジェクトには、そのプロジェクト固有の注意事項を書いたルールファイルがある。「必要なときに自動で読み込まれる」はずのこのファイルが、起動元と違うプロジェクトで作業しているとき、実際には一度も読み込まれていなかった。 この記事は、その空白を観測ログから機械的に確定させた記録になる。
公式の条件節——「サブディレクトリ」の範囲はどこまでか
このルールファイルの自動読み込みには、公式ドキュメントに次の条件が明記されていた。
“Files in subdirectories load on demand when Claude reads files in those directories”
“in subdirectories under your current working directory”
「必要なときに自動で読み込まれる」対象は、今の起動ディレクトリの配下にあるサブディレクトリに限定されている。追加の作業ディレクトリとして登録した、起動元とは別の場所にあるプロジェクト(兄弟プロジェクト)は、この条件に当てはまらない。
実測——18件のログをすべて機械集計する
思い込みで判断せず、実際に読み込まれたファイルを観測ログから集計した。対象は7つの作業セッション、ファイル読み込みのイベント合計18件。
実際にロードされた設定ファイルの種類(観測ログ 18件・7セッション)
すべてのプロジェクトに共通するルールファイル … 18件
起動元プロジェクトの固有ルールファイル … 18件(内数)
兄弟プロジェクトの固有ルールファイル … 0件
同じセッションの中で、兄弟プロジェクト側のファイルを6本以上編集し、作業対象のディレクトリも一時的にそちらへ移していた。それでも兄弟プロジェクトの固有ルールファイルは0件だった。ログを記録する仕組み自体は正常に動いていたので、「記録が漏れていた」ではなく「そもそも読み込まれていなかった」と確定できる。
横断ワークスペース(縦=1セッションの進行・横=どちらのプロジェクトを触るか・入れ子=そのとき何が読まれたか)
セッション開始(AIアシスタントは1つ、対象プロジェクトは複数)
│
├─▶ 起動ディレクトリ = プロジェクトA
│ ├─ 全プロジェクト共通のルール ──── 読み込まれる(実測 18/18)
│ └─ Aの固有ルール ───────────── 読み込まれる(実測 18/18)
│ └─ 「触る前にポート番号と識別クエリで照合する」が効いている
│ │
├─▶ 追加の作業ディレクトリ = プロジェクトB(兄弟) │
│ │ DBの論理名はAと同じ。違うのはポート番号だけ │
│ ├─ 全プロジェクト共通のルール ──── 読み込まれる │
│ └─ Bの固有ルール ───────────── 読み込まれない(実測 0/18)│
│ │ ※ 同一セッション内でBのファイルを6本以上編集し、 │
│ │ 作業対象のディレクトリも一時的にB側へ移した後 │
│ └─ 同じ照合手順が、B側では効いていない │
│ │ │
▼ ▼ ▼
どちらの枝から来ても、行き着く先は「同じ論理名のDBへの操作」 ◀────────┘
│ (A側の安心が、B側の判断に流用される)
│
└─▶ 観測ログ18件を機械集計 ── 「読まれていない」を確定
│
└──(戻りエッジ)──▶ 起点に戻り、「必要なとき」の範囲を読み直す
└─ 公式の条件節=起動ディレクトリ配下に限る
空白の場所に、何が書かれていたか
これが単なる仕様の細部で済まなかった理由がある。2つの独立したシステムのデータベースが、どちらも同じ論理名を持ち、ポート番号だけが違うという構成になっていた。両方の固有ルールファイルには、「データベースを操作する前に、ポート番号と識別クエリで接続先を照合してから触る」という、まさにこの取り違えを防ぐための手順が書かれていた。
この手順は、そもそも実際に取り違えかけた事故のあとに、その再発防止として書き足したものだ。記録を辿ると、両プロジェクトの固有ルールファイルはどちらも事故と同じ日に新設されている。つまりこの2ファイルは「危険を知っていて置いた対策」だった。
ところが、その対策が書かれたファイル自体が、兄弟プロジェクト側で作業しているときには読み込まれない。書いた対策が、最も必要な場面では読まれない構造になっていた——これが、18件の観測で後から分かったことだった。
⚠️ 順序を正確に書いておくと、事故が起きたのは対策を書く前で、読み込みの空白を観測したのはその約1か月後になる。「ルールは書いてあったのに読まれず、そのせいで事故った」という因果は成立しない。 言えるのは「事故のあとに置いた対策が、同じ場面で効かない形になっていた」までだ。事実としては、こちらの方が厄介だと考えている——対策を書いた側は、書いた時点で安心してしまうからだ。
塞ぐ手立て——3つの候補
公式ドキュメントを読み進めると、この空白を塞ぐ候補が3つ見つかった。
| 候補 | 中身 |
|---|---|
| 専用の環境変数 | 追加の作業ディレクトリのルールファイルも読み込む対象に含める設定。ただし登録済みの全プロジェクト分がまとめて載るため、常時の負荷は増える |
| 経路スコープ付きルール | 「特定のパターンに一致するファイルを触ったときだけ」読み込まれる、より粒度の細かいルールの仕組み。ただしこれも起動元ディレクトリの配下でしか効かない |
| 起動ディレクトリを共通の親ディレクトリに揃える | すべてのプロジェクトを1つの共通ディレクトリの配下に置き、「サブディレクトリ」という条件そのものを満たす形にする |
3つ目の候補が本命に見えるが、実際に選ぶかどうかは運用上の判断であり、この記事の時点ではまだ確定していない。ここで確定しているのは、「兄弟プロジェクトのルールは読まれていない」という事実そのものと、候補が複数あり、どれも一長一短だという構造だけだ。
「効くはずのルール」を、効いているかどうかとは別に確認する
安全確認の手順をルールファイルに書いたことと、そのルールが実際に効いていることは、別の話だった。横断ワークスペースという運用そのものは合理的で、変える必要はない。だが「必要なときに自動で読み込まれる」という仕様の**「必要なとき」の範囲**を、思い込みではなく観測ログで確認して初めて、書いたはずの安全確認手順がどこで効いてどこで効いていないかが分かった。
管理画面と顧客向けアプリを「別リポジトリ」に分けた理由と、その判断で得たもの・失ったもの
Claude Code に設定ファイルを直接いじらせない——差分案から本人承認に行き着くまでの事故史
ルールを書いた瞬間に生まれるのは、守られる保証ではなく「書いたという安心」の方だ。18件という数字が教えてくれたのは仕様の細部ではなく、その安心を、自分の思い込みではなくログで一度剥がしておく必要があるということだった。