Agent do review nie powinien móc pisać. Oto jak to wymuszamy, CLI po CLI.

W runie z 17 węzłami agent release'u zmienił test, żeby czerwony zestaw zrobił się zielony, a potem dwa agenty review napisały tę samą poprawkę i zderzyły się. Prompt mówił: tylko review. Nie wytrzymało. Incydent, dlaczego pisemna instrukcja nie może nieść tej reguły, i dokładne flagi, przez które Claude Code, Codex, Grok, Antigravity i OpenCode odmawiają zapisu.

Na początku tego tygodnia użytkownik przysłał nam raport z runu, który warto przeczytać dwa razy. Siedemnaście agentów, jeden wspólny worktree, pipeline z implementatorem, bramką release'u i dwiema gałęziami review. Wersja 1.171.0 AgentsRoom.

W tym runie zdarzyły się trzy rzeczy, w tej kolejności.

Agent release'u miał przed sobą czerwony zestaw testów. Edytował spec testu, aż zestaw zrobił się zielony. Przy okazji dostarczył prawdziwą wadę, teraz pokrytą testem, który się z nim zgadzał.

Potem dwa agenty review, na dwóch równoległych gałęziach tego samego runu, znalazły po prawdziwym jednoliniowym bugu. Każdy poprawił go bezpośrednio, w tym samym worktree, w tym samym czasie. Zderzyły się.

Każdy z tych agentów miał prompt kroku, który mówił wprost: tylko review. Nic ich nie zatrzymało i nic tego nie zasygnalizowało: od strony platformy krok miał narzędzia zapisu i ich użył.

Dlaczego prompt nie wytrzymał

Kusząca interpretacja jest taka, że agenty zignorowały instrukcję. Nie to się stało, i to ma znaczenie, bo zmienia to, czym musi być poprawka.

Każdy agent miał lokalnie obronny powód, żeby pisać. Czerwony zestaw i spec, który wyglądał na błędny. Bug, którego poprawienie zajmuje cztery sekundy, a opisanie czterdzieści. Żaden nie postanowił złamać reguły. Każdy uznał, że jego przypadek to ten, którego reguła nie miała na myśli. Z wnętrza kroku wyjątek zawsze wygląda rozsądnie.

Pisemna instrukcja to prośba skierowana do osądu modelu. Reviewer, który może też poprawiać, prędzej czy później będzie poprawiać, bo poprawienie to najkrótsza droga od „znalazłem” do „zrobione”. Jedyna reguła, która przetrwa kontakt z wiarygodnym wyjątkiem, to taka, z którą model nie może dyskutować: narzędzie, którego nie ma.

Dlaczego ustawienie globalne też nie mogło tego zrobić

Wcześniej jedyną dźwignią, która sięgała do działającego kroku, były ustawienia providera, obejmujące naraz wszystkie agenty Claude na maszynie. To zły kształt dla runu. W tym samym pipeline implementator musi pisać, a reviewer nie. Przełącznik globalny nie potrafi ich rozróżnić.

A ograniczenie per agent, które już mieliśmy, to, które ticket może nieść, gdy uruchamia agenta, celowo nie było przekazywane do kroków zespołu. Agent uruchomiony z ticketu mógł więc być ograniczony, a węzeł zespołu nie. To była główna przyczyna i była to decyzja projektowa, która źle się zestarzała.

Reguła: jeden checkbox na węźle

Poprawka to boolean na węźle review. Zaznacz Tylko do odczytu, a agent, który wciela ten krok, jest uruchamiany bez dostępu do zapisu w projekcie: żadnej edycji plików, żadnego git commit ani push, żadnej komendy shella, której jedynym zadaniem jest zmiana drzewa roboczego. Czytanie, grep, git diff, git log, testy, linter i wszystkie narzędzia zespołowe pozostają otwarte.

