doxでAGENTS.mdを自動更新する方法
3週間後にAGENTS.mdが古くなり、エージェントが誤った情報を信じる問題を解決します。doxでリポジトリから再生成し、コードと同じように差分をレビューできます。
3 週間後に AGENTS.md が間違っている理由
AGENTS.md ファイルは、コードと結び付いていないため古くなります。リポジトリが特定の状態だった日に、手作業で 1 回だけ作成するからです。その後、テストランナーが変わり、パッケージ名が変更され、サービスが削除されても、ファイルには 6 月の状態が記載されたままです。ビルド手順でこのファイルを読み込まないため、何も失敗しません。
エージェントはその内容を読み、正しい情報だと判断します。問題はそこにあります。AGENTS.md がないリポジトリでは、コーディングエージェントは操作する前に周囲を確認します。間違った AGENTS.md があるリポジトリでは、すでに答えを持っているため、確認を止めます。ファイルに記載されたコマンドを実行し、シェルが Missing script: "test" と応答すると、エージェントは推測を始めます。多くの場合、ドキュメントで約束したスクリプトを追加するために package.json を編集します。古くなったファイルは、ひそかに失敗したのではありません。望んでいない編集を引き起こしたのです。
dox は、その問題に対する 1 つの解決策です。これはエージェント向けに記述したルールのセットです。作業を完了する際にドキュメントも更新するようにするため、ファイルは、そのファイルを誤った状態にしたコードと同じコミットで変更されます。
dox とは何か、何ではないか
dox は単一の Markdown ファイルです。リポジトリは agent0ai/dox で、MIT ライセンスです。2026 年 8 月 11 日時点で、プロジェクト全体は 3906 バイトの AGENTS.md 1 つ、README、LICENSE、画像 2 つで構成されています。インストールするパッケージもランタイムもありません。
これは重要です。generator という語からは、コードを解析するプログラムを想像しやすいためです。コードを解析するものはありません。dox はコーディングエージェントが読む契約です。generator はエージェントであり、dox は、いつドキュメントを読み、いつ書き換え、各ドキュメントをどの形式にするかを指示する命令セットです。
このファイルには 10 個のセクションがあり、そのうち 2 つが実際の処理を担います。"Read Before Editing" は、エージェントに対して、リポジトリのルートから変更する予定のすべてのパスまでをたどり、その経路上にあるすべての AGENTS.md を、メモリに頼らず、現在のセッションで読むよう指示します。"Update After Editing" は、意味のある変更を行うたびに DOX パスが必要であることを示します。つまり、タスク完了とみなす前にドキュメント更新手順を実行します。目的、構造、ワークフロー、権限、またはユーザー設定が変更された場合、このパスによって最も近い所有ドキュメントが更新されます。
残りは形式を定めています。子 AGENTS.md には、Purpose、Ownership、Local Contracts、Work Guidance、Verification、Child DOX Index という既定のセクション順があります。ルートファイルには、プロジェクト全体に適用するルールとトップレベルの Child DOX Index があります。エージェントはこのインデックスを使って子ドキュメントを見つけます。"Closeout" は、エージェントがタスクの最後に実行するチェックリストです。変更したパスをチェーンと照合し、最も近い所有ドキュメントを更新し、影響を受けるすべてのインデックスを更新し、矛盾を削除し、既存の検証を実行し、意図的に更新しなかったドキュメントを報告します。
main ではなく、1 つのコミットに 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 はこの点を理解しています。dox 自身のルールでは、Work Guidance はプロジェクトの現在の標準またはユーザーの指示を反映する必要があり、それらがまだない場合はセクションを空にすると定めています。Verification は既存のチェックを反映する必要があります。そのため、リポジトリにテストフレームワークがない場合、このセクションはテストフレームワークが導入されるまで空のままにします。標準を作り上げてしまう生成ファイルは、空のセクションよりも問題があります。エージェントが、その作り上げられた標準を強制するようになるためです。
生成インベントリに手書きの意図を混在させない
これは、生成ドキュメントをあきらめる原因になる典型的な失敗です。ジョブキューを単一のコンシューマーに維持する必要があることを段落で説明したとします。3 週間後、パスによってファイルが書き換えられ、その段落が消えます。しかも、ほとんどがファイル名の入れ替えにすぎない 40 行の差分に埋もれるため、誰も気付きません。
2 つの仕組みを使います。どちらも必要です。
まず、永続的な意図を別のファイルに移します。設計上の決定とその理由は、エージェント向けに作成した 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 のコメントはページに表示されませんが、エージェントは読み取れます。次に、このブロックが維持されていることを検証可能にします。パスによってブロックが削除された場合に、明確に失敗させるためです。すべての pull request で、CI(継続的インテグレーション)から次を実行します。
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 で終了します。出力がある場合、パスが人間の管理するテキストを書き換えています。その場合は、人間が承認するか、変更を元に戻します。誰かが覚えておく必要はなく、このチェックだけで維持できます。
プルリクエストで再生成し、タイマーでは実行しない
ドキュメントを更新する最適なタイミングは、そのドキュメントを誤った内容にするコミットの時点です。構造変更と同じプルリクエストに 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 内で失敗しても誰もエラーを確認できません。内容を設定し、スケジュールする前にスクリプトを手動で1回実行してください。|| exit 0 も重要です。ツリーがすでに最新の場合、git commit は nothing to commit, working tree clean で非ゼロの終了ステータスになります。set -e の下では、正常な実行が失敗として報告されます。
処理を実行するたびにトークンを消費します。「Read Before Editing」により、エージェントは各タスクで一連の関連情報全体を読み取るためです。これはトレードオフです。すでにエージェントの実行コストを数えている場合は、コストを監視する価値があります。
モノレポ: 多数のコントラクトを1つのインデックスで管理
40個のパッケージを含むリポジトリで、ルートに1つだけ AGENTS.md を置くと、誰も確認しない再生成差分が発生し、エージェントが現在取り組んでいる内容とはほとんど関係のない文書になります。dox が示す解決策は Child DOX Index です。ルートにはリポジトリ全体のルールと子ファイルへの参照を置き、永続的な境界ごとに専用ファイルを持たせます。このツリーの構成方法と、ネストしたファイルを読み取れるツールについては、モノレポ向けのネストした AGENTS.md ファイルで説明しています。
dox が変えるのは、レビュー対象の範囲です。packages/api に変更を加えるプルリクエストでは、packages/api 内だけにドキュメント差分が発生するはずです。
git diff --stat -- '*AGENTS.md'1つのパッケージだけを変更したのに、そのコマンドで6個のファイルが表示される場合は、ツリーの構成が適切ではありません。境界が粗すぎるか、ルートに置くべきルールをすべての子にコピーしています。dox は修正方法を明確に示します。広範なルールは親の文書に置き、具体的な詳細は子の文書に置きます。ルールが重複していると、通常の処理で全体が書き換えられます。同じルールが複数のリポジトリに本当に適用される場合は別の問題です。その場合は、リポジトリ間でのエージェントスキルの共有のほうが適切なツールです。
差分をコードとしてレビューする
生成されたドキュメントの差分は、読まずに承認しやすいものです。その結果、誤ったファイルがリリースされます。生成コードを確認するときと同じように注意深く読み、次の4点を確認してください。
- ファイルに新しく記載されたコマンド。マージする前に自分で実行してください。存在しないビルド手順の作成は、最も多い失敗です。
- 意図を示していた削除行。追加は容易です。失われるのは削除された内容です。
- 絶対パス、ホスト名、内部 URL、または認証情報に見える文字列
- すでに存在しないもののインベントリ項目。
lsを使えば、すぐに確認できます。
次に、wc -l AGENTS.md でサイズを確認してください。root ファイルが200行を超えている場合は、分割する目安です。このチェーンの価値は、エージェントがすべてを読むのではなく、必要な小さな部分だけを読むことにあるためです。
問題が発生した場合
パスによって intent ブロックが削除された場合。 上の 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 ライセンスの Markdown ファイル 1 つで、2026 年 8 月 11 日時点では、リポジトリにパッケージもリリースもありません。内容をプロジェクトの AGENTS.md にコピーし、コーディングエージェントはそこに記載されたルールに従います。コピーしたコミット(執筆時点では f34ec7ad1055d3393887e5a2670e8cb7320c9165)を固定し、後からツリーがどのバージョンのルールに基づいて構築されたか確認できるよう、コミットメッセージにそのコミットを記載してください。
再生成によって手書きのルールが削除されるのを防ぐにはどうすればよいですか?
意図とインベントリを分けて管理してください。変更されにくい理由や判断は別のドキュメントに記載し、AGENTS.md 内に残す必要がある内容はマーク付きブロックに入れます。その後、CI でブロックを検証します。ブランチと origin/main から sed でそれぞれ抽出し、diff で比較します。差分があればビルドを失敗させます。これにより、大きな差分の中で変更が見落とされることなく、担当者が変更を承認または取り消せます。
AGENTS.md はどのくらいの頻度で再生成すべきですか?
内容が誤る原因となる pull request で再生成してください。構造変更とそのドキュメントは 1 つの差分にまとめます。両方を確認するためのコンテキストを担当者が持てるのは、その時点だけだからです。週次のスケジュール実行は、ブランチで見逃されたドリフトに対する予備策です。main に直接コミットするのではなく、pull request を作成してください。
ビルドコマンドはルートの AGENTS.md と子の AGENTS.md のどちらに記載すべきですか?
そのコマンドを管理する最も近いドキュメントに記載してください。リポジトリ全体のルールと子のインデックスはルートに置きます。1 つのパッケージに適用するコマンドは、そのパッケージの AGENTS.md に置きます。dox は距離に基づいて競合を解決します。近いドキュメントがローカルの詳細を制御し、子のドキュメントが親のルールを弱めることはできません。同じコマンドをすべての子にコピーすると、通常の処理でツリー全体が書き換えられます。
小規模なリポジトリでも dox を使う価値はありますか?
通常はありません。テストコマンドが 1 つだけのパッケージと 20 行の AGENTS.md であれば、内容はゆっくりしか劣化せず、気付いた直後の 1 分で修正できます。リポジトリに異なるルールを持つ複数の境界がある場合や、背景知識を持たないコントリビューターがいる場合は、dox の導入コストに見合います。その場合、ドキュメントの連鎖が、1 人の担当者だけでは担えない作業を代わりに行うためです。