chore(opencode): эксперимент с permission-reviewer — итоги и отключение
Плагин настроен и проверен (jev через Zen + прокси, enforce+deny), но признан не стоящим использования: хрупкая цепочка, нервные эскалации, запертая сессия. Запись в opencode.json отключена (закомментирована), выводы — в docs/research/.
This commit is contained in:
1 parent
9f6db963be
commit
16e85139b9
4 files changed
+165
-11
No files matched your search
@@ -0,0 +1,75 @@
|
||||
# Эксперимент: ИИ-ревьюер разрешений в OpenCode (autoapprove)
|
||||
|
||||
**Дата:** 2026-10-11
|
||||
**Статус:** эксперимент закрыт, плагин снят. Документ сохранён как описание
|
||||
системы и причин отказа — если идея вернётся, начинать отсюда.
|
||||
|
||||
## Итог одним абзацем
|
||||
|
||||
Плагин `opencode-permission-reviewer` (LLM-ревьюер каждого `ask`) настроен и
|
||||
работоспособен, но признан не стоящим использования: хрупкая цепочка (ключ в
|
||||
окружении сервиса → региональный 451 на endpoint jev → прокси), плюс ревьюер
|
||||
нервно эскалует всё подряд в сессиях с «опасным» транскриптом. Боевой режим:
|
||||
`permission: autoaccept` + deny-паттерны на секреты + snapshots/git как
|
||||
обратимость. AFK для системного администрирования не достигнут: узкое место —
|
||||
не разрешения, а компетентность модели-исполнителя (glm flash провалил простые
|
||||
админские задачи: «делал странное с умным видом»).
|
||||
|
||||
## Как была устроена система
|
||||
|
||||
Цепочка решений для каждого `ask` из `opencode.json`:
|
||||
|
||||
1. **Deny-паттерны** (`permission.bash`) — мгновенный отказ по строке команды,
|
||||
до моделей. Только секреты: `*.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`: `manual` (спросить человека; при
|
||||
`permission=autoaccept` на него отвечает auto) или `deny` (отказ с причиной).
|
||||
`enforcementMode`: `observe` (только аудит, дефолт) или `enforce`.
|
||||
|
||||
## Инфраструктурные грабли (главная ценность эксперимента)
|
||||
|
||||
- Jev ходит на отдельный endpoint Zen `/zen/v1/systemone`. Zen закрывает его
|
||||
по региону (HTTP 451) — нужен прокси в окружении сервиса
|
||||
(`HTTPS_PROXY` в `~/.env.secrets`). Чат-модели Zen
|
||||
(`/zen/v1/chat/completions`) доступны без прокси; блокирован только
|
||||
systemone. Jev нет в общем каталоге моделей — это намеренно (не чат-модель),
|
||||
на плагин не влияет.
|
||||
- `OPENCODE_API_KEY` должен быть в окружении **процесса сервиса**. Сервис
|
||||
наследует окружение шелла, из которого запущен; после правки
|
||||
`~/.env.secrets` нужны `source` + рестарт из свежего шелла. Рестарт из
|
||||
старого шелла ключ не подхватывает.
|
||||
- Ревьюер зовётся из серверного процесса: рестарт сервиса из сессии агента
|
||||
рвёт саму сессию.
|
||||
- Emergency brake: команды, пахнущие выносом креденшелов
|
||||
(`curl -H "Authorization: ... $KEY"`), режутся детерминированно.
|
||||
- Конфиг плагина читается с O_NOFOLLOW: симлинк молча игнорируется, деплой
|
||||
только копией (см. `.stow-local-ignore`).
|
||||
|
||||
## Известные свойства поведения
|
||||
|
||||
- Сессия, полная опасных команд в транскрипте, выглядит для ревьюера
|
||||
подозрительно: jev эскалует всё подряд, и с `escalationMode: deny` такая
|
||||
сессия становится неработоспособной — fail-closed по замыслу.
|
||||
- В этой сессии это проявилось полностью: заперт даже `git status`, отменить
|
||||
отказы изнутри сессии нельзя (явное разрешение в чате не помогло).
|
||||
- Пороги тонкой настройки (не крутились): `systemOneConfidenceThreshold`
|
||||
(дефолт 0.4), `systemOneReasoningThreshold` (дефолт 0.38),
|
||||
`confidenceThreshold` (чат-ревьюер, 0.7).
|
||||
- Установлено про авто-подтверждение без плагина: ручное approve при серии
|
||||
запросов вырождается в слепое «да» — честный auto + обратимость лучше
|
||||
декоративного ручного.
|
||||
|
||||
## Ссылки
|
||||
|
||||
- Плагин и все опции: https://github.com/warc0s/opencode-permission-reviewer
|
||||
(README: https://npm.io/package/opencode-permission-reviewer)
|
||||
- Модель разрешений OpenCode V2: https://opencode.ai/v2/docs/permissions
|
||||
- Jev: https://jevmodel.org/ (прямой API TypeSafe с ключом `TYPESAFE_API_KEY` —
|
||||
запасной маршрут мимо Zen)
|
||||
- Аудит решений (на машине): `~/.local/share/opencode/permission-reviewer-audit.jsonl`
|
||||
- Снятый конфиг сохранён закомментированным в `opencode/.config/opencode/opencode.json`
|
||||
Reference in new issue
Block a user