Files
dotfiles/opencode/.config/opencode/permission-reviewer.md
T
Dmitry DementievandClaude Opus 5.5 4d3edc09ee fix(opencode): исправлена подстановка ключа Context7 и почищены разрешения
- ключ Context7 подставляется через {env:...}: с ${env:...} в заголовок
  уходил лишний $
- убраны устаревшие в V2 разрешения write и patch, их покрывает edit
- удалён слишком широкий шаблон *shadow*
- в permission-reviewer.md отмечено, что система отключена

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:37:23 +02:00

5.3 KiB
Raw Blame History

Система автоподтверждения разрешений (autoapprove)

Отключена. Эксперимент 2026-10-11 оказался малополезен, плагин снят из opencode.json. Итоги — docs/research/2026-10-11-opencode-permission-reviewer-autoapprove.md. Ниже — описание на случай, если систему решат вернуть.

Как была устроена подтверждение команд в OpenCode на этой машине, и где что искать.

Цепочка решений

Каждый ask из opencode.json проходит слои сверху вниз:

  1. Deny-паттерны (permission.bash в opencode.json) — мгновенный отказ по строке команды, до всяких моделей. Только секреты: *.env*, *.secrets*, ~/.ssh/* и т.п. Паттерны слепы к содержимому скриптов — это не рубеж, а только защита секретов.
  2. Jev (opencode/jev-1.13, System One) — типизированный ревьюер: получает команду, свидетельства из транскрипта и содержимое локальных скриптов (read-only enrichment), отвечает allow / deny / escalate.
  3. Второе мнение (opencode-go/glm-5.3-flash) — разбирает трудные случаи, где jev неуверен, но есть шанс на решение.
  4. Финал — 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) — сколько эскалаций уходит на второе мнение.

Документация