Mettre plusieurs sites dans un même dépôt, déposer des règles pour l’IA (CLAUDE.md ou AGENTS.md) dans le dossier de chaque site, et l’IA suivra les règles de ce site : c’est ce qu’on suppose naturellement, mais ni Claude Code ni Codex ne lisent « toujours » les règles des dossiers inférieurs. Lancé depuis la racine du dépôt, Claude Code ne les charge qu’au moment où il touche des fichiers de ce dossier, et Codex ne les charge pas automatiquement (l’IA peut les ouvrir d’elle-même, mais rien ne le garantit). Cet article compare, point par point et d’après la documentation officielle des deux outils, quand ces fichiers sont chargés et comment vérifier qu’ils l’ont été, puis montre comment faire respecter les règles par des vérifications automatiques plutôt que par des documents. Il s’appuie sur ce que nous avons appris en concevant cette organisation dans un environnement où des agents IA gèrent l’exploitation des serveurs et plusieurs projets.

Quand les règles du dossier de chaque site sont-elles chargées ? (lancement depuis la racine du dépôt)

repo/ ├─ CLAUDE.md, AGENTS.md ← règles de tout le dépôt └─ sites/ ├─ blog/CLAUDE.md, AGENTS.md ← règles de blog ├─ shop/CLAUDE.md, AGENTS.md ← règles de shop └─ shared/ ← composants partagés

Claude Code

  • Au démarrageLe CLAUDE.md de la racine
  • Au contactCharge le CLAUDE.md de blog quand il lit, écrit ou modifie un fichier de sites/blog/
  • Pas encoreLes règles d’un dossier qu’il n’a pas encore touché (shop) ne sont pas chargées

Codex

  • Au démarrageL’AGENTS.md de la racine
  • Non garantiL’AGENTS.md de sites/blog/ n’est pas chargé automatiquement (Codex ne cherche pas sous le dossier de lancement)
  • Non garantiL’AGENTS.md de sites/shop/ (idem)

Lancez donc le travail sur un site depuis le dossier de ce site, et ne comptez pas sur des documents pour ce qui doit être imposé. Mettez en place une vérification automatique qui « arrête la mise en production si quoi que ce soit a changé hors du dossier attribué », et définissez le périmètre de chaque agent par un réglage propre à chaque worktree. Gardez les documents de règles pour expliquer à l’IA les raisons et les étapes.

Sources : How Claude remembers your project d’Anthropic et Custom instructions with AGENTS.md d’OpenAI (vérifiés le 1er novembre 2026).

1. Ce que nous a appris le placement des règles dans le dossier de chaque site

Dans un environnement où des agents IA gèrent l’exploitation des serveurs et plusieurs sites, nous avons envisagé de mettre plusieurs sites dans un même dépôt et de placer les règles de chaque site dans son dossier (les détails qui permettraient d’identifier des lieux ou des noms sont omis, et le contenu technique est généralisé). L’objectif était une répartition des rôles : l’IA chargée de blog ne lit que les règles de blog et ne touche jamais à shop.

Mais en consultant la documentation officielle des deux outils, nous avons constaté que rien ne garantit que les règles placées soient chargées avant le début du travail. Les règles chargées dépendent du dossier depuis lequel on lance l’outil. De plus, la documentation de Claude Code présente CLAUDE.md comme du contexte, et non comme une configuration imposée. Même chargées, rien ne garantit que les règles seront suivies.

  1. !

    Placer des règles dans des dossiers ne suffit pas à répartir les responsabilités

    Risque
    Une IA lancée à la racine modifie des fichiers sans avoir lu les règles de ce site, ou avant de les lire
    Parade
    Lancer le travail sur un site depuis le dossier du site, et bloquer les modifications hors périmètre par une vérification avant mise en production (section 4)
    Contrôle
    Confirmer avec les outils quelles règles ont été chargées (section 3), et modifier volontairement quelque chose hors périmètre pour voir si la mise en production s’arrête

Les causes générales pour lesquelles l’IA ignore les règles, et leurs remèdes, sont traitées dans « Pourquoi les agents IA ignorent les règles .md : vérifier le chargement et les résultats avec Hooks et CI ». Cet article se concentre sur ce qui se passe quand on répartit les règles entre plusieurs dossiers. Deux autres mises en garde issues du même environnement, sur le fait de confier plusieurs dépôts à une IA, figurent en section 5.

