指示書を1本にする
同じリポジトリを複数のコーディングエージェントで触ると、指示書がエージェントの数だけ増える。
Claude Code は CLAUDE.md を、Codex は AGENTS.md を読む。中身は同じつもりでも、片方だけ更新した瞬間から実行主体によって守られるルールが変わる。
厄介なのは、これが失敗として表に出ないことだ。エラーも警告も出ない。「なぜかCodexのときだけmainに直接コミットされる」という形で、ずっと後から気づく。
まず差分を見る
手を入れる前に、何がズレているかを機械的に出す。
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 Code | Codex |
|---|---|---|
| グローバル | ~/.claude/CLAUDE.md | ~/.codex/AGENTS.md |
| リポジトリ | CLAUDE.md | AGENTS.md |
グローバル側を突き合わせたら、片方をコピーして作った跡が残っていた。.claude → .Codex の一括置換が本文にも当たり、~/.Codex/settings.json や .Codex/rules/ という**実在しないパスを禁止対象として列挙していた。**大文字小文字まで置換に巻き込まれている。
コピーして固有名詞を置換する運用は、この形で静かに壊れる。置換後に実在確認をしていないと気づけない。
grep -n "\.Codex" ~/.codex/AGENTS.md # 該当が出たら置換が本文へ当たっている
グローバル側も同じくリンクへ寄せた。ただし対象パスの列挙は両ツール分を1つのリストに統合する必要がある。リンクにすると「片方だけに当てはまる記述」が置けなくなるため、列挙型のルールは統合してから寄せる。
確認すること
diff AGENTS.md CLAUDE.mdで乖離の中身を出す。予想で済ませない- 片方にしか無いルールを本体へ統合する。列挙型は両方分をまとめる
ln -s CLAUDE.md AGENTS.mdでリンクにするgit cat-file -p :AGENTS.mdがリンク先パスを返すことを確認する- 参照している分割ルールが自動読み込みされるかを主体ごとに確認する
- ホーム配下の同じ対も点検する。置換の当たり損ねを
grepで探す
以後は本体だけを編集する。リンク側を直接編集すると実体を書き換えることになるので、その注意を本体の冒頭に書いておく。
作業の経緯は 指示書がズレていた に書いた。 並行作業そのものの分離は worktreeで分ける を参照。