SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor

Garder AGENTS.md à jour automatiquement avec dox

Votre AGENTS.md devient obsolète en trois semaines. Utilisez dox pour le régénérer depuis le dépôt, puis relisez le diff comme du code.

Pourquoi votre AGENTS.md est erroné trois semaines plus tard

Un fichier AGENTS.md devient obsolète parce que rien ne le relie au code. Vous l’écrivez une fois, manuellement, le jour où le dépôt présente une certaine structure. Puis le test runner change, un package est renommé, un service est supprimé, et le fichier décrit toujours l’état du mois de juin. Rien n’échoue, car aucune étape de build ne le lit.

L’agent le lit et lui fait confiance. C’est ce qui vous coûte du temps. Dans un dépôt sans AGENTS.md, un agent de programmation examine le contenu avant d’agir. Dans un dépôt avec un AGENTS.md erroné, il cesse de vérifier, car il a déjà une réponse. Il exécute la commande indiquée dans votre fichier, le shell renvoie Missing script: "test", et l’agent commence alors à deviner. Souvent, il modifie package.json pour ajouter le script promis par votre documentation. Le fichier obsolète n’a pas simplement échoué sans bruit. Il a provoqué une modification que vous ne vouliez pas.

dox est une réponse à ce problème. Il s’agit d’un ensemble de règles rédigées pour l’agent. Elles font de la mise à jour de la documentation une étape du travail à terminer, afin que le fichier soit modifié dans le même commit que le code qui l’a rendu erroné.

Ce que fait dox et ce qu’il ne fait pas

dox est un fichier Markdown unique. Le dépôt est agent0ai/dox, il est distribué sous licence MIT et, au 11 août 2026, le projet complet tient dans un seul AGENTS.md de 3906 octets, un README, un LICENSE et deux images. Aucun package n’est à installer et aucun runtime n’est nécessaire.

C’est important, car le terme generator laisse penser qu’un programme analyse votre code. Rien n’analyse votre code. dox est un contrat que lit votre coding agent : votre agent est le generator, et dox est l’ensemble d’instructions qui lui indique quand lire la documentation, quand la réécrire et quelle forme doit prendre chaque document.

Le fichier comporte dix sections, dont deux assurent l’essentiel du fonctionnement. « Read Before Editing » indique à l’agent de parcourir, depuis la racine du dépôt, chaque chemin qu’il prévoit de modifier et de lire chaque AGENTS.md rencontré sur ces chemins, pendant la session en cours, sans s’appuyer sur sa mémoire. « Update After Editing » lui indique que toute modification significative nécessite un passage DOX, c’est-à-dire une étape de mise à jour de la documentation à exécuter avant de considérer la tâche comme terminée. Ce passage met à jour le document propriétaire le plus proche lorsque la finalité, la structure, le workflow, les permissions ou les préférences utilisateur ont changé.

Le reste concerne la structure. Un AGENTS.md enfant suit un ordre de sections par défaut : Purpose, Ownership, Local Contracts, Work Guidance, Verification et Child DOX Index. Le fichier racine contient les règles applicables à l’ensemble du projet ainsi que le Child DOX Index de niveau supérieur, qui permet à un agent de découvrir les documents enfants. « Closeout » est la checklist exécutée par l’agent à la fin d’une tâche : revérifier les chemins modifiés par rapport à la chaîne, mettre à jour les documents propriétaires les plus proches, actualiser chaque index concerné, supprimer les contradictions, exécuter les vérifications existantes et indiquer quels documents il a délibérément laissés inchangés.

Épinglez dox sur un commit, pas sur main

Le dépôt n’a ni tags ni releases : il n’existe donc aucun numéro de version à épingler. Épinglez plutôt le commit. Le fichier AGENTS.md actuel correspond au commit f34ec7ad1055d3393887e5a2670e8cb7320c9165, daté du 1 août 2026.

mkdir -p .agent
curl -fsSL -o .agent/dox-f34ec7a.md \
  https://raw.githubusercontent.com/agent0ai/dox/f34ec7ad1055d3393887e5a2670e8cb7320c9165/AGENTS.md
wc -c .agent/dox-f34ec7a.md

wc -c doit afficher 3906. Un autre numéro signifie que vous n’avez pas récupéré le fichier décrit par ce guide. Lisez-le avant de lui faire confiance. Si vous saisissez mal le hash du commit, -f fait arrêter curl avec curl: (22) The requested URL returned error: 404 et n’écrit aucun contenu. wc -c affiche alors 0. Un fichier tronqué est pire qu’une absence de fichier, car l’agent applique la moitié d’un contrat sans le savoir.