2. Quand les règles par dossier sont-elles chargées ?

Le chargement des règles du dossier de chaque site dépend du dossier depuis lequel vous lancez l’outil et de l’outil utilisé. Voici, côte à côte, ce que dit la documentation officielle des deux outils.

PointClaude CodeCodex
Chargé au démarrageTous les CLAUDE.md et CLAUDE.local.md du dossier de lancement (launch directory) et de tous les dossiers au-dessusDe la racine du projet (project root, en général la racine git) jusqu’au dossier de lancement, un fichier par dossier : AGENTS.override.md, sinon AGENTS.md
Sous le dossier de lancementPas chargé au démarrage ; chargé quand Claude lit, écrit ou modifie un autre fichier de ce dossierPas chargé automatiquement (la recherche s’arrête au dossier de lancement ; l’IA peut les ouvrir d’elle-même)
Ajout en cours de session ?Oui (les règles des dossiers touchés s’ajoutent ensuite)Non (construit une fois au début de chaque exécution)
Limites de tailleMoins de 200 lignes par fichier est le repère (les fichiers plus longs sont moins bien suivis) ; pour les CLAUDE.md des dossiers inférieurs, tout ce qui dépasse 40 000 caractères par fichier (avec un contexte de 200K tokens) est coupé, et seul le début est transmisPlus rien n’est ajouté une fois le total au-delà de 32 KiB (valeur par défaut de project_doc_max_bytes)
Le fichier de règles de l’autre outilLit AGENTS.md quand il n’y a ni CLAUDE.md, ni .claude/CLAUDE.md, ni CLAUDE.local.md dans le dossier de lancement ou au-dessus (par défaut)Ne lit pas CLAUDE.md (seuls les noms ajoutés à project_doc_fallback_filenames sont lus)

Sources : How Claude remembers your project et Monorepos and large repos d’Anthropic, et Custom instructions with AGENTS.md d’OpenAI (vérifiés le 1er novembre 2026). La limite de Claude Code pour les dossiers inférieurs s’applique à partir de la v2.1.309. Avec un contexte de 1M tokens, elle est de 150 000 caractères (200 000 pour Opus 4.6 et Sonnet 4.6). Claude Code lit directement AGENTS.md à partir de la v2.1.277 ; un AGENTS.md d’un dossier inférieur est lu quand ce dossier n’a pas de CLAUDE.md et que Claude y ouvre un fichier avec l’outil Read. Pour que les deux soient lus, réglez Project instructions sur claude-md-and-agents-md dans /config.

Le dossier de lancement change les règles chargées

Dans un même dépôt, le résultat dépend de l’endroit d’où vous lancez l’outil. Lancez-le depuis le dossier d’un site, et les deux outils lisent les règles de ce site dès le départ.

Lancé depuisClaude CodeCodex
La racine du dépôtSeulement les règles de la racine ; les règles de chaque site s’ajoutent quand Claude touche les fichiers de ce siteSeulement les règles de la racine ; les règles des sites ne sont pas chargées automatiquement
sites/blog/Lit au démarrage les règles de blog et de la racine (modifier des fichiers hors du dossier de lancement demande une approbation)Lit la racine, puis blog ; les règles de shop ne sont pas sur le chemin, donc pas chargées automatiquement

Le point facile à manquer, c’est ce qui compte comme « toucher » dans « chargé au contact ». Ce que la documentation de Claude Code compte comme lecture, c’est lire, écrire ou modifier un fichier avec ses outils, ainsi que les commandes qui affichent un seul fichier, comme cat ou head. Les opérations qui modifient des fichiers autrement, comme un rechercher-remplacer en masse sur les dossiers de plusieurs sites, ne figurent pas dans cette liste. Les fichiers d’un site peuvent donc changer avant que ses règles soient lues.

Dans Codex, si vous lancez depuis la racine du dépôt et demandez de « corriger blog et shop », aucun des AGENTS.md des sites n’est chargé automatiquement. La documentation indique que Codex arrête sa recherche en atteignant le dossier de travail courant ; les règles d’un dossier inférieur ne sont donc incluses de façon sûre au démarrage que si vous lancez depuis ce dossier ou plus bas.

Cela dit, les instructions par défaut (base_instructions/default.md) du dépôt Codex demandent en substance au modèle de vérifier les AGENTS.md applicables quand il travaille sous le dossier de travail courant ou en dehors. L’IA peut ouvrir d’elle-même l’AGENTS.md d’un site, mais cela relève de son jugement, non d’une garantie du mécanisme de chargement.