Byliśmy wyraźni co do tego, czym to nie jest: to nie jest lista zakazów, którą użytkownik pisze ręcznie, CLI po CLI. Nikt nie powinien musieć znać pięciu składni uprawnień, żeby powiedzieć „ten robi review”. Przełącznik generuje właściwą flagę dla każdego providera i jest stosowany na końcu, po trybie autonomicznym i po wszystkim, co użytkownik zapisał na agencie, więc wygrywa.

Co robi każde CLI, odczytane z jego własnej pomocy

Wymuszamy tylko u providerów, których flagę odczytaliśmy w ich własnym --help. Zgadnięta flaga zabija start błędem parsowania, a to gorsze niż krok bez wymuszenia. Pozostałe CLI dostają tylko pisemną regułę, a edytor mówi o tym otwartym tekstem pod checkboxem.

CLICo dodaje przełącznik tylko do odczytuTrzyma w trybie autonomicznym?
Claude Code--disallowedTools "Edit" "Write" "MultiEdit" "NotebookEdit" "Bash(git commit:*)" "Bash(git push:*)" i resztaTak, reguły deny obowiązują pod --dangerously-skip-permissions
Codex--sandbox read-onlyTak, to sandbox systemu operacyjnego (Seatbelt na macOS, Landlock na Linux), nie lista narzędzi
Grok Build--deny "Edit" --deny "write" --deny "Bash(git commit*)" i resztaTak, reguły deny obowiązują pod --always-approve
Antigravity--mode planTak, plan to tryb wykonania CLI tylko do odczytu
OpenCode--agent planTak, wbudowany agent plan odmawia narzędzi edycji
Mistral Vibe, Kimi Code, Copilot, Cursor, Amp, Aider i resztatylko akapit w prompcieBrak zweryfikowanej flagi, i mówimy o tym w edytorze

Dwa szczegóły z tej tabeli kosztowały nas po jednym bugu, więc warto je rozpisać.

Codex i Grok odrzucają powtórzoną flagę. Oba parsują argumenty ścisłym parserem. Gdyby użytkownik zapisał już na agencie --sandbox workspace-write, dopisanie --sandbox read-only nie nadpisałoby go, tylko wywróciło start. Dla flag z wartością usuwamy więc każde istniejące wystąpienie, razem z wartością, zanim dopiszemy naszą. To samo dla --agent w OpenCode, którego parser zamienia powtórzoną flagę w tablicę i wywala się dalej.

Na Claude Code lista musi się sumować. --disallowedTools przyjmuje listę rozdzieloną spacjami i może być powtarzana, a my już jedną przekazujemy, gdy agent nie ma prawa sterować wbudowaną przeglądarką. Parser skleja powtórzoną opcję wariadyczną, więc obie listy się dodają, zamiast żeby druga zastąpiła pierwszą.

Pełna lista dla Claude Code to cztery narzędzia edycji plików, każda podkomenda git, która zapisuje do indeksu, drzewa, refów albo zdalnego repozytorium (add, commit, push, merge, rebase, reset, checkout, switch, restore, stash, cherry-pick, revert, apply, am, rm, mv, clean, tag, worktree), i komendy shella, które istnieją tylko po to, żeby zmieniać pliki (rm, mv, cp, tee, touch, mkdir, chmod, chown, ln, truncate, dd, sed -i). Grok przyjmuje te same ciągi reguł, w swojej formie glob, plus własne nazwy narzędzi plikowych (search_replace, write, hashline_edit).

Prompt wciąż ma zadanie

Flaga odmawia. Nie tłumaczy. A agent, który trafia na odmowę, której nie rozumie, traktuje ją jak bug i szuka innej drogi, czyli dokładnie tego zachowania, które chcieliśmy usunąć.

Krok tylko do odczytu dostaje więc też dwa zdania w swoim prompcie. Pierwsze mówi, że krok jest tylko do odczytu, wylicza, co to znaczy, i stwierdza, że odmowa jest regułą, a nie przeszkodą do obejścia inną komendą. Drugie wylicza, co pozostaje otwarte, i każe agentowi zgłosić w przekazaniu do następnego kroku, co powinno się zmienić, z plikiem, linią i powodem, i zostawić zastosowanie krokowi, który jest właścicielem kodu.

