1つのリポジトリに複数のサイトを入れ、サイトごとのフォルダに AI 向けの決まり(CLAUDE.md や AGENTS.md)を置けば、AI はそのサイトの決まりを守って作業する——そう考えたくなりますが、Claude Code も Codex も、下のフォルダの決まりを「いつも読む」わけではありません。リポジトリのルートで起動すると、Claude Code はそのフォルダのファイルに触れるまで読まず、Codex は自動では読み込みません(AI が自分で開くことはありますが、保証はありません)。この記事では、両ツールの公式の説明から「いつ読まれるか」と「読まれたかの確かめ方」を同じ項目で比べ、そのうえで、決まりを文書でなく自動の確認で守らせる方法をまとめます。きっかけは、AI のエージェントにサーバーの運用と複数のプロジェクトを任せている現場で、この設計を考えたときに分かったことです。

サイトごとのフォルダに置いた決まりは、いつ読まれるか(リポジトリのルートで起動したとき)

repo/ ├─ CLAUDE.md・AGENTS.md ← 全体の決まり └─ sites/ ├─ blog/CLAUDE.md・AGENTS.md ← blog の決まり ├─ shop/CLAUDE.md・AGENTS.md ← shop の決まり └─ shared/ ← 共有の部品

Claude Code

  • 起動時ルートの CLAUDE.md
  • 触れたらsites/blog/ のファイルを読む・書く・編集したときに、blog の CLAUDE.md を読む
  • まだまだ触れていないフォルダ(shop)の決まりは読み込まれていない

Codex

  • 起動時ルートの AGENTS.md
  • 保証なしsites/blog/ の AGENTS.md は自動では読み込まない(起動したフォルダより下は探さない)
  • 保証なしsites/shop/ の AGENTS.md(同じ)

だから、サイトの作業はサイトのフォルダで起動し、守らせたいことは文書に頼らない。「担当のフォルダの外を変えたらリリースが止まる」確認を自動で回し、担当は作業場所ごとの設定で決める。決まりの文書は、AI に理由と手順を伝えるために残す。

出典:Anthropic の How Claude remembers your project、OpenAI の Custom instructions with AGENTS.md(どちらも2026年11月1日確認)。

1. サイトごとに決まりを置く設計で分かったこと

AI のエージェントにサーバーの運用と複数のサイトを任せている現場で、1つのリポジトリに複数のサイトを入れ、サイトごとのフォルダにそのサイトの決まりを置く設計を考えました(場所や名前が分かる部分は伏せ、技術の中身は一般化しています)。ねらいは、blog の担当の AI は blog の決まりだけを読み、shop には触れない、という分担でした。

ところが、両ツールの公式の説明を確かめると、置いた決まりが作業の前に必ず読まれるとは限りませんでした。どのフォルダで起動したかで、読まれる決まりが変わります。さらに Claude Code の公式は、CLAUDE.md を「強制される設定ではなく文脈」と書いています。読まれても、守られる保証はありません。

  1. !

    決まりを置いただけでは、担当の分け方として足りない

    起こること
    ルートで起動した AI が、そのサイトの決まりを読まないまま、またはまだ読む前にファイルを変える
    避け方
    サイトの作業はサイトのフォルダで起動し、担当の外の変更はリリースの確認で止める(4章)
    確かめ方
    読まれた決まりをツールで確かめ(3章)、わざと担当の外を変えてリリースが止まるかを見る

AI がルールを無視する一般的な原因と対策は「AIがルールを無視する原因と対応策」にまとめています。この記事は、その中でもフォルダを分けて決まりを置くときに何が起きるかに絞ります。同じ現場で起きた、複数のリポジトリを任せるときの別の注意2つは5章にまとめました。

2. フォルダごとの決まりはいつ読まれるか

サイトごとのフォルダに置いた決まりが読まれるかは、どのフォルダで起動したかと、どのツールかで変わります。両ツールの公式の説明を、同じ項目で並べます。