Les fichiers de réglages par dossier s’héritent aussi différemment

Au-delà des documents de règles, les outils diffèrent aussi dans la façon dont ils traitent les dossiers pour les fichiers de réglages, comme les permissions.

PointClaude CodeCodex
Fichier de réglages du projet.claude/settings.json.codex/config.toml
Fichier de quel dossier est luCelui du dossier de lancement (primary working directory) ; contrairement à CLAUDE.md, il n’est pas hérité des dossiers parentsDe la racine du projet jusqu’au dossier de lancement (le plus proche l’emporte)
Lien avec la confiance (trust)Les règles comme allow prennent effet une fois le dossier approuvé ; deny et ask prennent effet immédiatementNe lit .codex/ que dans les projets approuvés

Sources : Claude Code settings et Monorepos and large repos d’Anthropic, et Config basics d’OpenAI (vérifiés le 1er novembre 2026).

3. Vérifier que les règles ont été chargées

Une fois les règles en place, vérifiez après le lancement qu’elles ont bien été chargées. La méthode diffère selon l’outil, et dans Claude Code on ne regarde pas au même endroit pour les règles chargées au démarrage et celles chargées ensuite.

À vérifierClaude CodeCodex
Règles chargées au démarrageLa liste Memory files de /contextDemander « Montre-moi quels fichiers d’instructions sont actifs. » (c’est le compte rendu de l’IA elle-même ; pour une certitude, utilisez le journal ci-dessous)
Règles chargées en cours de sessionAbsentes de Memory files ; quand l’une est chargée, une ligne Loaded avec son chemin s’affiche dans le terminalAucune ne s’ajoute en cours de session (idem)
Garder une traceUtiliser le hook InstructionsLoaded pour journaliser quelles règles ont été chargées, quand et pourquoi (il ne se déclenche pas pour un AGENTS.md lu directement)Lancer codex -c log_dir=./.codex-log pour écrire le journal du TUI (./.codex-log/codex-tui.log) et voir quelles règles ont été chargées

Sources : la section de dépannage de How Claude remembers your project d’Anthropic et « Verify your setup » dans Custom instructions with AGENTS.md d’OpenAI (vérifiés le 1er novembre 2026). Ajoutez le dossier du journal au .gitignore pour le garder hors de git.

Pour tester dans Claude Code un nouveau fichier de règles placé dans un dossier inférieur, suivez le conseil de la documentation : créez le fichier de règles dans le shell plutôt que de le faire écrire par l’IA, puis faites lire à l’IA un fichier de ce dossier et regardez si une ligne Loaded apparaît.

4. Imposer les règles par des vérifications automatiques, pas par des documents

Comme l’a montré la section 2, les règles placées dans des dossiers peuvent ne pas être chargées selon le dossier de lancement et l’outil utilisé. Et même chargées, rien ne garantit qu’elles soient suivies. Pensez donc l’application des règles en trois couches.

Documents de règles
Expliquer les raisons et les étapes CLAUDE.md et AGENTS.md. Ils peuvent ne pas être chargés, et même chargés, rien ne garantit qu’ils soient suivis. L’IA en a pourtant besoin pour comprendre pourquoi quelque chose s’est arrêté
Garde-fous de l’outil
Arrêter une action avant qu’elle ait lieu Les hooks et les réglages de permissions de l’outil d’IA (appelés « garde-fous de l’outil » dans cet article). Chaque outil les configure différemment, et ils peuvent ne pas s’appliquer selon le dossier de lancement et les réglages de confiance
Vérification avant mise en production
Le dernier verrou, quel que soit l’outil qui a fait le travail Si quoi que ce soit a changé hors du dossier attribué, le processus de mise en production lui-même s’arrête. Cela ne dépend pas de l’outil d’IA

Dans cet environnement, nous avons fait de la couche du bas, la vérification avant mise en production, la protection décisive. Que l’on change d’outil d’IA ou qu’une personne fasse le travail elle-même, tout passe par la même vérification.

Définir le périmètre de chaque agent par un réglage propre au worktree

Donnez à chaque site son propre worktree (git worktree), et placez en haut du worktree un petit fichier de réglages (.agent-owner) qui liste les dossiers que l’agent qui y travaille peut modifier. Si vous écriviez le périmètre dans un document de règles du dépôt, il serait identique dans tous les worktrees et ne pourrait pas varier selon l’emplacement. Gardez ce fichier hors de git (ajoutez-le à .git/info/exclude), et écrivez-le au moment de créer le worktree.

