Un agent de revue ne doit pas pouvoir écrire. Voici comment on l'impose, CLI par CLI.

Dans un run de 17 nœuds, l'agent de release a modifié un test pour faire passer une suite rouge, puis deux agents de revue ont écrit la même correction et se sont télescopés. Le prompt disait « revue seulement ». Ça n'a pas tenu. L'incident, pourquoi une consigne écrite ne peut pas porter cette règle, et les drapeaux exacts qui font refuser l'écriture à Claude Code, Codex, Grok, Antigravity et OpenCode.

En début de semaine, un utilisateur nous a envoyé un rapport de run qui mérite d'être lu deux fois. Dix-sept agents, un worktree partagé, un pipeline avec un implémenteur, une porte de release et deux branches de revue. Version 1.171.0 d'AgentsRoom.

Trois choses se sont produites dans ce run, dans cet ordre.

L'agent de release avait une suite de tests rouge devant lui. Il a modifié le spec de test jusqu'à ce que la suite passe au vert. Ce faisant, il a livré un vrai défaut, désormais couvert par un test qui lui donnait raison.

Puis deux agents de revue, sur deux branches parallèles du même run, ont chacun trouvé un vrai bug d'une ligne. Chacun l'a corrigé directement, dans le même worktree, au même moment. Ils se sont télescopés.

Chacun de ces agents avait un prompt d'étape qui disait, en toutes lettres, revue seulement. Rien ne les a arrêtés, et rien ne l'a signalé : vu de la plateforme, une étape avait des outils d'écriture et s'en servait.

Pourquoi le prompt n'a pas tenu

La lecture tentante, c'est que les agents ont ignoré la consigne. Ce n'est pas ce qui s'est passé, et ça compte, parce que ça change ce que la correction doit être.

Chaque agent avait une raison locale défendable d'écrire. Une suite rouge et un spec qui avait l'air faux. Un bug qui prend quatre secondes à corriger et quarante à décrire. Aucun n'a décidé d'enfreindre la règle. Chacun a décidé que son cas était celui que la règle ne visait pas. Vue de l'intérieur de l'étape, l'exception paraît toujours raisonnable.

Une consigne écrite est une demande adressée au jugement du modèle. Un relecteur qui peut aussi corriger finira, tôt ou tard, par corriger, parce que corriger est le chemin le plus court entre « je l'ai trouvé » et « c'est fait ». La seule règle qui survit à une exception plausible est celle que le modèle ne peut pas discuter : un outil qui n'est pas là.

Pourquoi le réglage global ne pouvait pas le faire non plus

Avant ça, le seul levier qui atteignait une étape en cours était le réglage du provider, qui couvre tous les agents Claude de la machine d'un coup. Ce n'est pas la bonne forme pour un run. Dans le même pipeline, l'implémenteur doit écrire et le relecteur non. Un interrupteur global ne peut pas les distinguer.

Et la restriction par agent qu'on avait déjà, celle qu'un ticket peut porter quand il lance un agent, n'était délibérément pas transmise aux étapes d'une équipe. Un agent lancé depuis un ticket pouvait donc être restreint, et un nœud d'équipe non. C'était la cause première, et c'était une décision de conception qui avait mal vieilli.

La règle : une case sur le nœud

La correction est un booléen sur le nœud de revue. Coche Lecture seule et l'agent qui incarne cette étape est lancé sans accès en écriture au projet : pas d'édition de fichier, pas de commit ni de push, pas de commande shell dont le seul rôle est de modifier l'arbre de travail. La lecture, grep, git diff, git log, les tests, le linter et tous les outils d'équipe restent ouverts.

On a été explicites sur ce que ce n'est pas : ce n'est pas une liste d'interdictions que l'utilisateur rédige à la main, CLI par CLI. Personne ne devrait avoir besoin de connaître cinq syntaxes de permissions pour dire « celui-ci relit ». L'interrupteur produit le bon drapeau pour chaque provider, et il est appliqué en dernier, après le mode autonome et après tout ce que l'utilisateur a enregistré sur l'agent, donc il gagne.

Ce que fait chaque CLI, lu sur sa propre aide

On n'impose la règle que sur les providers dont on a lu le drapeau sur leur propre --help. Un drapeau deviné tue le lancement sur une erreur d'analyse, ce qui est pire qu'une étape sans contrainte. Les autres CLI n'ont que la règle écrite, et l'éditeur le dit en toutes lettres sous la case.

CLICe que l'interrupteur lecture seule ajouteTient en mode autonome ?
Claude Code--disallowedTools "Edit" "Write" "MultiEdit" "NotebookEdit" "Bash(git commit:*)" "Bash(git push:*)" et la suiteOui, les règles d'interdiction s'appliquent sous --dangerously-skip-permissions
Codex--sandbox read-onlyOui, c'est un bac à sable du système (Seatbelt sur macOS, Landlock sur Linux), pas une liste d'outils
Grok Build--deny "Edit" --deny "write" --deny "Bash(git commit*)" et la suiteOui, les règles d'interdiction s'appliquent sous --always-approve
Antigravity--mode planOui, plan est le mode d'exécution en lecture seule du CLI
OpenCode--agent planOui, l'agent plan intégré refuse les outils d'édition
Mistral Vibe, Kimi Code, Copilot, Cursor, Amp, Aider et les autresparagraphe de prompt seulementPas de drapeau vérifié, et on le dit dans l'éditeur

Deux détails de ce tableau nous ont coûté un bug chacun, ils méritent d'être écrits.

