Глава 04

Конфиг и разрешения

Если AGENTS.md задает смысл и правила проекта, то opencode.json задает механику. Именно здесь определяется, какие инструкции грузятся, какие subagents доступны, как работают разрешения и где проходит граница между «агенту можно доверять» и «здесь нужен контроль».

Почему opencode.json — это control plane

В документации OpenCode прямо сказано, что конфиги объединяются, а не заменяют друг друга. Это значит, что проектный opencode.json — не просто локальная настройка отдельного разработчика, а один из главных уровней repo-level truth. Он должен описывать не личные предпочтения, а то, как OpenCode должен вести себя в рамках конкретного репозитория.

Хороший проектный конфиг обычно задает как минимум четыре вещи: набор инструкций, ограничения на skills, правила работы встроенных primary agents и общую permission policy для чувствительных действий.

Минимально полезный конфиг

Самый важный базовый шаг — подключить не только AGENTS.md, но и проектные спецификации. Иначе агент знает «правила», но не знает реальный intent и контракты.

{
  "$schema": "https://opencode.ai/config.json",
  "instructions": [
    "AGENTS.md",
    "docs/specs/*.md"
  ]
}

Это уже сильный старт, потому что модель получает не только описание структуры проекта, но и содержание спецификаций, лежащих рядом с кодом.

Как это сделано в репозитории-примере

{
  "$schema": "https://opencode.ai/config.json",
  "instructions": [
    "AGENTS.md",
    "docs/specs/*.md"
  ],
  "permission": {
    "skill": {
      "*": "deny",
      "delivery-planning": "allow",
      "requirements-spec": "allow",
      "dbt-modeling": "allow",
      "python-etl": "allow"
    }
  },
  "agent": {
    "build": {
      "permission": {
        "task": {
          "*": "deny",
          "project-manager": "allow",
          "system-analyst": "allow",
          "data-engineer": "allow"
        },
        "bash": {
          "*": "allow",
          "git push*": "ask",
          "docker compose down*": "ask",
          "rm -rf *": "ask"
        }
      }
    }
  }
}

Этот пример хорошо показывает, что зрелый конфиг — это не только про модель или тему интерфейса. Он задает и knowledge layer, и orchestration layer, и safety layer.

Почему instructions важнее, чем кажется

Очень частая ошибка — пытаться засунуть всё знание проекта в один большой AGENTS.md. Но гораздо лучше использовать instructions как механизм композиции. Тогда AGENTS.md остается главным проектным контрактом, а спецификации, дополнительные гайды и другие durable instructions подключаются отдельно и не превращают один файл в нечитабельный монолит.

Для монорепозиториев и evolving products это особенно полезно: можно постепенно наращивать instruction layer, не ломая базовую структуру.

Разрешения: теория и практическая политика

Базовая модель разрешений в документации очень проста: allow, ask, deny. Но в реальном проекте важно решить не только «что вообще можно», а где проходит разумная граница доверия. Если всё открыто, вы быстро теряете контроль. Если всё через ask, вы получаете permission fatigue и начинаете подтверждать действия на автомате.

Тип действий Здоровый дефолт Почему
Read/search инструменты allow Без этого analysis phase становится мучительно медленным.
Обычные локальные правки allow или agent-specific Иначе build-mode начинает вязнуть на каждом изменении.
Внешние или опасные bash-команды ask / deny Push, destructive cleanup и остановка сервисов требуют отдельной осторожности.
Доступ к skills Whitelist Так агенту проще выбирать и меньше риск загружать неподходящие навыки.

Паттерн: позволять широкую работу, но страховать опасные границы

В проекте-примере выбран очень практичный компромисс: bash в целом разрешён, но отдельные рискованные шаблоны идут через ask. Это хороший баланс между скоростью и контролем.

"bash": {
  "*": "allow",
  "git push*": "ask",
  "docker compose down*": "ask",
  "rm -rf *": "ask"
}

Такая схема обычно работает лучше, чем полный запрет всего. Агент не вязнет на каждом harmless действии, но чувствительные операции всё еще требуют подтверждения.

Паттерн: ограничивать task routing

Еще одна сильная идея — использовать permission.task как routing guardrail. Это позволяет не только ограничивать, кого агент может вызвать, но и делать orchestration более ясным. В результате build-agent не расползается по всем возможным ролям, а работает в рамках заданного проектом маршрута.

"task": {
  "*": "deny",
  "project-manager": "allow",
  "system-analyst": "allow",
  "data-engineer": "allow"
}

Рекомендуемые defaults для команды

  • Всегда указывать $schema.
  • Подключать AGENTS.md и docs/specs/*.md через instructions.
  • Явно описывать whitelist для permission.skill.
  • Переопределять agent.build.permission хотя бы для опасных bash-patterns.
  • Использовать task permissions как механизм маршрутизации, а не только как ограничение безопасности.

Чего не стоит класть в project config

Плохая идея

Секреты

Не храните API keys напрямую в opencode.json. Лучше использовать env vars или file substitution.

Плохая идея

Всё знание в одном JSON

Не превращайте конфиг в склад инструкций. Конфиг должен оркестрировать, а не заменять собой docs и правила.