Notez que l’IA se lance non pas depuis le haut du worktree, mais depuis le dossier du site à l’intérieur. Le haut du worktree équivaut à la racine du dépôt ; y lancer l’IA donne le même résultat que « la racine du dépôt » en section 2.

# Depuis le checkout principal (/srv/repo), créer un worktree pour sites/blog dans /srv/work-blog
cd /srv/repo
git worktree add /srv/work-blog -b blog-work
printf 'sites/blog/\n' > /srv/work-blog/.agent-owner
echo '.agent-owner' >> .git/info/exclude

# Lancer l'IA depuis sites/blog/ à l'intérieur du worktree
cd /srv/work-blog/sites/blog
claude        # ou codex pour Codex

# Avant la mise en production, lancer la vérification du checkout principal, en haut du worktree
cd /srv/work-blog
bash /srv/repo/tools/check-owner.sh origin/main

Lancez le script de vérification depuis le checkout principal (où l’IA ne travaille pas) ou depuis la CI, et non la copie présente dans le worktree. Si vous lancez la copie du worktree, une IA qui réécrirait le script de vérification lui-même passerait sans encombre.

Arrêter la mise en production quand quelque chose change hors du périmètre

Placez la vérification suivante (tools/check-owner.sh ci-dessus) au début du processus de mise en production. Elle suppose que les mises en production ne se font qu’à partir de commits : elle s’arrête s’il reste des modifications non commitées, et elle s’arrête si le diff commité depuis la base (origin/main ou équivalent) contient ne serait-ce qu’un fichier hors des dossiers attribués. Elle lit .agent-owner ; lancez-la donc en haut du worktree.

#!/usr/bin/env bash
# À lancer en haut du worktree avant la mise en production : arrêter si quelque chose a changé hors des dossiers attribués
set -euo pipefail

base="${1:-origin/main}"
owner_file=".agent-owner"   # en haut du worktree, hors de git

if [ ! -s "$owner_file" ]; then
  echo "Aucun fichier de périmètre ($owner_file). Mise en production arrêtée" >&2
  exit 1
fi

# Arrêter s'il reste des modifications non commitées (mise en production uniquement à partir de commits)
if [ -n "$(git status --porcelain)" ]; then
  echo "Des modifications ne sont pas commitées. Mise en production arrêtée" >&2
  exit 1
fi