項目Claude CodeCodex
起動時に読むもの起動したフォルダと、その上の階層すべての CLAUDE.md・CLAUDE.local.mdプロジェクトの一番上(通常は git のルート)から起動したフォルダまで、各フォルダの AGENTS.override.md→AGENTS.md を1つずつ
起動したフォルダより下起動時には読まず、そのフォルダの別のファイルを読む・書く・編集したときに読む自動では読み込まない(起動したフォルダに着いたところで探すのをやめ、AI が自分で開くことはある)
作業の途中で増えるか増える(触れたフォルダの決まりがあとから加わる)増えない(1回の実行の最初に1度だけ組み立てる)
大きさの上限1ファイル200行未満が目安(長いほど守られにくい)で、下のフォルダの CLAUDE.md は、1ファイル4万字(20万トークンの文脈のとき)を超えた分は先頭だけが渡る合計 32 KiB(project_doc_max_bytes の既定)を超えた分は足さない
もう一方のツールの決まりAGENTS.md は、起動したフォルダとその上に CLAUDE.md・.claude/CLAUDE.md・CLAUDE.local.md のどれも無いときに読む(既定)CLAUDE.md は読まない(project_doc_fallback_filenames に足した名前だけを読む)

出典:Anthropic の How Claude remembers your project・Monorepos and large repos、OpenAI の Custom instructions with AGENTS.md(2026年11月1日確認)。Claude Code の下のフォルダの上限は v2.1.309 から。100万トークンの文脈では15万字(Opus 4.6・Sonnet 4.6 は20万字)です。Claude Code が AGENTS.md を直接読むのは v2.1.277 以降で、下のフォルダの AGENTS.md は、そのフォルダに CLAUDE.md が無く、Read ツールでそこのファイルを開いたときに読みます。両方を読ませたいときは、/config の Project instructions を claude-md-and-agents-md にします。

起動する場所で、読まれる決まりが変わる

同じリポジトリでも、どこで起動するかで結果が変わります。サイトのフォルダで起動すれば、両ツールともそのサイトの決まりを最初から読みます。

起動する場所Claude CodeCodex
リポジトリのルートルートの決まりだけで、各サイトの決まりはそのサイトのファイルに触れたときに加わるルートの決まりだけで、各サイトの決まりは自動では読み込まない
sites/blog/blog とルートの決まりを起動時に読む(起動したフォルダの外のファイルの編集は確認を求められる)ルート→blog の順に読み、shop の決まりは道の途中に無いので自動では読み込まない

ここで見落としやすいのが、「触れたら読む」の「触れる」の範囲です。Claude Code の公式が「読む」に数えると書いているのは、ツールでファイルを読む・書く・編集することと、1つのファイルを cat や head で表示するコマンドです。複数のサイトのフォルダにまたがる一括置換のように、それ以外の形でファイルを変える操作は、この中に挙がっていません。サイトの決まりを読む前に、そのサイトのファイルが変わることはありえます。

Codex では、リポジトリのルートで起動して「blog と shop の両方を直して」と頼むと、どちらのサイトの AGENTS.md も自動では読み込まれません。公式の説明は「作業中のフォルダに着いたら探すのをやめる」で、下のフォルダの決まりが起動時に確実に入るのは、そのフォルダかその下で起動したときだけです。

ただし、Codex のリポジトリにある既定の指示(base_instructions/default.md)には、「作業中のフォルダより下や外で作業するときは、当てはまる AGENTS.md を確かめる」という趣旨の指示があります。AI が自分でサイトの AGENTS.md を開くことはありますが、それは AI の判断で、読み込みの仕組みとしての保証ではありません。

フォルダごとの設定ファイルも、引き継ぎ方が違う

決まりの文書だけでなく、権限などの設定ファイルも、フォルダの扱いがツールで違います。

項目Claude CodeCodex
プロジェクトの設定ファイル.claude/settings.json.codex/config.toml
どのフォルダのものを読むか起動したフォルダ(primary working directory)のもので、CLAUDE.md と違い親のフォルダから引き継がないプロジェクトの一番上から起動したフォルダまで(近いほうが優先)
信頼との関係allow のルールなどは、そのフォルダを信頼してから効き、deny と ask はすぐ効く信頼したプロジェクトの .codex/ だけを読む

出典:Anthropic の Claude Code settings・Monorepos and large repos、OpenAI の Config basics(2026年11月1日確認)。

3. 読まれたかを確かめる