cp .agent/dox-f34ec7a.md AGENTS.md
git add AGENTS.md .agent/dox-f34ec7a.md
git commit -m "Add DOX rules (agent0ai/dox @ f34ec7a)"

Ce cp concerne un dépôt qui ne contient pas encore de fichier AGENTS.md. Si vous en avez déjà un, ne l’écrasez pas. Placez les sections dox au-dessus de votre contenu existant, conservez vos propres règles en dessous, puis lisez le résultat une fois de haut en bas. Deux documents contradictoires produisent un agent qui applique la dernière règle qu’il a lue.

Demandez ensuite à votre agent d’effectuer le premier passage depuis le dépôt. Le README fournit la formulation exacte :

Initialize DOX tree for this project now.

Il crée les fichiers AGENTS.md enfants et les index qui pointent vers eux. Vérifiez ce qu’il a fait avant de lui faire confiance :

git status --short
find . -name AGENTS.md -not -path './.git/*' | sort

Chaque fichier de cette sortie find doit apparaître quelque part au-dessus de lui dans un Child DOX Index. Un document enfant qui n’est mentionné par aucun index peut être ignoré par l’agent, car l’index lui permet de trouver les documents qui ne se trouvent pas directement sur le chemin qu’il parcourt.

Ce que dox peut voir et ce qu’il ne peut pas savoir

L’agent qui construit votre arborescence lit le dépôt. Tout ce qui s’y trouve peut donc être ajouté à l’inventaire : l’organisation des répertoires, les manifestes de paquets et les lockfiles, les scripts dans package.json, Makefile ou pyproject.toml, les fichiers de workflow CI, les Dockerfiles, les points d’entrée et CODEOWNERS si vous en avez un. Un inventaire construit à partir de ces éléments s’auto-maintient réellement. Lorsqu’un paquet est déplacé, le passage suivant déplace la ligne qui le décrit.

Tout ce qui suit doit être indiqué par vous, car ces informations ne se trouvent pas dans le dépôt :

  • la raison d’être d’une règle, ce qui empêche un agent de la supprimer en la considérant comme une complexité inutile
  • lequel de deux chemins fonctionnels est pris en charge et lequel doit encore être supprimé
  • tout ce qui se trouve en dehors du dépôt, comme l’environnement de staging ou la raison pour laquelle une dépendance est épinglée à deux versions en arrière
  • ce que vous prévoyez de faire la semaine prochaine, car c’est ce qui distingue un fichier à jour d’un fichier utile

dox le sait à son propre sujet. Ses propres règles indiquent que Work Guidance doit refléter les standards actuels du projet ou les instructions de l’utilisateur. S’il n’en existe pas encore, cette section doit rester vide. Verification doit refléter un contrôle existant. En l’absence de test framework dans le dépôt, cette section reste donc vide jusqu’à ce qu’il y en ait un. Un fichier généré qui invente un standard est pire qu’une section vide, car l’agent appliquera ensuite cette invention.

Ne mélangez pas les intentions rédigées manuellement avec l’inventaire généré

C’est le problème qui fait abandonner la documentation générée. Vous rédigez un paragraphe expliquant que la file d’attente des tâches doit rester utilisée par un seul consommateur. Trois semaines plus tard, une passe réécrit le fichier et votre paragraphe disparaît dans un diff de quarante lignes qui réorganisent surtout des noms de fichiers. Personne ne le remarque.

Deux mécanismes sont nécessaires, et vous devez utiliser les deux.

Tout d’abord, placez les intentions durables dans un autre fichier. Les décisions d’architecture et leur justification doivent figurer dans un DESIGN.md rédigé pour l’agent, tandis que les notes destinées aux personnes doivent se trouver là où vous séparez HUMAN.md de AGENTS.md. AGENTS.md contient alors l’inventaire et les contrats locaux. C’est précisément la partie qui doit changer lorsque le code évolue.

Ensuite, protégez les intentions qui doivent rester dans AGENTS.md. Entourez-les de marqueurs et considérez le bloc comme géré par les personnes :

## 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 -->

Les commentaires Markdown ne sont pas affichés sur la page, mais l’agent les lit toujours. Rendez maintenant la conservation du bloc vérifiable, afin qu’une passe qui le supprime échoue explicitement. Exécutez ceci dans la CI (intégration continue) pour chaque pull request :

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.head

