指示書を1本にする

更新: 2026-09-09
Claude CodeCodexAIエージェントCLAUDE.mdAGENTS.md

同じリポジトリを複数のコーディングエージェントで触ると、指示書がエージェントの数だけ増える。 Claude Code は CLAUDE.md を、Codex は AGENTS.md を読む。中身は同じつもりでも、片方だけ更新した瞬間から実行主体によって守られるルールが変わる。

厄介なのは、これが失敗として表に出ないことだ。エラーも警告も出ない。「なぜかCodexのときだけmainに直接コミットされる」という形で、ずっと後から気づく。

まず差分を見る

乖離した状態Claude CodeCLAUDE.mdCodexAGENTS.mdズレるPR必須・IssueラベルDockerメモリ制限Codexは知らないClaudeは知らない1本化した状態CLAUDE.md(実体)AGENTS.md(リンク)両方のエージェントが同じ1つの内容を読む乖離はエラーを出さない。「Codexのときだけルールが守られない」として後から気づく。同期させるのではなく、そもそも分かれない形にする。
2つの指示書を同期し続けるのではなく、実体を1つにして分岐を消す。

手を入れる前に、何がズレているかを機械的に出す。

diff AGENTS.md CLAUDE.md

実際に出てきたのは次の乖離だった。どちらも実害のあるルールで、「まあ似たようなことが書いてあるだろう」という予想は外れた。

CLAUDE.md にしかなかったAGENTS.md にしかなかった
Issueラベル運用、main直コミット禁止・PR必須Dockerのメモリ・CPU制限、E2E実行手順
設計ドキュメントの配置ルール進捗ログの記入形式
デプロイ手順(自動デプロイ停止中)最小差分・未コミット変更を戻さない

Codex には「PRを経由せよ」が届いておらず、Claude Code には「docker compose run にメモリ上限を明示せよ」が届いていなかった。後者は制限なしで大規模処理を走らせて Docker ごと落とす類のルールで、知らないまま実行される状態が続いていた。

実体を1つにする

内容を複製して差分を見張る方法もあるが、書き分ける理由が無いなら、そもそも分かれない形にするほうが安い。

git rm --cached AGENTS.md
rm AGENTS.md
ln -s CLAUDE.md AGENTS.md

Git はシンボリックリンクをモード 120000 のオブジェクトとして記録する。中身はリンク先のパス文字列そのものになる。

$ git cat-file -p :AGENTS.md
CLAUDE.md

これが CLAUDE.md を返せば、複製ではなくリンクとして記録されている。クローンした側でもリンクとして復元される。

エージェント側の設定変更は要らない。Codex は AGENTS.md をファイルシステム経由で開くので、リンクは透過的に解決される。**「Codexに伝える」作業が発生しないのがこの方式の要点で、**指示書を配る運用が残っている限り配り忘れも残る。

実体をどちら側に置くか

AGENTS.md は複数のAI CLIが読む共通フォーマットとして策定されていて、ln -s AGENTS.md CLAUDE.md と**逆向きに張る例のほうが多い。**Claude Code は CLAUDE.md が無ければ AGENTS.md をフォールバックとして読むので、その構成でも成立する。

向きの判断は「編集がどちら側で発生するか」で決まる。ルールの追加が Claude Code のセッション中に起きることが多いなら、実体を CLAUDE.md に置くほうが、うっかりリンク側を編集する事故が減る。**リンクを張る向きに正解は無いが、決めたら本体の冒頭に明記する。**どちらが実体かは ls -l を打たないと分からない。

リンクにできない場合は複製と点検にする

実行基盤そのものが違って同じ手順が成立しないものは、リンクにできない。サブエージェントの起動方法がその例で、Claude Code はバックグラウンドの claude -p セッション、Codex は multi_agent_v1__spawn_agent を使う。同じ文面では両方とも動かない。

この場合は複製を許し、代わりに点検スクリプトで差分を落とす。判定はこう置いた。

状況結果
両方にあり本文が一致OK
両方にあり本文が不一致差分あり(終了コード1)
両方に sync-exempt 注記がある除外(理由を表示)
片方だけに sync-exempt差分あり
片方に無く、注記も無い差分あり

**片方に無いだけの状態を情報表示で済ませないのが肝心で、**それをやると「意図的に置いていない」と「単に入れ忘れた」が区別できない。実際、この判定を緩くしていた期間に3つのスキルが取りこぼされていた。

判定の使い分けは1つの問いで決まる。基盤の違いで同じ手順が成立しないか。 文面の好みや書き手の違いは複製の理由にならない。

自動読み込みの範囲が違うことに注意する

CLAUDE.md から切り出した詳細ルール(.claude/rules/ 配下など)は、Claude Code が自動で読み込む。Codex は読まない。

リンクで指示書を1本にしても、そこから参照している別ファイル群は自動では追随しない。分割したルールを両方に効かせるなら、本体に読む指示を1行書く。

- `.claude/rules/` 配下の各ルールは実行主体を問わず適用する。
  Claude Code は自動で読み込むが、Codex は自動では読まないため作業前に該当ファイルを確認する。

指示書を分割するほど、この「自動で読まれる範囲の差」が効いてくる。分割の判断は読みやすさだけで決めない。

グローバル階層も同じ問題を持つ

リポジトリ内だけを見て終わりにしない。ホーム配下にも同じ対が存在する。

階層Claude CodeCodex
グローバル~/.claude/CLAUDE.md~/.codex/AGENTS.md
リポジトリCLAUDE.mdAGENTS.md

グローバル側を突き合わせたら、片方をコピーして作った跡が残っていた。.claude.Codex の一括置換が本文にも当たり、~/.Codex/settings.json.Codex/rules/ という**実在しないパスを禁止対象として列挙していた。**大文字小文字まで置換に巻き込まれている。

コピーして固有名詞を置換する運用は、この形で静かに壊れる。置換後に実在確認をしていないと気づけない。

grep -n "\.Codex" ~/.codex/AGENTS.md   # 該当が出たら置換が本文へ当たっている

グローバル側も同じくリンクへ寄せた。ただし対象パスの列挙は両ツール分を1つのリストに統合する必要がある。リンクにすると「片方だけに当てはまる記述」が置けなくなるため、列挙型のルールは統合してから寄せる。

確認すること

  1. diff AGENTS.md CLAUDE.md で乖離の中身を出す。予想で済ませない
  2. 片方にしか無いルールを本体へ統合する。列挙型は両方分をまとめる
  3. ln -s CLAUDE.md AGENTS.md でリンクにする
  4. git cat-file -p :AGENTS.md がリンク先パスを返すことを確認する
  5. 参照している分割ルールが自動読み込みされるかを主体ごとに確認する
  6. ホーム配下の同じ対も点検する。置換の当たり損ねを grep で探す

以後は本体だけを編集する。リンク側を直接編集すると実体を書き換えることになるので、その注意を本体の冒頭に書いておく。

作業の経緯は 指示書がズレていた に書いた。 並行作業そのものの分離は worktreeで分ける を参照。

WIKI一覧へ