Kilo Code или OpenCode: перенос правил доступа — это перевод узкой политики Git-команд из YAML-блока permission в Markdown-агенте Kilo CLI в массив permissions файла opencode.jsonc OpenCode V2, где каждое правило описано полями action, resource и effect. Ниже — обе конфигурации целиком, таблица ожидаемых решений и разбор порядка правил.
Границы сравнения: Kilo CLI и OpenCode V2
Сравниваем две текущие CLI-поверхности: Kilo CLI и OpenCode V2. В документации Kilo Code правила доступа живут в Markdown-файлах агентов как YAML-frontmatter под ключом permission, а глобальные значения по умолчанию задаются в kilo.jsonc (kilo.ai/docs/customize/agent-permissions). В документации OpenCode V2 используется множественное число permissions и имена действий shell, subagent вместо bash, task (opencode.ai/v2/docs/permissions/).
Разные поля V1 и V2 — первое, что ломает механический перенос. Документация OpenCode прямо предупреждает: в V2 применяются permissions, shell и subagent, тогда как V1 использовал permission, bash и task. Если скопировать старый блок в новый файл, движок не увидит правил.
Второе различие — форма записи. Kilo описывает правило как одну строку действия или карту шаблонов: read: allow, edit: { "*": deny }. OpenCode V2 требует три строковых поля в каждом элементе массива: action, resource, effect. Одно и то же намерение «спрашивать перед любой shell-командой» в Kilo выглядит как bash: { "*": ask }, а в OpenCode V2 — как объект {"action": "shell", "resource": "*", "effect": "ask"}.
Третье — область действия. В Kilo пример ниже относится к конкретному Markdown-субагенту, а в OpenCode — к глобальному массиву permissions верхнего уровня. Это разные уровни конфигурации, и равенство их значений по умолчанию не предполагается.
Общий upstream и разные оболочки
Kilo Code и OpenCode выросли из общей инженерной линии CLI-агентов, но оформились как разные продукты с собственными файлами конфигурации. Kilo Code описывает себя как CLI с кастомными субагентами, которые запускаются в изолированных сессиях со своими промптами, моделями, доступом к инструментам и правами (kilo.ai/docs/customize/custom-subagents). OpenCode V2 публикует собственную схему прав с массивом permissions и встроенным сканером shell-команд (opencode.ai/v2/docs/permissions/).
Практический вывод для переноса: общая идея «последнее совпавшее правило побеждает» присутствует в обеих документациях, но синтаксис, имена полей и способ подключения файла различаются. Kilo подключает правила через Markdown-файл агента в .kilo/agents/, OpenCode — через opencode.jsonc в корне проекта.
Продуктовая оболочка определяет и способ проверки. В Kilo список агентов выводится командой kilo agent list, а вызов субагента выполняется упоминанием @git-review. В OpenCode проверка сводится к разбору самого файла конфигурации и порядка элементов массива.
Рекламный рейтинг здесь не нужен: обе поверхности решают одну задачу — ограничить набор команд, которые агент выполняет без подтверждения. Выбор зависит от того, в каком файле уже живёт ваша политика.
Kilo: Markdown-агент git-review
В Kilo правила пишутся в YAML-frontmatter Markdown-файла. Проектные агенты размещаются в .kilo/agents/, имя файла без расширения .md становится именем агента (kilo.ai/docs/customize/custom-subagents). Создайте файл .kilo/agents/git-review.md:
---
description: Учебная проверка Git-команд
mode: subagent
permission:
bash:
"*": ask
"git status *": allow
"git diff *": allow
"git push *": deny
---
Объясни, какие Git-команды разрешены в этой учебной копии.
Не выполняй push ради проверки.
Здесь mode: subagent делает агента вызываемым через Task tool или упоминание. Ключ permission содержит карту bash, где широкое правило "*": ask стоит первым, а конкретные исключения идут после него. Порядок критичен: документация Kilo указывает, что при совпадении нескольких правил побеждает последнее совпавшее (kilo.ai/docs/customize/agent-permissions).
Проверка выполняется в два шага. Команда kilo agent list показывает имя, режим и конфигурацию прав каждого агента, включая git-review. В сессии агент вызывается упоминанием @git-review — это создаёт подзадачу в изолированном контексте субагента с его промптом и правами.
Обратите внимание на разбор shell-команд. Kilo проверяет каждую разобранную команду в блоке: если блок содержит несколько команд, каждая значимая должна быть разрешена, а одна запрещённая отклоняет весь запрос. Пример из документации: при правилах "cd *": allow и "git *": deny команда cd "/project"; git status отклоняется, потому что git status совпадает с git *.
OpenCode V2: opencode.jsonc с permissions
В OpenCode V2 правила задаются массивом permissions в opencode.jsonc. Каждый элемент — объект с тремя строковыми полями: action (действие инструмента), resource (путь, команда, URL, запрос, ID навыка или агента) и effect (allow, deny, ask). При отсутствии совпадения OpenCode использует ask (opencode.ai/v2/docs/permissions/).
Создайте opencode.jsonc в корне проекта:
{
"$schema": "https://opencode.ai/config.json",
"permissions": [
{ "action": "shell", "resource": "*", "effect": "ask" },
{ "action": "shell", "resource": "git status *", "effect": "allow" },
{ "action": "shell", "resource": "git diff *", "effect": "allow" },
{ "action": "shell", "resource": "git push *", "effect": "deny" }
]
}
Документация OpenCode приводит похожий пример как типовую настройку: спрашивать перед shell-командами, разрешать рутинную инспекцию Git и блокировать push. Широкое правило resource: "*" стоит первым, конкретные исключения — после него. Последнее совпавшее правило побеждает, поэтому исключения должны идти после широкого правила.
Шаблоны используют простые подстановки на всё значение: * покрывает ноль или больше символов, включая /, ? — ровно один символ, остальное — литерал. Шаблон shell, оканчивающийся на *, совпадает и с командой без аргументов: git status * покрывает и git status, и git status --short.
Правила объединяются по порядку загрузки: сначала низкоприоритетная конфигурация, затем глобальные правила, затем правила агента. Правила агента добавляются после глобальных и не заменяют глобальный массив.
Таблица ожидаемых решений
Ниже — заполненная таблица для обеих конфигураций. Команды не запускаются: решения выведены из порядка правил в файлах выше.
| Команда | Kilo (permission.bash) |
OpenCode V2 (permissions) |
|---|---|---|
git status --short |
allow | allow |
git diff --stat |
allow | allow |
git push origin example |
deny | deny |
| неописанная команда | ask | ask |
cd "/project"; git status |
ask: cd попадает под * |
ask: cd попадает под * |
В этой строке показан результат только приведённых правил shell/bash; дополнительные политики и проверки каталогов учитываются отдельно.
В Kilo git status --short совпадает с git status * и получает allow. В OpenCode V2 та же команда совпадает с правилом resource: "git status *" и тоже получает allow. Push в обеих схемах блокируется явным deny.
Неописанная команда в Kilo попадает под широкое "*": ask и требует подтверждения. В OpenCode V2 неописанные команды спрашивают благодаря явно добавленному shell-правилу resource: "*" с эффектом ask. Базовая политика OpenCode начинает с allow для всех действий и ресурсов, поэтому удаление своего ask меняет результат; остальные действующие правила нужно учитывать отдельно.
Для составной команды cd "/project"; git status показанные правила дают ask: cd совпадает с общим правилом подтверждения, git status разрешён своим исключением. Запрет git * используется в отдельном примере документации Kilo выше; добавление этого запрета изменило бы результат.
Отрицательный случай: catch-all последним
Порядок правил — самая частая ошибка при переносе. Разберём отрицательный случай на копии конфигурации, не меняя рабочий файл. В Kilo переставим широкое правило "*": ask в конец блока bash:
permission:
bash:
"git status *": allow
"git diff *": allow
"git push *": deny
"*": ask
Документация Kilo описывает ровно этот эффект: если поставить catch-all последним, он переопределяет более раннее конкретное правило. В примере с uv * и * команда uv pip install ... начинает спрашивать, потому что последнее правило * тоже совпадает (kilo.ai/docs/customize/agent-permissions).
В OpenCode V2 действует тот же принцип: последнее совпавшее правило побеждает. Перестановка resource: "*" с эффектом ask в конец массива вернёт git status к запросу подтверждения, несмотря на более раннее правило allow.
Проверку выполняйте разбором правил вручную. Push не запускайте ради проверки: правило deny блокирует команду, но сама попытка отправки в удалённый репозиторий не нужна для подтверждения порядка. Достаточно проследить, какое правило совпадёт последним для каждой команды из таблицы.
Инструкции проекта, permissions и права хоста
Три уровня ограничений работают независимо. Инструкции проекта (файлы вроде AGENTS.md) задают, что агенту предписано делать. Инструментальные permissions в kilo.jsonc или opencode.jsonc определяют, какие вызовы инструментов разрешены, требуют подтверждения или блокируются. Права хоста — это полномочия пользователя операционной системы, от имени которого запущен процесс.
Документация OpenCode V2 прямо указывает: shell выполняется с файловой системой, процессами и сетевыми полномочиями пользователя хоста, а вывод директорий из текста команды носит характер best effort (opencode.ai/v2/docs/permissions/). Поэтому узкий allowlist shell-команд предпочтительнее шаблонов, рассчитанных на распознавание всех опасных команд.
Инструкции проекта не образуют песочницу. Файл AGENTS.md может предписывать агенту не трогать определённые каталоги, но это указание для модели. Реальное ограничение даёт только правило в конфигурации прав.
Полную read-only изоляцию такая настройка не обеспечивает. Настроен только shell/bash. Другие действия, дополнительные policies, сохранённые approvals и права пользователя хоста учитываются отдельно. В OpenCode V2 есть отдельный механизм policies, который может жёстко запретить проверку прав после применения правил и сохранённых подтверждений, превращая allow или ask в deny.
Различие grep resource и пути
Отдельная ловушка при переносе — действие grep. В OpenCode V2 поле resource для grep содержит регулярное выражение запроса. Это прямо указано в таблице действий и ресурсов: grep сопоставляется с запрошенным регулярным выражением.
Механический перенос path-pattern из Kilo здесь ломается. В Kilo файловые инструменты read, edit, write разрешают входной путь и проверяют права по пути относительно текущего worktree, поэтому шаблоны вида docs/* или src/generated/* осмысленны. В OpenCode V2 действие read использует location-relative внутренний путь или канонический абсолютный внешний путь, а grep — регулярное выражение.
Практический порядок: для grep в OpenCode V2 формулируйте правило по содержимому запроса. Правило для glob проверяет запрошенный шаблон отдельного вызова glob; оно не задаёт путевые ограничения для вызова grep. Для чтения файлов применяйте read с путём, а жёсткие границы доступа проверяйте отдельно для используемых инструментов.
В Kilo шаблоны используют глоб-сопоставление, а сопоставитель нормализует обратные слэши Windows в прямые перед сравнением. На Windows сопоставление регистронезависимо, на Unix-подобных системах — регистрозависимо. В конфигурации предпочтительны прямые слэши: они работают на обеих платформах.
Частые вопросы
Чем отличается permission в Kilo от permissions в OpenCode V2?
В Kilo ключ permission пишется в YAML-frontmatter Markdown-агента, а действие bash задаётся картой шаблонов. В OpenCode V2 используется массив permissions, где каждый элемент содержит поля action, resource и effect. Документация OpenCode предупреждает, что V1 применял permission, bash и task, а V2 использует permissions, shell и subagent.
Какое правило побеждает при совпадении нескольких?
В обеих схемах побеждает последнее совпавшее правило. В Kilo правила вычисляются в порядке конфигурации, и при совпадении нескольких правил выигрывает последнее. В OpenCode V2 правила объединяются по порядку загрузки, и последнее совпадение определяет результат. Поэтому широкие правила ставят первыми, а исключения — после них.
Почему git status снова спрашивает подтверждение?
Широкое правило с эффектом ask оказалось последним в списке и переопределило более раннее конкретное правило allow. В Kilo это происходит, если "*": ask стоит после "git status *": allow. В OpenCode V2 то же самое случится, если resource: "*" с эффектом ask окажется в конце массива.
Как проверить конфигурацию Kilo без запуска команд?
Выполните kilo agent list: команда показывает имя, режим и конфигурацию прав каждого агента, включая ваш git-review. В сессии вызовите агента упоминанием @git-review, чтобы создать подзадачу в изолированном контексте. Разбор порядка правил можно сделать вручную, не отправляя shell-команды.
Почему правило grep не срабатывает по пути?
В OpenCode V2 поле resource для действия grep содержит регулярное выражение запроса. Правило glob проверяет шаблон отдельного вызова glob; само по себе оно не ограничивает пути вызова grep. Для чтения файлов действует отдельное действие read с путём.