diff n’affiche rien et renvoie 0 lorsque le bloc n’a pas été modifié. Toute sortie signifie que la passe a réécrit du texte géré par les personnes. Une personne doit alors l’approuver ou l’annuler. Le contrôle fonctionne sans que personne ait besoin de s’en souvenir.

Régénérez lors de la pull request, pas selon un calendrier

Le meilleur moment pour actualiser un document est celui du commit qui le rend incorrect. Ajoutez l’exécution de DOX à la même pull request que la modification structurelle. Le diff reste ainsi suffisamment court pour être réellement relu.

Voici un contrôle bloquant qui impose cette règle :

#!/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

Adaptez les chemins à votre dépôt. L’intérêt est que le contrôle échoue sur la branche, là où la correction est peu coûteuse, et pour une raison sur laquelle un reviewer peut agir.

La planification est une solution de secours, pas le mécanisme principal. Une tâche hebdomadaire détecte ce que personne n’a remarqué sur une branche : des fichiers déplacés par un rebase, un paquet supprimé lors d’un merge ou un document qui référence un répertoire qui n’existe plus. Exécutez-la sur une petite machine, la même que celle que vous pourriez utiliser pour exécuter un agent de codage sur un VPS, et faites-lui ouvrir une pull request au lieu de pousser vers main.

#!/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

Ce commentaire est volontairement un placeholder. Chaque agent possède sa propre CLI (interface de ligne de commande) et son propre flag non interactif. Une commande copiée depuis une page web qui ne correspond pas à votre version échoue dans cron, sans que personne ne voie l’erreur. Complétez-la, puis exécutez le script manuellement une fois avant de planifier son exécution. Le || exit 0 est également important : git commit retourne un code différent de zéro avec nothing to commit, working tree clean lorsque l’arborescence est déjà à jour. Avec set -e, cela signalerait à tort une exécution réussie comme un échec.

Chaque exécution consomme des tokens, car « Read Before Editing » oblige l’agent à lire toute la chaîne à chaque tâche. C’est le compromis à accepter. Il vaut la peine de le surveiller si vous suivez déjà le coût des exécutions de votre agent.

Monorepos : plusieurs contrats, un seul index

Un fichier AGENTS.md à la racine d’un dépôt contenant quarante packages produit un diff de régénération que personne ne lit, ainsi qu’un document largement sans rapport avec la tâche que l’agent exécute actuellement. La solution dox est le Child DOX Index : la racine contient les règles communes au dépôt et pointe vers ses enfants, tandis que chaque frontière durable possède son propre fichier. La structure de cette arborescence et les outils qui lisent réellement les fichiers imbriqués sont présentées dans les fichiers AGENTS.md imbriqués pour les monorepos.

dox modifie la surface de revue. Une pull request qui touche packages/api doit produire un diff de documentation dans packages/api, et nulle part ailleurs :

git diff --stat -- '*AGENTS.md'

Si cette commande liste six fichiers pour une modification limitée à un package, l’arborescence est incorrecte. Les frontières sont soit trop larges, soit une règle qui devrait se trouver dans la documentation racine a été copiée dans chaque enfant. dox énonce directement la correction : les règles générales vont dans les documents parents, et les détails concrets dans les documents enfants. Ce sont les règles dupliquées qui font qu’un passage courant réécrit tout. Si les mêmes règles s’appliquent réellement à plusieurs dépôts distincts, il s’agit d’un autre problème ; partager des compétences d’agent entre dépôts est alors l’outil le mieux adapté.

Relisez le diff comme du code

Un diff de documentation généré est facile à approuver sans le lire. C’est ainsi qu’un fichier incorrect est publié. Lisez-le avec la même vigilance que du code généré et recherchez quatre éléments.

  • une commande désormais indiquée dans le fichier, que vous devez exécuter vous-même avant la fusion. Les instructions de build inventées sont l’erreur la plus fréquente ;
  • une ligne supprimée qui exprimait une intention. Les ajouts coûtent peu. C’est dans les suppressions que se produit la perte d’information ;
  • un chemin absolu, un hostname, une URL interne ou toute chaîne qui ressemble à un identifiant ;
  • une entrée d’inventaire correspondant à un élément qui n’existe plus, ce que ls permet de vérifier en une seconde.

Vérifiez ensuite la taille avec wc -l AGENTS.md. Un fichier racine de plus de deux cents lignes doit généralement être découpé. Toute la valeur de cette chaîne repose sur le fait que l’agent lit uniquement la partie pertinente, et non l’ensemble du contenu.

En cas de problème