# --no-renames : compter un déplacement depuis un autre dossier comme une suppression plus un ajout
# Ajouter un / final à chaque entrée du périmètre (pour que sites/blog ne corresponde pas à sites/blog-old)
# Testé avec gawk (Git Bash). awk BSD peut échouer si une valeur -v contient des retours à la ligne
outside=$(git diff --name-only --no-renames "$base"...HEAD |
  awk -v list="$(tr -d '\r' < "$owner_file")" '
    BEGIN { n = split(list, own, "\n")
            for (i = 1; i <= n; i++) if (own[i] != "" && substr(own[i], length(own[i])) != "/") own[i] = own[i] "/" }
    { ok = 0; for (i = 1; i <= n; i++) if (own[i] != "" && index($0, own[i]) == 1) ok = 1
      if (!ok) print }')

if [ -n "$outside" ]; then
  echo "Des fichiers hors du périmètre ont changé. Mise en production arrêtée :" >&2
  echo "$outside" >&2
  exit 1
fi
echo "Modifications dans le périmètre uniquement"

Voici les résultats obtenus quand Claude Code, qui a rédigé cet article, a construit un dépôt de test avec deux sites et un dossier partagé, et lancé la vérification le 1er novembre 2026, avec Git 2.56 (Git Bash sous Windows).

Ce que nous avons essayéRésultat
L’agent de blog n’a modifié que des fichiers de blogPasse
Déplacé un fichier de shop dans le dossier de blogS’arrête (le fichier d’origine de shop est listé)
Modifié un fichier du dossier partagéS’arrête (le dossier partagé est hors périmètre s’il n’est pas listé)
Écrit le périmètre sans / final et ajouté sites/blog-old/S’arrête (une version qui n’ajoutait pas le / le laissait passer)
Laissé des modifications non commitées dans shopS’arrête (une version qui ne vérifie que le diff commité ne le voit pas)
Supprimé le fichier de périmètreS’arrête

C’est --no-renames qui empêche les déplacements de passer à travers. Sans lui, git ne liste une modification qu’il considère comme un déplacement que sous le nom de destination ; un changement qui rapatrie des fichiers d’un autre site passe alors inaperçu. La vérification « s’arrête » aussi plutôt que de « passer » quand le fichier de réglages manque, afin qu’un worktree dont le périmètre n’a jamais été défini ne passe pas.

Cette vérification évite les confusions, pas les violations délibérées. Si l’IA réécrit .agent-owner, la vérification passe. Pour l’éviter aussi, interdisez également la modification de ce fichier de réglages avec les garde-fous de l’outil ci-dessous.

Ajouter les garde-fous de l’outil

N’arrêter qu’avant la mise en production, c’est s’en apercevoir après que l’IA a déjà réécrit quelque chose hors périmètre. Pour l’arrêter avant l’écriture, ajoutez les fonctions propres aux outils.

PointClaude CodeCodex
Bloquer l’écriture de fichiersAjouter Edit(chemin) à deny dans les réglages de permissions (s’applique aux outils intégrés et aux commandes que Claude Code reconnaît, comme sed, tee et les redirections)Dans un hook PreToolUse, examiner où écrit apply_patch (qui correspond aussi à Edit et Write), et renvoyer deny comme permissionDecision
Bloquer des commandesAjouter Bash(commande *) à deny, ou renvoyer le code de sortie 2 ou un JSON de refus depuis un hook PreToolUseLa règle prefix_rule(pattern=[...], decision="forbidden") (expérimentale) et les hooks PreToolUse
Bloquer tous les processusLe sandbox (deny n’arrête pas un script qui ouvre et écrit lui-même des fichiers)Le sandbox (sandbox_mode = "workspace-write" limite l’écriture au dossier de lancement ; les writable roots ajoutent des emplacements accessibles en écriture, n’en ajoutez donc pas à la légère)
Conditions quand ils sont placés dans le projetLit le .claude/settings.json du dossier de lancement ; deny s’applique même avant que vous approuviez le dossierNe lit le .codex/ du projet que si le projet est approuvé ; les hooks ne s’exécutent pas tant que vous ne les avez pas examinés et approuvés

Sources : Configure permissions et Hooks guide d’Anthropic, et Hooks et Rules d’OpenAI (vérifiés le 1er novembre 2026).

Dans Claude Code, des réglages qui empêchent le worktree de blog de modifier le fichier de périmètre (.agent-owner), les scripts de vérification (tools/), les règles de la racine, shop et le dossier partagé ressemblent à ceci (en supposant que le worktree se trouve dans /srv/work-blog). Les chemins qui commencent par // sont des chemins absolus. L’emplacement des worktrees varie d’une machine à l’autre ; ajoutez donc ces règles aux réglages utilisateur de cette machine (~/.claude/settings.json) au moment de créer le worktree, et non aux réglages versionnés dans le dépôt.

{
  "permissions": {
    "deny": [
      "Edit(//srv/work-blog/.agent-owner)",
      "Edit(//srv/work-blog/tools/**)",
      "Edit(//srv/work-blog/CLAUDE.md)",
      "Edit(//srv/work-blog/AGENTS.md)",
      "Edit(//srv/work-blog/sites/shop/**)",
      "Edit(//srv/work-blog/sites/shared/**)",
      "Edit(//srv/repo/**)"
    ]
  }
}

Dans Codex, enregistrez le script de vérification sous PreToolUse dans la configuration des hooks (votre ~/.codex/hooks.json personnel, le .codex/hooks.json du dépôt, ou équivalent), avec apply_patch comme matcher. Les hooks ne s’exécutent pas tant que vous ne les avez pas examinés et approuvés avec /hooks dans Codex (si vous les modifiez, il faut les approuver de nouveau).

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "^apply_patch$",
        "hooks": [ { "type": "command", "command": "python3 ~/.codex/hooks/owner_guard.py" } ] }
    ]
  }
}

Le script de vérification extrait les chemins visés des lignes *** Add File:, *** Update File:, *** Delete File: et *** Move to: de l’entrée d’apply_patch, et renvoie deny si l’un d’eux est hors périmètre ou protégé. Voici un exemple minimal.

import json, posixpath, re, sys