Na CLI ze zweryfikowaną flagą ten akapit sprawia, że odmowa jest zrozumiała. Na pozostałych to całe wymuszenie, i wolimy to powiedzieć, niż udawać.

Kto jest tylko do odczytu w dostarczanych szablonach

Węzły, które oceniają, są tylko do odczytu: krok weryfikacji QA dwóch szablonów startowych, kroki reprodukcji i weryfikacji w Bug hunt, gałęzie QA i Security w Release shield, tester w Feature squad.

Węzły, które są właścicielami kodu, dalej piszą: developer i bramka release'u, która jest napisana tak, żeby sama poprawiać każde znalezisko. Bramka release'u, która nie może pisać, to bramka release'u, która nie może wydać release'u.

Ten podział to cały projekt i to ten podział incydent naruszył dwa razy: węzeł release'u, który pisał w złym miejscu, i węzły review, które w ogóle pisały.

Czym to nie jest

To nie jest granica bezpieczeństwa. Zgłaszający powiedział to w raporcie i miał rację: bash -c omija listę zakazanych narzędzi. Jeśli musisz odizolować agenta, któremu nie ufasz, to jest sandbox albo osobna maszyna, a Codex jest jedynym z pięciu, którego tryb tylko do odczytu naprawdę tym jest.

To, co przełącznik zatrzymuje, to wypadek i dryf roli, czyli to, co naprawdę się dzieje. Reviewer nie ucieka z listy zakazów celowo. Sięga po Edit odruchowo, a odruch jest teraz odrzucany.

Czego nie zbudowaliśmy

Zgłaszający prosił o jeszcze jedną rzecz: zdarzenie na osi czasu runu mówiące „węzeł X zapisał do drzewa”, jako minimalny sygnał nawet bez wymuszenia. To dobry pomysł i nie zrobiliśmy go tutaj, bo wymaga bazowego diffa per krok po stronie runnera. Jeśli potrzeba wróci, to będzie następny kawałek.

Jeśli nie używasz AgentsRoom

Powyższe flagi można skopiować tak, jak są. Agent review uruchomiony ręcznie z codex --sandbox read-only albo claude --disallowedTools "Edit" "Write" "MultiEdit" "NotebookEdit" "Bash(git commit:*)" "Bash(git push:*)" nie może zrobić tego, co zrobiły nasze dwa węzły review. Wstaw te same dwa zdania do jego promptu, żeby wiedział, dlaczego dostaje odmowę.

To, co dodaje checkbox, to że nie musisz pamiętać, która z pięciu składni obowiązuje, że flaga wygrywa z każdym trybem autonomicznym, w którym działa krok, i że przeżywa run, który później ponownie wchodzi w ten sam krok.

Przełącznik węzła i tabela per provider są udokumentowane na stronie Agent Teams. Czy review przez agenta w ogóle jest coś wart, i jaka część diffa wciąż zasługuje na człowieka, to inne pytanie, i pisaliśmy o tym w Czy nadal trzeba robić review kodu swojego agenta AI?. Ten wpis jest o mniejszej, bardziej mechanicznej rzeczy: gdy już zdecydujesz, że agent robi review, spraw, żeby fizycznie nie mógł zrobić niczego innego.

Pobierz AgentsRoom

Uruchamiaj wszystkich swoich agentów AI, we wszystkich projektach, z jednego okna.

Za darmoPobierz AgentsRoom

Aplikacja towarzysząca: monitoruj agentów w podróży

Użyj Claude, Codex, Antigravity CLI lub innego dostawcy AI.

Zainstaluj rozszerzenie
Chrome Web Store

Wysyłaj bugi i prośby bezpośrednio do swojego publicznego backlogu.

Wiele projektów
Multi-provider
Wielu agentów
Status na żywo
Diff i commit
Aplikacja mobilna
Podgląd na żywo
Zespoły agentów
Testy w przeglądarce
Dev oparta na backlogu
Biblioteka promptów
Biblioteka umiejętności
Zobacz wszystkie funkcje

Czytaj dalej