Le pass a supprimé votre bloc d’instructions. Le contrôle diff ci-dessus affiche les lignes supprimées. Restaurez le fichier depuis le point de branchement avec git restore --source=origin/main AGENTS.md, puis relancez le pass avec une instruction plus ciblée qui indique les sections qu’il peut modifier.

Deux branches ont toutes deux régénéré le fichier. Vous obtenez CONFLICT (content): Merge conflict in AGENTS.md et des marqueurs de conflit <<<<<<< HEAD dans le fichier. Ne modifiez pas ces marqueurs manuellement. Le fichier est généré ; la résolution correcte consiste à exécuter un nouveau pass sur l’arborescence fusionnée.

L’agent ignore complètement le fichier. Vérifiez le nom de fichier réellement lu par votre outil. S’il en lit un autre, faites-le pointer vers le même contenu avec ln -s AGENTS.md CLAUDE.md et validez le lien symbolique. Vous conservez ainsi une seule source au lieu de deux documents qui divergent.

L’arborescence contient de nouveaux enfants que personne n’a indexés. Comparez la sortie de find . -name AGENTS.md avec les entrées d’index des documents parents. Un enfant qui n’est mentionné dans aucun index est un enfant que l’agent peut parcourir sans le voir.

Quand un générateur est excessif

Un seul package, une seule commande de test et deux personnes qui connaissent toutes les deux le repository : écrivez les vingt lignes à la main. Un fichier AGENTS.md de vingt lignes ne se dégrade pas assez vite pour justifier un arbre, un index, un contrôle CI et une tâche hebdomadaire. Relisez-le lorsque vous modifiez le build. C’est tout le coût de maintenance, et il est inférieur à celui de la machinerie qui l’entoure.

dox vaut la peine lorsque le repository comporte des limites que personne ne peut garder entièrement en tête : plusieurs packages avec des règles différentes, ou des contributeurs qui arrivent sans connaître le contexte. La valeur ne réside pas dans le texte généré. Elle réside dans le fait que la documentation devient un élément sur lequel une pull request peut échouer, ce qui est la seule raison pour laquelle un fichier d’un repository reste à jour.

FAQ

Dois-je installer quelque chose pour utiliser dox ?

Non. dox est un fichier Markdown sous licence MIT et, au 11 août 2026, le repository ne contient aucun package ni aucune release. Copiez son contenu dans le fichier AGENTS.md de votre projet : votre coding agent appliquera ensuite ces règles. Épinglez le commit copié, f34ec7ad1055d3393887e5a2670e8cb7320c9165 au moment de la rédaction, et indiquez-le dans votre message de commit. Vous pourrez ainsi identifier ultérieurement la version des règles utilisée pour construire votre arborescence.

Comment empêcher une régénération de supprimer mes règles écrites manuellement ?

Séparez l’intention de l’inventaire. Placez le raisonnement durable dans un document distinct, et tout ce qui doit rester dans AGENTS.md dans un bloc marqué. Vérifiez ensuite ce bloc dans la CI : extrayez-le de la branche et de origin/main avec sed, comparez les deux avec diff, puis faites échouer le build en cas de différence. Une personne approuve ou rétablit alors la modification, au lieu de la laisser passer inaperçue dans un diff volumineux.

À quelle fréquence dois-je régénérer AGENTS.md ?

Lors de la pull request qui le rend incorrect. Une modification structurelle et sa documentation doivent figurer dans le même diff, car c’est le seul moment où quelqu’un dispose du contexte nécessaire pour examiner les deux. Une exécution planifiée hebdomadaire sert de secours pour détecter la dérive qui a échappé à une branche. Elle doit ouvrir une pull request au lieu de committer directement dans main.

Les commandes de build doivent-elles figurer dans l’AGENTS.md racine ou dans un fichier enfant ?

Dans le document le plus proche qui les définit. Les règles applicables à tout le repository et l’index enfant se trouvent à la racine. Une commande qui s’applique à un seul package figure dans l’AGENTS.md de ce package. dox résout les conflits selon la distance : le document le plus proche contrôle les détails locaux, et aucun enfant ne peut assouplir une règle parente. Copier la même commande dans chaque enfant force une exécution courante à réécrire toute l’arborescence.

dox est-il utile pour un petit repository ?

Généralement non. Un package avec une seule commande de test et un AGENTS.md de vingt lignes évolue lentement, et vous pouvez le corriger dans la minute qui suit sa détection. dox justifie son coût lorsque le repository comporte plusieurs périmètres soumis à des règles différentes ou des contributeurs qui ne disposent pas du contexte nécessaire. La chaîne de documents accomplit alors un travail qu’aucune personne ne prend en charge seule.