# Hook PreToolUse de Codex : arrêter apply_patch s'il modifie des fichiers hors périmètre ou protégés
OWN = ["/srv/work-blog/sites/blog/"]                  # périmètre (avec le / final)
PROTECT = ["/srv/work-blog/.agent-owner", "/srv/work-blog/tools/"]

event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")
if isinstance(command, list):
    command = "\n".join(command)

bad = []
for m in re.finditer(r"^\*\*\* (?:Add File|Update File|Delete File|Move to): (.+)$", command, re.M):
    path = posixpath.normpath(posixpath.join(event.get("cwd", ""), m.group(1).strip()))
    if not any(path.startswith(o) for o in OWN) or any(path.startswith(p) for p in PROTECT):
        bad.append(path)

if bad:
    print(json.dumps({"hookSpecificOutput": {
        "hookEventName": "PreToolUse",
        "permissionDecision": "deny",
        "permissionDecisionReason": "Fichiers hors périmètre : " + ", ".join(bad)}}, ensure_ascii=False))

Claude Code, qui a rédigé cet article, a lancé ce script sur des entrées construites à la main au format que Codex transmet (dans le périmètre, shop, .agent-owner, un déplacement vers shared et une suppression sous tools/) et a confirmé que seule la modification dans le périmètre passait. Nous ne l’avons pas exécuté dans Codex.

Les commandes Bash peuvent s’écrire de bien des façons ; un hook ne peut donc pas déterminer entièrement où elles écrivent. OpenAI qualifie lui-même les hooks de « a useful guardrail, not a complete enforcement boundary » (un garde-fou utile, pas une frontière d’application complète). Bloquez les commandes à interdire, comme rm, par une règle avec decision = "forbidden", et laissez la vérification avant mise en production attraper le reste. Les règles se placent dans le dossier rules/ d’une couche de configuration, comme ~/.codex/rules/default.rules. Le .codex/rules/ d’un projet n’est lu que si ce projet est approuvé.

Les garde-fous de l’outil doivent être réécrits pour chaque outil, et ils peuvent ne pas s’appliquer selon le dossier de lancement et les réglages de confiance. Bâtissez donc sur la vérification avant mise en production, par laquelle toute modification doit finir par passer, et ajoutez par-dessus les garde-fous de l’outil pour détecter les problèmes plus tôt. Pour écrire des hooks Claude Code, voir « Que sont les hooks de Claude Code ? » ; pour les réglages en lecture seule, voir « Codex et Claude Code en lecture seule ».

5. Autres points de vigilance : confusion entre dépôts et variables d’environnement

Dans le même environnement, deux autres choses se sont produites quand une IA s’est vu confier plusieurs dépôts. Les deux ont été repérées avant de devenir des incidents graves, mais indépendamment de la façon de placer les règles, prévoyez des procédures pour elles.

Distinguer les dépôts aux noms proches par leur URL remote

Une IA a jugé que le dépôt d’un autre service au nom très proche était « une ancienne copie du même service » et l’a déplacé ailleurs (il a été remis en place aussitôt, contenu inchangé). Son raisonnement était « aucune modification locale, et la dernière mise à jour est ancienne », mais cela montre seulement que « rien n’est en cours de modification » et que « personne ne l’a modifié récemment ». Plus un service tourne de façon stable, moins il est mis à jour souvent.

Avant de déplacer ou de supprimer quoi que ce soit, lancez ce qui suit dans le dossier visé et dans le dossier utilisé en production, et comparez les résultats côte à côte.

# URL remote (retirer tout jeton ou mot de passe intégré à l'URL avant de l'afficher)
git -C <dossier> remote get-url origin | sed -E 's#://[^/@]+@#://#'

# Vérifier d'abord qu'il ne s'agit pas d'un clone superficiel (si true, le résultat suivant n'est pas fiable)
git -C <dossier> rev-parse --is-shallow-repository

# Commit racine (les copies issues du même historique le partagent)
git -C <dossier> rev-list --max-parents=0 HEAD
  • Comparer les URL remote par hôte et chemin du dépôt : https://github.com/org/app.git et git@github.com:org/app.git sont le même dépôt écrit différemment ; à l’inverse, avec des miroirs ou des alias d’hôte, un même dépôt peut sembler différent
  • Dans un clone superficiel, le commit racine n’est pas le vrai premier commit : dans un clone récupéré avec --depth 1, on obtient le plus ancien commit récupéré (dans notre test, HEAD lui-même)
  • Ne pas afficher les jetons intégrés à l’URL : une URL remote peut contenir un jeton d’authentification, et l’afficher tel quel fait fuiter un secret dans la sortie, exactement comme les variables d’environnement ci-dessous

