ADR 0167 — Автоматический режим снимает область путей, и только он
Статус
Accepted. Решено владельцем продукта 2026-09-26 (AT-226) из трёх вариантов: "com o modo automático ligado, o agente executa qualquer comando de terminal sem aprovação, inclusive fora da pasta do projeto". Пересматривает ТОЛЬКО для агента в автоматическом режиме предел области путей ADR 0055. Не редактирует ни 0055, ни ADR 0102 (предел внешнего эффекта/привилегированной команды, RN-418), которые продолжают действовать целиком. Правило, рождающееся отсюда, — RN-603; оно пересматривает RN-153 и RN-154.
Контекст
"Автоматический режим" (RN-153) — это
подстановочный знак "*" в agent_autonomy: автономия для любого типа действия
агента. Он был задуман так, чтобы НЕ пробивать ни одного предела decide() — пределы
действовали по current.policy === 'auto_approve', не зная, откуда пришла
разрешительность (RN-154).
Один из этих пределов — ОБЛАСТЬ ПУТЕЙ (ADR 0055): команда терминала, которая
касается пути вне папки проекта, никогда не автоодобряется. Измерено в базе
владельца 2026-09-26, проект exp001 (режим mounted, контейнер поднят): при
включённом автоматическом режиме у dev agents 51 команда терминала всё ещё
запросила одобрение, и 47 — только потому, что упоминали /work или /tmp. Dev agent
работает ВНУТРИ контейнера, где папка проекта — /work, а область
сравнивает команду с корнем ХОСТА — так что всё, что агент пишет
правильно для места, где он работает, становится "вне папки проекта". Ни одна из 51
не была git push, PR, deploy или sudo.
Был второй запрос по той же причине, без названия области: СОСТАВНАЯ
команда (cd /work && npm test) с сегментом без правила в
permissions.json получает require_approval, СИНТЕЗИРОВАННЫЙ файлом, — который
существует, чтобы частичный allow не повышал всю команду, — и этот
вердикт перезаписывал auto_approve автономии.
Владелец попросил: "uma vez que o usuário apertar o botão modo automático, aquele agente deve entender que pode executar qualquer comando… só deve novamente pedir para aprovar quando o usuário definir os agentes como manual novamente".
Решение
decide()начинает знать ИСТОЧНИК автономии. Репозиторий (AgentAutonomyRepository.resolve) возвращает разрешённый режим И то, пришёл ли он из конкретного правила типа или из подстановочного знака. Приоритет конкретное > подстановочное по-прежнему живёт там, один раз —findModeстал чтениемresolve, а не вторым мерилом.decide()остаётся чистой: получаетctx.autonomyOrigin, а отсутствующий источник считается'especifica'(кто его не сообщает, сохраняет прежний вердикт).- Автоматический режим — это ровно: подстановочный знак, разрешённый как
auto_approve."*": require_approval(выключенный переключатель) и"*": denyне получают никаких полномочий. Конкретное правило типа (terminal: require_approval) побеждает подстановочный знак в репозитории и приходит с источником'especifica'— автоматический режим его не перекрывает. - В автоматическом режиме предел области путей не применяется. Как и
require_approval, который составная команда синтезирует для сегмента без правила: это файл БЕЗ мнения, а файл без мнения никогда не понижает предыдущую стадию.ask, ЗАПИСАННЫЙ вpermissions.json, продолжает действовать — это правило пользователя, а явное правило побеждает подстановочный знак, как в репозитории. - Всё остальное остаётся байт в байт.
deny(изpermissions.json, из встроенных шаблонов или из конкретной автономии) продолжает побеждать; предел внешнего эффекта/привилегированной команды (git push, PR, deploy,sudo/doas, RN-418) выполняется ДО предела области и не смотрит на источник; merge в защищённую ветку,instruction_patch,parallelize/raise_max_parallelиcontainer_removeпо-прежнему никогда не автоодобряются. - Экран говорит до клика, что кнопка снимает и что продолжает
запрашивать. Примечание
ApprovalCardдействует в обоих вариантах (чат и очередь Aprovações), а карточка агента показывает фразу под переключателем — только когда ПОДСТАНОВОЧНЫЙ ЗНАК включён, потому что переключатель на репрезентативном типе записывает конкретное правило, которое не снимает область.
Последствия
- Агент в автоматическом режиме может читать и писать вне папки проекта,
не спрашивая. Это выбранная цена: находка U (агент читает код
платформы, которая его выполняет, ADR 0055) снова становится возможной ДЛЯ ЭТОГО АГЕНТА
по явному решению пользователя, включившего режим. Остающееся сдерживание — это
место, где выполняется команда, — mount namespace контейнера
(
container/mounted, ADR 0134) или машина пользователя (runner), — плюсdenyи пределы эффектов. - Возврат переключателя карточки агента в "manual" перезаписывает подстановочный знак как
require_approvalи восстанавливает предел области при следующем предложении. - Переключатель карточки, когда подстановочный знак НЕ записан, продолжает редактировать
репрезентативный тип (
autonomyActionTypeFor) — конкретное правило. Включение оттуда — не автоматический режим и не снимает область; экран не говорит, что снимает. decide()перестаёт быть слепой к источнику автономии, что было доказательством по построению RN-154. Доказательство продолжает действовать для всех пределов, кроме области, и закреплено тестом: каждый из них с включённым подстановочным знаком остаётсяrequire_approval.
Рассмотренные альтернативы
- Переводить
/workв корень хоста перед областью. Решило бы 47 вexp001, но не/tmpи не то, о чём просил владелец ("любая команда"). А перевод намеренно живёт в engine, после решения (ADR 0134). - Снять область для любой автономии
auto_approve, конкретной или нет. Отвергнуто:terminal: auto_approveпо типу существует с Фазы 8d с областью поверх, и изменение её смысла без чьей-либо просьбы вновь открыло бы находку U в проектах, которые никогда не включали автоматический режим. - Позволить игнорировать и
ask, записанный в файле. Отвергнуто: это был бы автоматический режим, перекрывающий явное правило пользователя, — обратное приоритету, который уже применяет репозиторий.