- ключ Context7 подставляется через {env:...}: с ${env:...} в заголовок
уходил лишний $
- убраны устаревшие в V2 разрешения write и patch, их покрывает edit
- удалён слишком широкий шаблон *shadow*
- в permission-reviewer.md отмечено, что система отключена
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.3 KiB
5.3 KiB
Система автоподтверждения разрешений (autoapprove)
Отключена. Эксперимент 2026-10-11 оказался малополезен, плагин снят из
opencode.json. Итоги —docs/research/2026-10-11-opencode-permission-reviewer-autoapprove.md. Ниже — описание на случай, если систему решат вернуть.
Как была устроена подтверждение команд в OpenCode на этой машине, и где что искать.
Цепочка решений
Каждый ask из opencode.json проходит слои сверху вниз:
- Deny-паттерны (
permission.bashвopencode.json) — мгновенный отказ по строке команды, до всяких моделей. Только секреты:*.env*,*.secrets*,~/.ssh/*и т.п. Паттерны слепы к содержимому скриптов — это не рубеж, а только защита секретов. - Jev (
opencode/jev-1.13, System One) — типизированный ревьюер: получает команду, свидетельства из транскрипта и содержимое локальных скриптов (read-only enrichment), отвечает allow / deny / escalate. - Второе мнение (
opencode-go/glm-5.3-flash) — разбирает трудные случаи, где jev неуверен, но есть шанс на решение. - Финал —
escalationMode: deny: неразрешённое отклоняется с причиной агенту. Человек в цепочке не участвует: приpermission=autoзапрос к человеку всё равно решил бы auto.
Ключевые настройки в permission-reviewer.jsonc рядом с этим файлом:
enforcementMode: enforce (применять политику рисков; дефолт observe — только
аудит), escalationMode: deny (дефолт manual — спросить человека).
Инфраструктура
- Jev ходит на OpenCode Zen endpoint
/zen/v1/systemone. Zen закрывает его по региону (HTTP 451), поэтому сервису нужен прокси:HTTPS_PROXYв~/.env.secrets(сейчасhproxy.local:12334). Чат-модели Zen (/zen/v1/chat/completions) доступны без прокси — блокирован только systemone. - Ключ
OPENCODE_API_KEYдолжен быть в окружении процесса сервиса:~/.env.secretsсорсится из~/.bash_custom, сервис наследует окружение шелла, из которого его запустили. После правки.env.secrets:source ~/.env.secrets && opencode service restart— рестарт из старого шелла ключ не подхватит. - Jev нет в общем каталоге моделей OpenCode — это намеренно (не чат-модель), на плагин не влияет: он зовёт systemone endpoint напрямую.
Аудит и отладка
- Журнал решений:
~/.local/share/opencode/permission-reviewer-audit.jsonl— одна JSON-строка на ревью: вердикт, уверенность, причина, кто решал (decisionSource: system-one-reviewer / llm-reviewer / failure-safe). - Поле
reviewerEscalatedFromпоказывает, что первичный ревьюер (jev) сработал, но эскалировал. failure-safeвreason= ревьюер недоступен (нет ключа, 451, таймаут) — решение ушло в эскалацию.- Emergency brake: команды, пахнущие выносом креденшелов наружу
(
curl -H "Authorization: ..."), режутся детерминированно, мимо моделей.
Известные свойства
- Сессия, полная опасных команд в транскрипте, выглядит для ревьюера
подозрительно: jev начинает эскаловать всё подряд, и с
denyтакая сессия становится неработоспособной. Это fail-closed по замыслу. Лечение — работать в чистой сессии. - Тонкие пороги:
systemOneConfidenceThreshold(дефолт 0.4) — насколько уверенным должен быть jev, чтобы решать самому;systemOneReasoningThreshold(дефолт 0.38) — сколько эскалаций уходит на второе мнение.
Документация
- Плагин и все опции: https://github.com/warc0s/opencode-permission-reviewer (README на https://npm.io/package/opencode-permission-reviewer)
- Модель разрешений OpenCode V2: https://opencode.ai/v2/docs/permissions
- Jev у TypeSafe AI: https://jevmodel.org/ (есть прямой API с отдельным ключом
TYPESAFE_API_KEY— запасной маршрут, если Zen закроет systemone совсем)