Même si la comparaison montre qu’il s’agit d’« une copie inutilisée », ne la supprimez pas tout de suite ; déplacez-la d’abord ailleurs. Notez où elle est allée, où elle se trouvait et la commande pour la remettre, et ne la supprimez qu’après avoir constaté pendant un certain temps que rien n’est cassé. Dans cet environnement, la confusion a pu être réparée aussitôt précisément parce que le dossier avait été déplacé, et non supprimé.

Ne regarder que les noms des variables d’environnement

Une IA a lancé une commande pour inspecter la configuration d’un conteneur qui affichait les variables d’environnement avec leurs valeurs, et une chaîne de connexion à la base de données (mot de passe compris) est apparue dans la sortie. Une fois qu’une valeur apparaît dans la sortie, elle reste dans l’historique de la conversation et elle est aussi envoyée au modèle. Si vous voulez seulement savoir ce qui est défini, les noms suffisent.

Variables d’environnement d’un conteneur

Affiche les valeurs (à éviter)

docker inspect <conteneur>
docker exec <conteneur> printenv
docker exec <conteneur> sh -c 'env | cut -d= -f1'

Noms seulement

docker inspect --format '{{range .Config.Env}}{{index (split . "=") 0}}{{println}}{{end}}' <conteneur>
docker exec <conteneur> awk 'BEGIN{for(k in ENVIRON) print k}'

Sans option, docker inspect affiche toute la configuration, et son Env contient les valeurs telles quelles. Dans les conteneurs sans awk, utilisez docker inspect --format.

Configuration Docker Compose

Affiche les valeurs (à éviter)

docker compose config

Sans interpolation des variables

docker compose config --no-interpolate

Avec --no-interpolate, ${DB_URL} s’affiche tel quel, et env_file n’affiche que le chemin du fichier. Les variables dont la valeur est écrite directement dans compose.yaml sont affichées.

Shell local

Affiche les valeurs (à éviter)

env
printenv
Get-ChildItem Env:

Noms seulement

compgen -e                  # bash
(Get-ChildItem Env:).Name   # PowerShell

Voici les résultats quand Claude Code, qui a rédigé cet article, a fait l’essai avec des valeurs factices le 1er novembre 2026, avec Docker 29.8 et Docker Compose v5.6. Dans un conteneur avec une valeur contenant des retours à la ligne (la forme utilisée pour transmettre le contenu d’un fichier de clé), env | cut -d= -f1 a affiché les deuxième et troisième lignes de la valeur telles quelles, mêlées aux noms des variables. ENVIRON d’awk et docker inspect --format n’ont pas affiché les valeurs. docker compose config a affiché les valeurs factices écrites dans .env et env_file ; avec --no-interpolate, aucune n’est apparue, et seule la valeur écrite directement dans compose.yaml s’est affichée.

Pour plus de sûreté, écrivez « ne regarder que les noms des variables d’environnement » dans les documents de règles, et interdisez aussi les commandes qui affichent les valeurs avec les garde-fous de l’outil de la section 4. Si une valeur s’affiche malgré tout, considérez-la comme « vue » et décidez s’il faut la renouveler. Pour un réglage de Codex qui empêche de transmettre les variables d’environnement elles-mêmes aux commandes de l’IA, voir la section 6 de « Empêcher Codex de lire les fichiers secrets ».

6. Liste de contrôle avant de confier le travail

  • Décidé que le travail sur un site lance l’IA depuis le dossier du site à l’intérieur du worktree
  • Après le lancement, vérifié que les règles du site sont incluses : Memory files de /context pour Claude Code, la liste des fichiers d’instructions actifs pour Codex
  • Pour le travail lancé à la racine, prévu un moyen de voir si les règles des dossiers inférieurs ont été chargées en cours de session (la ligne Loaded de Claude Code, le hook InstructionsLoaded)
  • Ajouté une vérification qui arrête la mise en production si quelque chose a changé hors des dossiers attribués, et constaté qu’elle s’arrête sur une modification volontairement hors périmètre
  • Écrit le périmètre de chaque worktree avec des barres obliques finales, et fait en sorte que la vérification s’arrête si le fichier de périmètre manque
  • Interdit, avec les garde-fous de l’outil, l’écriture hors du périmètre et dans le fichier de périmètre
  • Inscrit dans les règles une procédure pour comparer l’URL remote et le commit racine avec la production avant de déplacer ou supprimer un dossier, et pour déplacer plutôt que supprimer
  • Inscrit dans les règles les commandes qui n’affichent que les noms des variables d’environnement, et interdit avec les garde-fous de l’outil les commandes qui affichent les valeurs