決まりを置いたら、起動したあとに「実際に読まれたか」を確かめます。確かめ方もツールで違い、Claude Code では起動時に読んだものと、あとから読んだもので見る場所が変わります。

確かめたいことClaude CodeCodex
起動時に読んだ決まり/context の Memory files の一覧「Show which instruction files are active.」と頼む(AI の自己申告で、確実に見るなら下のログ)
作業の途中で読んだ決まりMemory files には出ず、読み込まれると端末に Loaded の行とパスが出る途中では増えない(上と同じ)
記録に残すInstructionsLoaded フックで、どの決まりをいつ・なぜ読んだかを書き出す(直接読んだ AGENTS.md では動かない)codex -c log_dir=./.codex-log で TUI のログ(./.codex-log/codex-tui.log)を出し、読んだ決まりを見る

出典:Anthropic の How Claude remembers your project のトラブルシューティング、OpenAI の Custom instructions with AGENTS.md の Verify your setup(2026年11月1日確認)。ログのフォルダは .gitignore に足し、git に入れないようにします。

Claude Code で新しく置いた下のフォルダの決まりを試すときは、公式の勧めどおり、決まりのファイルは AI に書かせずシェルで作り、そのあと AI にそのフォルダのファイルを読ませて、Loaded の行が出るかを見ます。

4. 決まりは文書でなく自動の確認で守らせる

2章のとおり、フォルダに置いた決まりは、起動の場所とツールしだいで読まれないことがあります。読まれても、守られる保証はありません。そこで、守らせる手段を3段に分けて考えます。

決まりの文書
理由と手順を伝えるCLAUDE.md・AGENTS.md。読まれないことがあり、読まれても守られる保証はない。それでも「なぜ止まったか」を AI が理解するために要る
ツールの止め
操作の前に止めるAI のツールのフック・権限の設定(この記事では「ツールの止め」と呼ぶ)。ツールごとに書き方が違い、起動の場所や信頼の設定で効かないことがある
リリースの確認
どのツールで作業しても最後に止める担当のフォルダの外を変えたら、リリースの手順そのものが止まる。AI のツールに依存しない

この現場では、いちばん下の「リリースの確認」を決め手にしました。AI のツールを替えても、人が直接作業しても、同じ確認を通るからです。

担当は「作業場所ごとの設定」で決める

サイトごとに作業場所(git worktree)を分け、作業場所の一番上に「この場所の担当が変えてよいフォルダ」を書いた小さな設定ファイル(.agent-owner)を置きます。担当をリポジトリの中の決まりの文書に書くと、どの作業場所でも同じ内容になり、場所ごとに変えられません。設定ファイルは git に入れず(.git/info/exclude に足す)、作業場所を作るときに書きます。

注意したいのは、AI を起動する場所は作業場所の一番上ではなく、その中のサイトのフォルダだという点です。作業場所の一番上はリポジトリのルートと同じなので、そこで起動すると2章の「リポジトリのルート」と同じ結果になります。

# 元の checkout(/srv/repo)から、sites/blog を受け持つ作業場所を /srv/work-blog に作る
cd /srv/repo
git worktree add /srv/work-blog -b blog-work
printf 'sites/blog/\n' > /srv/work-blog/.agent-owner
echo '.agent-owner' >> .git/info/exclude

# AI は作業場所の中の sites/blog/ で起動する
cd /srv/work-blog/sites/blog
claude        # Codex なら codex

# リリースの前に、作業場所の一番上で、元の checkout にある確認の版を回す
cd /srv/work-blog
bash /srv/repo/tools/check-owner.sh origin/main

確認のスクリプトは、作業場所の中の版ではなく、元の checkout(AI が作業しない場所)か CI にある版で回します。作業場所の中の版を回すと、AI が確認のスクリプトそのものを書き換えたときに素通りしてしまうからです。

担当の外を変えたらリリースを止める

リリースの手順の最初に、次の確認(上の tools/check-owner.sh)を入れます。リリースはコミットからだけ行う前提で、コミットしていない変更が残っていれば止まり、比べる基準(origin/main など)からのコミットの差分に担当のフォルダの外のファイルが1つでもあれば止まります。.agent-owner を読むので、作業場所の一番上で回します。

