- ключ Context7 подставляется через {env:...}: с ${env:...} в заголовок
уходил лишний $
- убраны устаревшие в V2 разрешения write и patch, их покрывает edit
- удалён слишком широкий шаблон *shadow*
- в permission-reviewer.md отмечено, что система отключена
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
75 lines
5.3 KiB
Markdown
75 lines
5.3 KiB
Markdown
# Система автоподтверждения разрешений (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) — сколько эскалаций уходит
|
||
на второе мнение.
|
||
|
||
## Документация
|
||
|
||
- Плагин и все опции: 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 совсем)
|