Exemple de texte pour les documents de règles (prêt à l’emploi)
## Règles pour travailler sur plusieurs projets
- Le périmètre de ce worktree se limite aux dossiers listés dans .agent-owner. Ne modifie pas de fichiers en dehors
  (toute modification hors périmètre arrête la vérification avant mise en production)
- Avant de déplacer ou supprimer un dossier, compare git remote get-url origin et
  git rev-list --max-parents=0 HEAD avec la production (attention aux clones superficiels).
  Déplace au lieu de supprimer, et note comment restaurer
- Ne regarde que les noms des variables d'environnement. N'utilise pas env, printenv, docker inspect (sans --format) ni
  docker compose config (sans --no-interpolate)

Rédigez les documents non comme un moyen d’imposer les règles, mais comme une explication, pour que l’IA comprenne pourquoi quelque chose s’est arrêté et choisisse la bonne procédure.

En résumé

  • Quand on lance depuis la racine, les règles placées dans le dossier de chaque site ne sont chargées par Claude Code qu’au moment où il touche des fichiers de ce dossier, et ne sont pas chargées automatiquement par Codex (l’IA peut les ouvrir d’elle-même, mais rien ne le garantit)
  • Avec les deux outils, lancer depuis le dossier du site charge les règles de ce site dès le départ (avec un worktree, lancez depuis le dossier du site à l’intérieur)
  • Vérifiez ce qui a été chargé au démarrage avec /context de Claude Code ou la liste des fichiers d’instructions actifs de Codex, et ce que Claude Code a chargé en cours de session avec la ligne Loaded ou le hook InstructionsLoaded
  • Transformez ce qui doit être imposé en une vérification automatique qui arrête la mise en production si quelque chose a changé hors des dossiers attribués, et ajoutez par-dessus les garde-fous de l’outil pour détecter les problèmes plus tôt
  • Par ailleurs, distinguez les dépôts aux noms proches par l’URL remote et le commit racine, et ne regardez que les noms des variables d’environnement

FAQ

Q. Un CLAUDE.md placé dans un sous-dossier est-il chargé ?

R. Oui, mais pas au lancement. Claude Code charge le CLAUDE.md d’un dossier quand Claude lit, écrit ou modifie un fichier de ce dossier. À ce moment-là, il n’apparaît pas dans Memory files de /context ; c’est une ligne Loaded avec son chemin qui s’affiche dans le terminal. Si vous lancez depuis ce dossier, il est chargé au démarrage et apparaît dans Memory files.

Q. Comment faire lire à Codex un AGENTS.md placé dans un sous-dossier ?

R. Lancez Codex depuis ce dossier (en CLI, codex --cd <dossier>). Au démarrage, Codex lit les AGENTS.md de la racine du projet jusqu’au dossier de lancement, et ne cherche pas en dessous. Si vous lancez depuis la racine, l’AGENTS.md d’un dossier inférieur est lu si l’IA l’ouvre d’elle-même, mais la documentation officielle ne propose aucun réglage qui le charge de façon sûre.

Q. Dans un monorepo, faut-il regrouper les documents de règles dans un seul fichier à la racine ?

R. La documentation des deux outils recommande de mettre les règles de tout le dépôt à la racine et les règles propres à un site dans le dossier de ce site. Cependant, les règles d’un site peuvent ne pas être chargées si vous ne lancez pas depuis ce dossier ; sortez donc des documents tout ce qui poserait problème s’il était ignoré, et confiez-le à la vérification avant mise en production ou aux garde-fous de l’outil.

Q. Comment faire lire à Claude Code à la fois CLAUDE.md et AGENTS.md ?

R. Par défaut, s’il existe un CLAUDE.md, un .claude/CLAUDE.md ou un CLAUDE.local.md dans le dossier de lancement ou au-dessus, AGENTS.md n’est pas lu. Importez-le avec une seule ligne @AGENTS.md dans CLAUDE.md, ou réglez Project instructions sur claude-md-and-agents-md dans /config.

Sources