Un agente di review non dovrebbe poter scrivere. Ecco come lo imponiamo, CLI per CLI.
In un run da 17 nodi, l'agente di release ha modificato un test per far passare una suite rossa, poi due agenti di review hanno scritto la stessa correzione e si sono scontrati. Il prompt diceva «solo review». Non ha retto. L'incidente, perché un'istruzione scritta non può reggere quella regola, e i flag esatti che fanno rifiutare la scrittura a Claude Code, Codex, Grok, Antigravity e OpenCode.
A inizio settimana un utente ci ha mandato un report di run che merita di essere letto due volte. Diciassette agenti, un worktree condiviso, una pipeline con un implementatore, un release gate e due rami di review. Versione 1.171.0 di AgentsRoom.
In quel run sono successe tre cose, in quest'ordine.
L'agente di release aveva davanti una suite di test rossa. Ha modificato lo spec del test finché la suite non è diventata verde. Così facendo ha rilasciato un difetto reale, ora coperto da un test che gli dava ragione.
Poi due agenti di review, su due rami paralleli dello stesso run, hanno trovato ciascuno un vero bug da una riga. Ciascuno l'ha corretto direttamente, nello stesso worktree, nello stesso momento. Si sono scontrati.
Ognuno di quegli agenti aveva un prompt di step che diceva, a chiare lettere, solo review. Niente li ha fermati, e niente l'ha segnalato: dal lato della piattaforma, uno step aveva strumenti di scrittura e li ha usati.
Perché il prompt non ha retto
La lettura tentatrice è che gli agenti abbiano ignorato l'istruzione. Non è quello che è successo, e conta, perché cambia cosa deve essere la correzione.
Ogni agente aveva una ragione localmente difendibile per scrivere. Una suite rossa e uno spec che sembrava sbagliato. Un bug che richiede quattro secondi per essere corretto e quaranta per essere descritto. Nessuno ha deciso di infrangere la regola. Ciascuno ha deciso che il suo caso era quello che la regola non intendeva coprire. Vista dall'interno dello step, l'eccezione sembra sempre ragionevole.
Un'istruzione scritta è una richiesta rivolta al giudizio del modello. Un revisore che può anche correggere, prima o poi, correggerà, perché correggere è la strada più corta tra «l'ho trovato» e «fatto». L'unica regola che sopravvive al contatto con un'eccezione plausibile è quella che il modello non può discutere: uno strumento che non c'è.
Perché neanche l'impostazione globale poteva farlo
Prima di questo, l'unica leva che raggiungeva uno step in esecuzione erano le impostazioni del provider, che coprono tutti gli agenti Claude della macchina in un colpo solo. Non è la forma giusta per un run. Nella stessa pipeline, l'implementatore deve scrivere e il revisore no. Un interruttore globale non riesce a distinguerli.
E la restrizione per agente che avevamo già, quella che un ticket può portare con sé quando lancia un agente, deliberatamente non veniva passata agli step di un team. Quindi un agente avviato da un ticket poteva essere limitato, e un nodo di un team no. Era questa la causa principale, ed era una decisione di design invecchiata male.
La regola: una casella sul nodo
La correzione è un booleano sul nodo di review. Spunta Sola lettura e l'agente che incarna quello step viene lanciato senza accesso in scrittura al progetto: nessuna modifica di file, nessun commit né push git, nessun comando di shell il cui unico compito è cambiare l'albero di lavoro. La lettura, grep, git diff, git log, i test, il linter e tutti gli strumenti di team restano aperti.
Siamo stati espliciti su cosa non è: non è una lista di divieti che l'utente scrive a mano, CLI per CLI. Nessuno dovrebbe aver bisogno di conoscere cinque sintassi di permessi per dire «questo fa la review». L'interruttore produce il flag giusto per ogni provider, e viene applicato per ultimo, dopo la modalità autonoma e dopo qualsiasi cosa l'utente abbia salvato sull'agente, quindi vince.
Cosa fa ogni CLI, letto sulla sua stessa guida
Imponiamo la regola solo sui provider il cui flag abbiamo letto sul loro stesso --help. Un flag tirato a indovinare uccide l'avvio con un errore di parsing, il che è peggio di uno step senza vincolo. Le altre CLI ricevono solo la regola scritta, e l'editor lo dice in chiaro sotto la casella.
| CLI | Cosa aggiunge l'interruttore sola lettura | Regge in modalità autonoma? |
|---|---|---|
| Claude Code | --disallowedTools "Edit" "Write" "MultiEdit" "NotebookEdit" "Bash(git commit:*)" "Bash(git push:*)" e il resto | Sì, le regole di divieto valgono sotto --dangerously-skip-permissions |
| Codex | --sandbox read-only | Sì, è una sandbox del sistema operativo (Seatbelt su macOS, Landlock su Linux), non una lista di strumenti |
| Grok Build | --deny "Edit" --deny "write" --deny "Bash(git commit*)" e il resto | Sì, le regole di divieto valgono sotto --always-approve |
| Antigravity | --mode plan | Sì, plan è la modalità di esecuzione in sola lettura della CLI |
| OpenCode | --agent plan | Sì, l'agente plan integrato nega gli strumenti di modifica |
| Mistral Vibe, Kimi Code, Copilot, Cursor, Amp, Aider e gli altri | solo il paragrafo del prompt | Nessun flag verificato, e lo diciamo nell'editor |
Due dettagli di quella tabella ci sono costati un bug ciascuno, quindi vale la pena spiegarli.
Codex e Grok rifiutano un flag ripetuto. Entrambi analizzano gli argomenti con un parser rigoroso. Se l'utente aveva già salvato --sandbox workspace-write sull'agente, aggiungere --sandbox read-only in coda non lo sovrascriverebbe, farebbe crashare l'avvio. Quindi per i flag con valore rimuoviamo qualsiasi occorrenza esistente, con il suo valore, prima di aggiungere la nostra. Lo stesso vale per --agent su OpenCode, il cui parser trasforma un flag ripetuto in un array e fallisce più avanti.
Su Claude Code la lista deve accumularsi. --disallowedTools accetta una lista separata da spazi e può essere ripetuto, e ne passiamo già uno quando un agente non ha il permesso di pilotare il browser integrato. Il parser concatena un'opzione variadica ripetuta, quindi le due liste si sommano invece che la seconda sostituisca la prima.
La lista completa per Claude Code sono i quattro strumenti di modifica dei file, ogni sottocomando git che scrive nell'indice, nell'albero, nei ref o su un remoto (add, commit, push, merge, rebase, reset, checkout, switch, restore, stash, cherry-pick, revert, apply, am, rm, mv, clean, tag, worktree), e i comandi di shell che esistono solo per cambiare file (rm, mv, cp, tee, touch, mkdir, chmod, chown, ln, truncate, dd, sed -i). Grok prende le stesse stringhe di regole, nella sua forma glob, più i suoi nomi per gli strumenti sui file (search_replace, write, hashline_edit).
Il prompt ha ancora un compito
Il flag rifiuta. Non spiega. E un agente che incontra un rifiuto che non capisce lo tratta come un bug e cerca un'altra strada, che è esattamente il comportamento che volevamo eliminare.
Quindi uno step in sola lettura riceve anche due frasi nel suo prompt. La prima dice che lo step è in sola lettura, elenca cosa significa, e stabilisce che un rifiuto è la regola, non un ostacolo da aggirare con un altro comando. La seconda elenca cosa resta aperto, e dice all'agente di riportare cosa dovrebbe cambiare, con il file, la riga e il motivo, nel suo passaggio di consegne, e di lasciare che lo step che possiede il codice lo applichi.
Sulle CLI con un flag verificato, quel paragrafo è ciò che rende il rifiuto comprensibile. Sulle altre, è l'intero vincolo, e preferiamo dirlo piuttosto che fingere.
Chi è in sola lettura nei template forniti
I nodi che giudicano sono in sola lettura: lo step di verifica QA dei due template di partenza, gli step di riproduzione e verifica di Bug hunt, i rami QA e Sicurezza di Release shield, il tester di Feature squad.
I nodi che possiedono il codice continuano a scrivere: lo sviluppatore, e il release gate che è scritto per correggere da solo ogni segnalazione. Un release gate che non può scrivere è un release gate che non può rilasciare.
Quella divisione è tutto il design, ed è la divisione che l'incidente ha violato due volte: un nodo di release che ha scritto nel posto sbagliato, e nodi di review che hanno scritto, punto.
Cosa non è
Non è un confine di sicurezza. Chi ha segnalato l'incidente l'ha scritto nel report, e aveva ragione: un bash -c aggira una lista di strumenti vietati. Se devi isolare un agente di cui non ti fidi, serve una sandbox o una macchina separata, e Codex è l'unico dei cinque la cui modalità in sola lettura è davvero questo.
Quello che l'interruttore ferma è l'incidente e la deriva di ruolo, che è quello che succede davvero. Un revisore non aggira una lista di divieti apposta. Afferra Edit per riflesso, e il riflesso adesso viene rifiutato.
Cosa non abbiamo costruito
Chi ha segnalato l'incidente ha chiesto un'altra cosa: un evento nella timeline del run che dica «il nodo X ha scritto nell'albero», come segnale minimo anche senza vincolo. È una buona idea e qui non l'abbiamo fatta, perché richiede un diff di riferimento per step dal lato del runner. Se il bisogno torna, è il pezzo successivo.
Se non usi AgentsRoom
I flag qui sopra si copiano così come sono. Un agente di review lanciato a mano con codex --sandbox read-only, o con claude --disallowedTools "Edit" "Write" "MultiEdit" "NotebookEdit" "Bash(git commit:*)" "Bash(git push:*)", non può fare quello che hanno fatto i nostri due nodi di review. Metti le stesse due frasi nel suo prompt perché sappia perché gli viene rifiutato.
Quello che la casella aggiunge è che non devi ricordare quale delle cinque sintassi si applica, che il flag vince su qualunque modalità autonoma in cui gira lo step, e che sopravvive a un run che ripassa più tardi dallo stesso step.
L'interruttore del nodo e la tabella per provider sono documentati nella pagina Agent Teams. Se una review fatta da un agente valga davvero la pena, e quanta parte di un diff meriti ancora un umano, è un'altra domanda, e ne abbiamo scritto in Dovresti ancora rileggere il codice del tuo agente IA?. Questo post parla della cosa più piccola e più meccanica: una volta deciso che un agente fa la review, rendilo fisicamente incapace di fare qualsiasi altra cosa.
Scarica AgentsRoom
Esegui tutti i tuoi agenti AI, su tutti i tuoi progetti, da una sola finestra.
App companion: monitora i tuoi agenti in movimento
Usa Claude, Codex, Antigravity CLI o un altro provider IA.
Invia bug e richieste direttamente nel tuo backlog pubblico.
Continua a leggere
Codex, Claude Code, Cursor o Copilot: scegliere in base a come lavori
Codex, Claude Code, Cursor, GitHub Copilot e AgentsRoom messi a confronto per modo di lavorare invece che per lista di funzioni: programmare da solo, gestire più agenti o consegnare in team.
Leggi l'articoloUna bacheca di feedback per gli agenti IA: lascia che siano i tuoi utenti a scrivere il prompt
Gli strumenti di feedback raccolgono richieste. Nessuno di loro sa realizzarne una. Quando la bacheca su cui scrivono i tuoi utenti è la stessa da cui partono i tuoi agenti di codice, il passaggio di riscrittura sparisce.
Leggi l'articoloDieci agenti hanno lanciato lo stesso typecheck insieme. La soluzione era una cartella.
Diciassette agenti di codice nello stesso checkout, dieci processi tsc insieme, load average 37 e 87 MB di RAM libera. Un typecheck da novanta secondi ci ha messo 7 min 36. Ecco la misura, perché la macchina non calcolava, e il piccolo lock condiviso che ha risolto. Copiabile in qualsiasi repository.
Leggi l'articolo