#!/usr/bin/env bash
# リリースの前に、作業場所の一番上で回す:担当のフォルダの外を変えていたら止める
set -euo pipefail

base="${1:-origin/main}"
owner_file=".agent-owner"   # 作業場所(worktree)の一番上に置き、git には入れない

if [ ! -s "$owner_file" ]; then
  echo "担当の設定($owner_file)がありません。リリースを止めます" >&2
  exit 1
fi

# コミットしていない変更が残っていたら止める(リリースはコミットからだけ)
if [ -n "$(git status --porcelain)" ]; then
  echo "コミットしていない変更があります。リリースを止めます" >&2
  exit 1
fi

# --no-renames:別のフォルダからの移動も「消した+足した」の両方で数える
# 担当の末尾に / を補う(sites/blog が sites/blog-old に当たらないように)
# gawk(Git Bash)で確かめた。BSD の awk は -v の値に改行があると止まることがある
outside=$(git diff --name-only --no-renames "$base"...HEAD |
  awk -v list="$(tr -d '\r' < "$owner_file")" '
    BEGIN { n = split(list, own, "\n")
            for (i = 1; i <= n; i++) if (own[i] != "" && substr(own[i], length(own[i])) != "/") own[i] = own[i] "/" }
    { ok = 0; for (i = 1; i <= n; i++) if (own[i] != "" && index($0, own[i]) == 1) ok = 1
      if (!ok) print }')

if [ -n "$outside" ]; then
  echo "担当の外のファイルが変わっています。リリースを止めます:" >&2
  echo "$outside" >&2
  exit 1
fi
echo "担当の中の変更だけでした"

この記事を書いた Claude Code が、2026年11月1日に Git 2.56(Windows の Git Bash)で、サイト2つと共有のフォルダを持つ試しのリポジトリを作って回した結果です。

試したこと結果
blog の担当が blog のファイルだけを直した通る
shop のファイルを blog のフォルダへ移した止まる(移動元の shop のファイルが出る)
共有のフォルダのファイルを直した止まる(共有のフォルダも担当に書かない限り外)
担当を末尾の / なしで書き、sites/blog-old/ を足した止まる(末尾の / を補わない版では通ってしまった)
コミットしていない変更を shop に残した止まる(コミットの差分だけを見る版では見落とす)
担当の設定ファイルを消した止まる

移動を見落とさないのが --no-renames です。これを付けないと、git が移動とみなした変更は移動先の名前だけが出るため、他のサイトからファイルを持ってきた変更を見落とします。設定ファイルが無いときに「通す」のではなく「止める」にしているのも、担当を決め忘れた作業場所を素通りさせないためです。

この確認が防ぐのは取り違えで、わざと破ることではない。AI が .agent-owner を書き換えれば通ってしまいます。そこまで防ぐなら、次のツールの止めで、この設定ファイルの編集も拒否します。

ツールの止めを足す

リリースの前に止まるだけでは、AI が担当の外を書き換えた後で気づくことになります。書く前に止めたいときは、ツールの機能を足します。

項目Claude CodeCodex
ファイルの書き込みを止める権限の設定の deny に Edit(パス) を書く(組み込みのツールと、sed・tee・リダイレクトなど Claude Code が見分けるコマンドに効く)PreToolUse フックで、apply_patch(Edit・Write としても当たる)の書き込む先を見て、permissionDecision の deny を返す
コマンドを止めるdeny に Bash(コマンド *) を書く・PreToolUse フックで終了コード2か拒否の JSON を返すルールの prefix_rule(pattern=[...], decision="forbidden")(実験的)と PreToolUse フック
どのプロセスも止めるサンドボックス(スクリプトが自分でファイルを開いて書く場合は deny では止まらない)サンドボックス(sandbox_mode = "workspace-write" で、書けるのを起動したフォルダの中に限る・writable roots は書ける場所を足す設定なので、むやみに足さない)
プロジェクトに置いたときの条件起動したフォルダの .claude/settings.json を読み、deny はフォルダを信頼する前から効くプロジェクトの .codex/ を信頼したときだけ読み、フックは確認して信頼するまで動かない

出典:Anthropic の Configure permissions・Hooks guide、OpenAI の Hooks・Rules(2026年11月1日確認)。

Claude Code なら、blog の作業場所で、担当の設定(.agent-owner)・確認のスクリプト(tools/)・ルートの決まり・shop・共有のフォルダを書き換えさせない設定は次のようになります(作業場所を /srv/work-blog に作った場合)。// で始まるパスは絶対パスです。作業場所の場所は端末ごとに違うので、リポジトリに入れる設定ではなく、その端末の個人の設定(~/.claude/settings.json)に、作業場所を作るときに書き足します。

{
  "permissions": {
    "deny": [
      "Edit(//srv/work-blog/.agent-owner)",
      "Edit(//srv/work-blog/tools/**)",
      "Edit(//srv/work-blog/CLAUDE.md)",
      "Edit(//srv/work-blog/AGENTS.md)",
      "Edit(//srv/work-blog/sites/shop/**)",
      "Edit(//srv/work-blog/sites/shared/**)",
      "Edit(//srv/repo/**)"
    ]
  }
}

Codex では、フックの設定(個人の ~/.codex/hooks.json か、リポジトリの .codex/hooks.json など)の PreToolUse に、apply_patch を当てはめ(matcher)にして確認のスクリプトを登録します。フックは、Codex の /hooks で中身を確かめて信頼するまで動きません(中身を変えると、もう一度信頼が要ります)。

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "^apply_patch$",
        "hooks": [ { "type": "command", "command": "python3 ~/.codex/hooks/owner_guard.py" } ] }
    ]
  }
}