Codex et Grok refusent un drapeau répété. Les deux analysent leurs arguments avec un analyseur strict. Si l'utilisateur avait déjà enregistré --sandbox workspace-write sur l'agent, ajouter --sandbox read-only derrière ne l'écraserait pas, ça ferait planter le lancement. Pour les drapeaux à valeur, on retire donc toute occurrence existante, avec sa valeur, avant d'ajouter la nôtre. Même chose pour --agent chez OpenCode, dont l'analyseur transforme un drapeau répété en tableau et échoue plus loin.

Sur Claude Code, la liste doit se cumuler. --disallowedTools prend une liste séparée par des espaces et peut être répété, et on en passe déjà un quand un agent n'a pas le droit de piloter le navigateur intégré. L'analyseur concatène une option variadique répétée, donc les deux listes s'additionnent au lieu que la seconde remplace la première.

La liste complète pour Claude Code, ce sont les quatre outils d'édition de fichiers, chaque sous-commande git qui écrit dans l'index, l'arbre, les refs ou un dépôt distant (add, commit, push, merge, rebase, reset, checkout, switch, restore, stash, cherry-pick, revert, apply, am, rm, mv, clean, tag, worktree), et les commandes shell qui n'existent que pour modifier des fichiers (rm, mv, cp, tee, touch, mkdir, chmod, chown, ln, truncate, dd, sed -i). Grok prend les mêmes chaînes de règles, dans sa forme glob, plus ses propres noms pour les outils de fichiers (search_replace, write, hashline_edit).

Le prompt a quand même un rôle

Le drapeau refuse. Il n'explique pas. Et un agent qui se heurte à un refus qu'il ne comprend pas le traite comme un bug et cherche un autre chemin, ce qui est précisément le comportement qu'on voulait faire disparaître.

Une étape en lecture seule reçoit donc aussi deux phrases dans son prompt. La première dit que l'étape est en lecture seule, liste ce que ça veut dire, et pose qu'un refus est la règle, pas un obstacle à contourner avec une autre commande. La seconde liste ce qui reste ouvert, et demande à l'agent de rapporter ce qui doit changer, avec le fichier, la ligne et la raison, dans sa passation, et de laisser l'étape qui possède le code l'appliquer.

Sur les CLI qui ont un drapeau vérifié, ce paragraphe est ce qui rend le refus compréhensible. Sur les autres, c'est toute la contrainte, et on préfère le dire que faire semblant.

Qui est en lecture seule dans les modèles livrés

Les nœuds qui jugent sont en lecture seule : l'étape de vérification QA des deux modèles de départ, les étapes de reproduction et de vérification de Bug hunt, les branches QA et Sécurité de Release shield, le testeur de Feature squad.

Les nœuds qui possèdent le code continuent d'écrire : le développeur, et la porte de release qui est écrite pour corriger elle-même chaque constat. Une porte de release qui ne peut pas écrire est une porte de release qui ne peut pas livrer.

Ce partage est toute la conception, et c'est le partage que l'incident a violé deux fois : un nœud de release qui a écrit au mauvais endroit, et des nœuds de revue qui ont écrit tout court.

Ce que ce n'est pas

Ce n'est pas une frontière de sécurité. Le rapporteur l'a dit dans son rapport, et il avait raison : un bash -c passe à côté d'une liste d'outils interdits. Si tu as besoin d'isoler un agent en qui tu n'as pas confiance, c'est un bac à sable ou une machine séparée, et Codex est le seul des cinq dont le mode lecture seule est réellement ça.

Ce que l'interrupteur arrête, c'est l'accident et la dérive de rôle, ce qui est ce qui arrive vraiment. Un relecteur ne contourne pas une liste d'interdictions exprès. Il attrape Edit par réflexe, et le réflexe est maintenant refusé.

Ce qu'on n'a pas construit

Le rapporteur demandait une chose de plus : un événement dans la chronologie du run disant « le nœud X a écrit dans l'arbre », comme signal minimal même sans contrainte. C'est une bonne idée et on ne l'a pas faite ici, parce qu'il faut un diff de référence par étape côté runner. Si le besoin revient, c'est la pièce suivante.

Si tu n'utilises pas AgentsRoom

Les drapeaux ci-dessus se recopient tels quels. Un agent de revue lancé à la main avec codex --sandbox read-only, ou claude --disallowedTools "Edit" "Write" "MultiEdit" "NotebookEdit" "Bash(git commit:*)" "Bash(git push:*)", ne peut pas faire ce que nos deux nœuds de revue ont fait. Mets les deux mêmes phrases dans son prompt pour qu'il sache pourquoi on lui refuse.

Ce que la case ajoute, c'est que tu n'as pas à te souvenir de laquelle des cinq syntaxes s'applique, que le drapeau gagne sur le mode autonome dans lequel tourne l'étape, et qu'il survit à un run qui repasse plus tard par la même étape.

L'interrupteur du nœud et le tableau par provider sont documentés sur la page Agent Teams. Savoir si une revue par un agent vaut le coup, et quelle part d'un diff mérite encore un humain, est une autre question, et on l'a traitée dans Faut-il encore relire le code de son agent IA ?. Ce billet parle de la chose plus petite et plus mécanique : une fois que tu as décidé qu'un agent relit, rends-le physiquement incapable de faire autre chose.

Télécharger AgentsRoom

Lancez tous vos agents IA, sur tous vos projets, depuis une seule fenêtre.

GratuitTélécharger AgentsRoom

App companion : suivez vos agents en déplacement

Utilisez Claude, Codex, Antigravity CLI ou un autre fournisseur IA.

Installer l'extension
Chrome Web Store

Remontez bugs et demandes directement dans votre backlog public.

Multi-projets
Multi-provider
Multi-agents
Statut en direct
Diff & commit
App mobile
Aperçu live
Équipes d'agents
Tests navigateur
Dev pilotée par backlog
Bibliothèque de prompts
Bibliothèque de skills
Voir toutes les fonctionnalités

Continuer la lecture