doxでAGENTS.mdを自動更新する方法
3週間後にAGENTS.mdが古くなる問題を解決します。doxでリポジトリから再生成し、コードと同じように差分を確認する手順を紹介します。
3 週間後に AGENTS.md が誤った内容になる理由
AGENTS.md が古くなるのは、その内容とコードを結び付ける仕組みがないためです。リポジトリが特定の状態だった日に、手作業で 1 度だけ作成します。その後、テストランナーが変わり、パッケージ名が変更され、サービスが削除されても、ファイルには 6 月の状態が記載されたままです。ビルド手順でこのファイルを読み込まないため、何も失敗しません。
エージェントはその内容を読み、正しいものとして扱います。ここが問題になります。AGENTS.md がないリポジトリでは、コーディングエージェントは処理を始める前に周囲を確認します。誤った AGENTS.md があるリポジトリでは、すでに答えを得たと判断し、確認を止めます。ファイルに記載されたコマンドを実行すると、shell は Missing script: "test" を返し、エージェントは推測を始めます。多くの場合、ドキュメントで示されたスクリプトを追加するために package.json を編集します。古いファイルは静かに無視されたのではありません。望んでいない編集を引き起こしたのです。
dox はその対策の 1 つです。エージェント向けに記述したルールの集合であり、ドキュメントの更新を作業完了の一部にします。そのため、ファイルは内容を誤らせたコードと同じコミットで変更されます。
dox とは何か、また何ではないか
dox は単一の Markdown ファイルです。リポジトリは agent0ai/dox で、MIT ライセンスが適用されています。2026年8月11日時点で、プロジェクト全体は 3906-byte の AGENTS.md、README、LICENSE、および 2 つの画像で構成されています。インストールするパッケージも、ランタイムもありません。
これは重要です。generator という名前から、コードを解析するプログラムを想像しやすいためです。コードを解析するものはありません。dox は coding agent が読む契約です。generator は agent であり、dox は、ドキュメントをいつ読み、いつ書き換え、各ドキュメントをどのような形式にするかを指示する命令セットです。
このファイルには 10 のセクションがあり、そのうち 2 つが実際の処理を担います。"Read Before Editing" は、agent に対して、変更する予定のすべてのパスをリポジトリのルートからたどり、各経路上にあるすべての AGENTS.md を、記憶に頼らず現在のセッション内で読むよう指示します。"Update After Editing" は、意味のある変更を行うたびに DOX pass が必要であり、タスク完了前にドキュメント更新手順を実行するよう指示します。この pass では、目的、構造、ワークフロー、権限、またはユーザー設定が変更された場合に、変更対象を管轄する最も近いドキュメントを更新します。
残りは形式を定義します。子 AGENTS.md には、Purpose、Ownership、Local Contracts、Work Guidance、Verification、Child DOX Index という既定のセクション順があります。ルートファイルにはプロジェクト全体のルールとトップレベルの Child DOX Index が記載されます。agent はこの Index を使って子ドキュメントを見つけます。"Closeout" は、agent がタスクの最後に実行するチェックリストです。変更したパスを chain と照合し、最も近い管轄ドキュメントを更新し、影響を受けるすべての Index を更新し、矛盾を削除し、既存の検証を実行し、意図的に変更しなかったドキュメントを報告します。
1 つのコミットに pin し、main には pin しない
リポジトリにはタグもリリースもないため、pin に使えるバージョン番号がありません。代わりにコミットを pin します。現在の AGENTS.md は、2026 年 8 月 1 日付のコミット f34ec7ad1055d3393887e5a2670e8cb7320c9165 です。
mkdir -p .agent
curl -fsSL -o .agent/dox-f34ec7a.md \
https://raw.githubusercontent.com/agent0ai/dox/f34ec7ad1055d3393887e5a2670e8cb7320c9165/AGENTS.md
wc -c .agent/dox-f34ec7a.mdwc -c は 3906 を出力する必要があります。異なる番号が表示された場合、このガイドで説明しているファイルを取得できていません。内容を読むまでは信頼しないでください。コミットハッシュを入力し間違えると、-f により curl は curl: (22) The requested URL returned error: 404 で停止し、内容を書き込みません。その後、wc -c は 0 を出力します。ファイルが途中で切れている状態は、ファイルがない状態より危険です。エージェントが契約の一部だけに従い、全体を把握できなくなるためです。
cp .agent/dox-f34ec7a.md AGENTS.md
git add AGENTS.md .agent/dox-f34ec7a.md
git commit -m "Add DOX rules (agent0ai/dox @ f34ec7a)"この cp は、まだ AGENTS.md がないリポジトリ向けです。すでにある場合は上書きしないでください。既存の内容の上に dox のセクションを追加し、自分のルールはその下に残します。追加後は、上から下まで一度通して読みます。互いに矛盾する 2 つの文書があると、エージェントは最後に読んだ方の記述に従います。
次に、リポジトリ内でエージェントに初回処理を依頼します。README に正確な文言が記載されています。
Initialize DOX tree for this project now.これにより、子 AGENTS.md ファイルと、それらを参照するインデックスが作成されます。内容を確認してから正しいと判断してください。
git status --short
find . -name AGENTS.md -not -path './.git/*' | sortfind の出力に含まれるすべてのファイルは、その上位にあるいずれかの Child DOX Index に記載されている必要があります。どのインデックスからも参照されていない子ドキュメントは、エージェントが見落とす可能性があります。インデックスは、エージェントが現在たどっているパス上に直接存在しない文書を見つけるために使われるためです。
dox が確認できる情報と確認できない情報
ツリーを作成するエージェントはリポジトリを読み取るため、リポジトリ内の情報はすべてインベントリに含められます。ディレクトリ構成、パッケージマニフェストとロックファイル、package.json、Makefile、pyproject.toml 内のスクリプト、CI ワークフローファイル、Dockerfile、エントリーポイント、CODEOWNERS(存在する場合)などです。これらから作成したインベントリは、実際に自己更新できます。パッケージを移動すると、次回の処理でそのパッケージを説明する行も移動します。
以下の事項は、リポジトリ内に存在せず読み取れないため、利用者が記述する必要があります。
- ルールが存在する理由。これにより、エージェントが不要な複雑さとしてルールを削除するのを防ぎます。
- 動作する2つの方法のうち、サポート対象がどちらか、また削除待ちなのがどちらか。
- ステージング環境や、依存関係を2つ前のバージョンに固定している理由など、リポジトリ外の情報。
- 来週に予定している作業。これは、ファイルが最新であることと、役立つことの違いです。
dox は、この点を自身についても把握しています。独自のルールでは、Work Guidance はプロジェクトの現在の標準またはユーザーの指示を反映する必要があり、まだどちらも存在しない場合は、そのセクションを空にすると定めています。Verification も既存のチェックを反映する必要があります。そのため、リポジトリにテストフレームワークがない場合、このセクションは導入されるまで空のままにします。標準を勝手に作り出す生成ファイルは、空のセクションよりも悪影響があります。エージェントが、その作り出された標準を適用してしまうためです。
生成インベントリに手書きの意図を混在させない
生成ドキュメントを諦める原因になるのが、この問題です。ジョブキューを単一コンシューマーのまま維持する必要があることを、段落で説明したとします。3 週間後、ある pass がファイルを書き換え、その段落が消えます。しかも、ほとんどがファイル名の並べ替えである 40 行の差分に埋もれるため、誰も気付きません。
2 つの仕組みを用意し、両方を使います。
まず、変更せずに残す意図を別のファイルへ移します。設計上の判断とその理由は、agent 向けに作成した DESIGN.md に記載します。人向けのメモは、AGENTS.md から HUMAN.md に分離する場所に置きます。AGENTS.md にはインベントリとローカルの契約だけを記載します。これはコードの変更に応じて変更されるべき部分です。
次に、AGENTS.md 内に残す必要がある意図を保護します。マーカーで囲み、そのブロックを人が管理する部分として扱います。
## User Preferences
<!-- dox:keep start -->
The jobs queue stays single consumer. Ordering is the reason this service exists.
Deploys ship on Tuesday. A Friday deploy is a human decision, not an agent decision.
<!-- dox:keep end -->Markdown のコメントはページ上に表示されませんが、agent は読み取れます。次に、このブロックが残っていることを検査できるようにします。ブロックを削除する pass が明確に失敗するようにするためです。すべての pull request で、CI (continuous integration) から次を実行します。
git fetch -q origin main
sed -n '/dox:keep start/,/dox:keep end/p' AGENTS.md > /tmp/keep.head
git show origin/main:AGENTS.md | sed -n '/dox:keep start/,/dox:keep end/p' > /tmp/keep.base
diff -u /tmp/keep.base /tmp/keep.headdiff は、ブロックが変更されていない場合、何も出力せずに 0 で終了します。出力があれば、pass が人の管理するテキストを書き換えたことを意味します。その場合は、人が承認するか、変更を元に戻します。誰かが覚えておかなくても、この検査によって状態を維持できます。
プルリクエストで再生成し、タイマーでは実行しない
ドキュメントを更新する最適なタイミングは、ドキュメントを誤った状態にしたコミットです。構造を変更する同じプルリクエストで DOX の処理も実行すれば、差分が実際に確認できる大きさに収まります。
これを強制するブロッキングチェックの例を示します。
#!/usr/bin/env bash
set -euo pipefail
git fetch -q origin main
base=$(git merge-base origin/main HEAD)
changed=$(git diff --name-only "$base" HEAD)
if grep -qE '^(src|apps|packages)/' <<<"$changed" && ! grep -q 'AGENTS\.md$' <<<"$changed"; then
echo "Code changed but no AGENTS.md was touched. Run a DOX pass, or say why not."
exit 1
fiパスはリポジトリに合わせて調整してください。ブランチ上で失敗するため修正コストが低く、レビュアーが対応できる理由で失敗することに意味があります。
スケジュール実行はバックアップであり、主要な仕組みではありません。週次ジョブを実行すると、ブランチ上で誰も気付かなかった変更を検出できます。たとえば、rebase で移動したファイル、merge で削除されたパッケージ、存在しなくなったディレクトリを参照するドキュメントなどです。小さなマシンで実行してください。VPS 上でコーディングエージェントを実行する場合と同じマシンでも構いません。また、main に直接 push するのではなく、プルリクエストを作成するようにします。
#!/usr/bin/env bash
set -euo pipefail
cd /srv/src/myapp
git fetch -q origin
git switch -c "dox/refresh-$(date +%Y%m%d)" origin/main
# Your agent CLI goes on the next line, in whatever non-interactive mode it offers.
# Prompt: "Run a DOX pass over this repository. Change AGENTS.md files only."
git add '*AGENTS.md'
git commit -m "dox: refresh AGENTS.md tree" || { echo "nothing to refresh"; exit 0; }
git push -q -u origin HEAD
gh pr create --fillこのコメントは意図的にプレースホルダーにしています。エージェントごとに CLI (command line interface) と非対話モード用のフラグが異なります。Web ページからコピーしたコマンドが使用中のバージョンに合わないと、エラーが表示されない cron 内で失敗します。スケジュールを設定する前に内容を埋め、スクリプトを一度手動で実行してください。|| exit 0 も重要です。ツリーがすでに最新の場合、git commit は nothing to commit, working tree clean で終了ステータスが 0 以外になります。そのため、set -e では正常な実行が失敗として報告されます。
各処理ではトークンを消費します。「Read Before Editing」により、エージェントはタスクごとに一連の情報全体を読み取るためです。これはトレードオフです。すでにエージェントの実行コストを集計している場合は、コストを監視する価値があります。
モノレポ: 多数の契約を1つのインデックスで管理
40個のパッケージを含むリポジトリに、ルートの AGENTS.md を1つだけ置くと、誰も読まない再生成差分が発生し、現在 agent が行っている作業にはほとんど関係のないドキュメントになります。dox の答えは Child DOX Index です。ルートにはリポジトリ全体のルールを置いて子ファイルを参照させ、各永続的な境界には専用ファイルを持たせます。このツリーの構成方法と、ネストされたファイルを実際に読み取るツールについては、モノレポでのネストされた AGENTS.md ファイルで説明しています。
dox が変えるのはレビュー対象の範囲です。packages/api に変更を加える pull request では、packages/api 内だけにドキュメント差分が生成され、他の場所には差分が出ないはずです。
git diff --stat -- '*AGENTS.md'1つのパッケージだけを変更したのに、そのコマンドが6個のファイルを一覧表示するなら、ツリーの構成が誤っています。境界が粗すぎるか、ルートに置くべきルールをすべての子にコピーしています。dox は修正方法を明確に示します。広範なルールは親のドキュメントに置き、具体的な詳細は子のドキュメントに置きます。定型的な処理のたびにすべてを書き換える原因は、ルールの重複です。同じルールが複数のリポジトリに本当に適用される場合、それは別の問題です。その場合は、リポジトリ間で agent skills を共有するほうが適切です。
生成された差分をコードとしてレビューする
生成されたドキュメントの差分は、読まずに承認しやすいものです。その結果、誤ったファイルがリリースされます。生成コードを確認するときと同じ注意を払い、次の4点を確認します。
- ファイルに新しく記載されたコマンド。マージ前に自分で実行します。架空のビルド手順は、最もよくある失敗です。
- 意図を示していた削除行。追加は容易です。失われるのは削除された内容です。
- 絶対パス、ホスト名、内部 URL、または認証情報のように見える文字列
- すでに存在しないもののインベントリエントリ。
lsで1秒以内に確認できます
次に、wc -l AGENTS.md でサイズを確認します。root ファイルが200行を超えている場合は、分割するサインです。このチェーンの価値は、エージェントがすべてではなく、関連する小さな部分だけを読むことにあるためです。
問題が発生した場合
パスによって意図ブロックが削除されました。 上記の diff チェックで、削除された行を確認できます。git restore --source=origin/main AGENTS.md でブランチポイント時点のファイルを復元し、変更対象としてよいセクションを指定する、より限定的な指示でパスを再実行します。
2 つのブランチで再生成されました。 CONFLICT (content): Merge conflict in AGENTS.md と、ファイル内の競合マーカー <<<<<<< HEAD が表示されます。マーカーを手作業で編集しないでください。ファイルは生成物なので、正しい解決方法はマージ済みツリーに対してパスを最初から実行することです。
エージェントがファイルを完全に無視します。 ツールが実際に読み込んでいるファイル名を確認します。別のファイルを読み込んでいる場合は、ln -s AGENTS.md CLAUDE.md で同じ内容を参照させ、シンボリックリンクをコミットします。これにより、内容が別々に変化する2つのドキュメントではなく、1つのソースを維持できます。ファイル名が正しく、それでもルールがスキップされる場合は、ドキュメントを再度書き直す前に コーディングエージェントが指示を無視する理由 の診断を実行します。
ツリーに、誰もインデックスに登録していない子が追加されました。 find . -name AGENTS.md の出力を、親ドキュメントのインデックス項目と比較します。どのインデックスにも記載されていない子は、エージェントがそのまま通り過ぎる可能性があります。
ジェネレーターが過剰になる場合
パッケージが1つで、テストコマンドが1つあり、リポジトリを把握している担当者が2人いるだけなら、20行を手作業で書いてください。20行の AGENTS.md は、ツリー、インデックス、CI チェック、週次ジョブを用意するほど速く陳腐化しません。ビルドを変更したときに読み直せば十分です。これが保守にかかるすべてのコストであり、その周辺の仕組みにかかるコストより小さくなります。
リポジトリの境界やルールを1人で把握しきれない場合は、dox の導入に価値があります。複数のパッケージでルールが異なる場合や、背景知識のないコントリビューターが参加する場合です。価値があるのは生成されたテキストではありません。ドキュメントが、プルリクエストを失敗させる検証対象になることに価値があります。これが、リポジトリ内のファイルを最新の状態に保つ唯一の理由です。
FAQ
dox を使うために何かインストールする必要がありますか?
いいえ。dox は MIT ライセンスの 1 つの Markdown ファイルです。2026 年 8 月 11 日時点で、リポジトリにはパッケージもリリースもありません。内容をプロジェクトの AGENTS.md にコピーすると、コーディングエージェントはそこに記載されたルールに従います。コピーしたコミット(執筆時点では f34ec7ad1055d3393887e5a2670e8cb7320c9165)を固定し、後からどのバージョンのルールを前提にツリーを構築したか確認できるよう、コミットメッセージにその名前を記載してください。
手書きのルールが再生成時に削除されないようにするにはどうすればよいですか?
意図と一覧を分離してください。変更しない理由や設計意図は別のドキュメントに記載し、AGENTS.md 内に残す必要がある内容はマーク付きブロックに入れます。次に、そのブロックを CI で検証します。ブランチと origin/main から sed でブロックを抽出し、diff で比較します。差分があればビルドを失敗させます。大きな差分の中で変更が見過ごされるのではなく、担当者が承認または変更を戻せます。
AGENTS.md はどのくらいの頻度で再生成すべきですか?
AGENTS.md が不正になる変更を行うプルリクエストで再生成します。構造の変更とそのドキュメントは 1 つの差分にまとめてください。その時点でなければ、両方の内容を確認するためのコンテキストが得られないためです。週次のスケジュール実行は、ブランチで見逃したドリフトを検出するための補助です。main に直接コミットせず、プルリクエストを作成してください。
ビルドコマンドはルートの AGENTS.md と子の AGENTS.md のどちらに記載すべきですか?
そのコマンドを管理する最も近いドキュメントに記載します。リポジトリ全体のルールと子のインデックスはルートに置きます。1 つのパッケージにだけ適用されるコマンドは、そのパッケージの AGENTS.md に置きます。dox は距離に基づいて競合を解決します。より近いドキュメントがローカルの詳細を決定し、子のルールで親のルールを弱めることはできません。同じコマンドをすべての子にコピーすると、通常の処理でツリー全体が書き換えられます。
小規模なリポジトリでも dox を使う価値はありますか?
通常はありません。1 つのテストコマンドしかない 1 つのパッケージと、20 行の AGENTS.md であれば、内容はゆっくりしか陳腐化しません。問題に気付いた直後の 1 分で修正できます。リポジトリに異なるルールを持つ複数の境界がある場合や、背景知識を持たないコントリビューターがいる場合は、dox の導入コストに見合います。そのような場合、ドキュメントの連鎖が、1 人の担当者だけでは担えない作業を処理するためです。