確認のスクリプトは、apply_patch の *** Add File:・*** Update File:・*** Delete File:・*** Move to: の行から書き込む先のパスを取り出し、担当の外か守るファイルなら deny を返します。最小の例です。

import json, posixpath, re, sys

# Codex の PreToolUse フック:apply_patch が担当の外や守るファイルを書き換えるなら止める
OWN = ["/srv/work-blog/sites/blog/"]                  # 担当(末尾の / まで書く)
PROTECT = ["/srv/work-blog/.agent-owner", "/srv/work-blog/tools/"]

event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")
if isinstance(command, list):
    command = "\n".join(command)

bad = []
for m in re.finditer(r"^\*\*\* (?:Add File|Update File|Delete File|Move to): (.+)$", command, re.M):
    path = posixpath.normpath(posixpath.join(event.get("cwd", ""), m.group(1).strip()))
    if not any(path.startswith(o) for o in OWN) or any(path.startswith(p) for p in PROTECT):
        bad.append(path)

if bad:
    print(json.dumps({"hookSpecificOutput": {
        "hookEventName": "PreToolUse",
        "permissionDecision": "deny",
        "permissionDecisionReason": "担当の外のファイルです: " + ", ".join(bad)}}, ensure_ascii=False))

この記事を書いた Claude Code が、Codex が渡す形を手で作った入力(担当の中・shop・.agent-owner・共有への移動・tools/ の削除)で回し、担当の中だけが通ることを確かめました。Codex に組み込んで動かしてはいません。

Bash のコマンドは書き方が多く、書き込む先をフックで完全には見分けられません。OpenAI もフックを「a useful guardrail, not a complete enforcement boundary」(役に立つ防護柵で、完全な強制の境界ではない)としています。rm など止めたいコマンドはルールの decision = "forbidden" で止め、最後はリリースの確認で受け止めます。ルールは ~/.codex/rules/default.rules のように設定の層の rules/ フォルダに置きます。プロジェクトの .codex/rules/ は、そのプロジェクトを信頼したときだけ読まれます。

ツールの止めはツールごとに書き直しが要り、起動の場所や信頼の設定で効かないこともあります。だから、最後に必ず通るリリースの確認を土台にし、ツールの止めは「早く気づくため」に重ねる、という順で考えます。Claude Code のフックの書き方は「Claude Code hooks(フック)とは」に、読み取りだけにする設定は「Codex・Claude Codeを読み取り専用で使う方法」にあります。

5. あわせて気をつけること——リポジトリの取り違えと環境変数

同じ現場では、AI に複数のリポジトリを任せたときに、ほかに2つのことが起きました。どちらも大きな事故になる前に止められましたが、決まりの置き方とは別に、手順として決めておきます。

似た名前のリポジトリは remote の URL で見分ける

AI が、名前のよく似た別のサービスのリポジトリを「同じサービスの古い写し」と判断して、別の場所へ退避しました(すぐに戻し、中身は無変更)。根拠は「手元に変更が無い・最後の更新が古い」でしたが、これは「作業の途中のものが無い」「最近は誰も直していない」ことしか示しません。安定して動いているサービスほど、更新は止まっています。

動かす・消す前に、対象のフォルダと本番で使っているフォルダの両方で次を出し、並べて比べます。

# remote の URL(URL に入ったトークンやパスワードは消して表示する)
git -C <フォルダ> remote get-url origin | sed -E 's#://[^/@]+@#://#'

# 浅いクローンでないかを先に確かめる(true なら次の結果は当てにならない)
git -C <フォルダ> rev-parse --is-shallow-repository

# 最初のコミット(同じ歴史から分かれた写しなら一致する)
git -C <フォルダ> rev-list --max-parents=0 HEAD
  • remote の URL はホストとリポジトリのパスで比べる:https://github.com/org/app.git と git@github.com:org/app.git は書き方が違うだけで同じリポジトリだが、逆にミラーや別名のホストを使っていると、同じリポジトリでも違って見える
  • 最初のコミットは、浅いクローンでは本当の最初ではない:--depth 1 で取ったクローンでは、取ってきたいちばん古いコミット(試すと HEAD そのもの)が出る
  • URL に入ったトークンを表示させない:remote の URL に認証のトークンが入っていることがあり、そのまま出すと次の環境変数と同じ形で秘密が出力に出る

照らした結果「使われていない写し」と分かっても、いきなり消さずに、まず別の場所へ移します。移した先・元の場所・戻すコマンドを書き残し、しばらく何も壊れないことを確かめてから消します。この現場で取り違えをすぐに戻せたのも、消さずに移していたからです。

環境変数は名前だけを見る

AI がコンテナの設定を調べるコマンドで環境変数を値ごと表示し、データベースの接続の文字列(パスワード入り)が出力に出ました。値が出力に出れば、それは会話の記録に残り、モデルにも送られます。何が設定されているかを見るだけなら、名前で足ります。

コンテナの環境変数

値が出る(使わない)

docker inspect <コンテナ>
docker exec <コンテナ> printenv
docker exec <コンテナ> sh -c 'env | cut -d= -f1'

名前だけ

docker inspect --format '{{range .Config.Env}}{{index (split . "=") 0}}{{println}}{{end}}' <コンテナ>
docker exec <コンテナ> awk 'BEGIN{for(k in ENVIRON) print k}'

docker inspect は何も指定しないと設定の全体を出し、その中の Env に値がそのまま入っています。awk の無いコンテナでは、docker inspect --format のほうを使います。

Docker Compose の設定

値が出る(使わない)

docker compose config

変数を展開しない

docker compose config --no-interpolate

--no-interpolate では、${DB_URL} はそのまま、env_file はファイルのパスだけが出ます。compose.yaml に値を直接書いた変数は出ます。

手元のシェル

値が出る(使わない)

env
printenv
Get-ChildItem Env:

名前だけ

compgen -e                  # bash
(Get-ChildItem Env:).Name   # PowerShell

この記事を書いた Claude Code が、2026年11月1日に Docker 29.8・Docker Compose v5.6 で、ダミーの値を入れて試した結果です。改行を含む値(鍵のファイルの中身を渡すときの形)を1つ入れたコンテナで env | cut -d= -f1 を回すと、変数の名前に混じって値の2行目と3行目がそのまま出ました。awk の ENVIRON と docker inspect --format では値は出ませんでした。docker compose config は、.env と env_file に書いたダミーの値を表示し、--no-interpolate を付けると、どちらも出ず、compose.yaml に直接書いた値だけが出ました。

決まりの文書に「環境変数は名前だけを見る」と書いたうえで、値を出すコマンドを4章のツールの止めで拒否しておくと確実です。それでも値が出てしまったら、その値は「見られたもの」として扱い、入れ替えるかを判断します。Codex で環境変数そのものを AI のコマンドに渡さない設定は「Codexに秘密ファイルを読ませない方法」の6章にあります。

6. 任せる前のチェックリスト

  • サイトの作業は、作業場所の中のサイトのフォルダで AI を起動すると決めた
  • 起動したあと、Claude Code は /context の Memory files、Codex は有効な決まりの一覧で、そのサイトの決まりが入っているかを見た
  • ルートで起動する作業では、下のフォルダの決まりが途中で読まれたか(Claude Code の Loaded の行・InstructionsLoaded フック)を見る手段を用意した
  • 担当のフォルダの外を変えたらリリースが止まる確認を入れ、わざと外を変えて止まるのを見た
  • 作業場所ごとに担当の設定を末尾の / 付きで書き、設定が無いときは止まるようにした
  • 担当の外と担当の設定ファイルへの書き込みを、ツールの止めで拒否した
  • フォルダを動かす・消す前に、remote の URL と最初のコミットを本番と照らし、消さずに移す手順を決まりに書いた
  • 環境変数は名前だけを見るコマンドを決まりに書き、値を出すコマンドはツールの止めで拒否した
決まりの文書に書いておく例(そのまま使える形)
## 複数のプロジェクトを扱うときの決まり
- この作業場所の担当は .agent-owner に書いたフォルダだけ。外のファイルは変えない
  (変えるとリリースの確認で止まる)
- フォルダを動かす・消す前に、git remote get-url origin と
  git rev-list --max-parents=0 HEAD を本番のものと照らす(浅いクローンに注意)。
  消さずに移し、戻し方を残す
- 環境変数は名前だけを見る。env・printenv・docker inspect(--format なし)・
  docker compose config(--no-interpolate なし)は使わない

文書は守らせる手段ではなく、止まったときに AI が理由を理解し、正しい手順を選ぶための説明として書きます。

まとめ

  • サイトごとのフォルダに置いた決まりは、ルートで起動すると、Claude Code ではそのフォルダのファイルに触れるまで読まれず、Codex では自動では読み込まれない(AI が自分で開くことはあるが保証はない)
  • どちらのツールでも、サイトのフォルダで起動すればそのサイトの決まりは最初から読まれる(worktree なら、その中のサイトのフォルダで起動する)
  • 読まれたかは、起動時の分を Claude Code の /context や Codex の有効な決まりの一覧で、Claude Code の途中の分を Loaded の行や InstructionsLoaded フックで確かめる
  • 守らせたいことは、担当のフォルダの外を変えたらリリースが止まる自動の確認にし、ツールの止めは早く気づくために重ねる
  • あわせて、似た名前のリポジトリは remote の URL と最初のコミットで見分け、環境変数は名前だけを見る

FAQ

Q. サブディレクトリに置いた CLAUDE.md は読まれますか?

A. 読まれますが、起動したときではありません。Claude Code は、Claude がそのフォルダの中のファイルを読む・書く・編集したときに、そのフォルダの CLAUDE.md を読み込みます。このとき /context の Memory files には出ず、端末に Loaded の行とパスが出ます。そのフォルダで起動した場合は起動時に読み、Memory files に出ます。

Q. Codex でサブディレクトリの AGENTS.md を読ませるには?

A. そのフォルダで Codex を起動します(CLI なら codex --cd <フォルダ>)。Codex はプロジェクトの一番上から起動したフォルダまでの AGENTS.md を起動時に読み、それより下は探しません。ルートで起動した場合、下のフォルダの AGENTS.md は AI が自分で開けば読まれますが、確実に読み込ませる設定は公式の説明にはありません。

Q. モノレポでは、決まりの文書はルートに1つにまとめるべきですか?

A. 全体に効かせたいことはルートに、サイトだけのことはサイトのフォルダに分けるのが両ツールの公式の勧めです。ただし、サイトの決まりはそのフォルダで起動しないと読まれないことがあるので、守らないと困ることは文書ではなく、リリースの確認やツールの止めに移します。

Q. Claude Code に CLAUDE.md と AGENTS.md の両方を読ませるには?

A. 既定では、起動したフォルダとその上に CLAUDE.md・.claude/CLAUDE.md・CLAUDE.local.md のどれかがあると、AGENTS.md は読みません。CLAUDE.md に @AGENTS.md の1行を書いて取り込むか、/config の Project instructions を claude-md-and-agents-md にします。

出典