# BRD — ORCH-074: фикс модели агентов (мёртвый frontmatter → валидация имени) Work Item ID: ORCH-074 Эпик: ORCH-052 (слой 3), под-задача ORCH-52a Приоритет: **urgent** Тип: доработка механизма выбора модели агентов (self-modifying). ## 0. История ревизий - **rev.1 (08.06):** первичный пакет аналитики по фиксированному скоупу Славы. - **rev.2 (08.06, текущая):** задача возвращена стейкхолдером в In Progress. Проверены последние комментарии и описание issue в Plane — НОВЫХ субстантивных ответов/изменений скоупа нет (только bot-комменты + служебный маркер «Агент перезапущен с ответами стейкхолдера»). Скоуп остаётся прежним (G1 + G2 + опц. G4; G3 снят; эффорт не трогаем). Пакет переподтверждён против фактического кода (`launcher.py`, `config.py`); уточнён код-факт по G4: fallback читается напрямую на `launcher.py:374` мимо `resolve_agent_model`, поэтому валидация G2 должна покрыть и fallback (детали — ТЗ §4, AC-5, TC-11). ## 1. Контекст и проблема Каркас выбора модели агентов реализован в ORCH-041 и **работает корректно**: `src/agents/launcher.py::resolve_agent_model(agent, project_id)` резолвит модель по приоритету project-override → `ORCH_AGENT_MODEL_` → `agent_model_default` → CLI-дефолт. Все 6 агентов сейчас резолвятся в `claude-opus-4-8` (через `agent_model_default`). Аудит кода (08.06) выявил два дефекта данных/валидации (НЕ дефект механизма): - **P1. Лживый/мёртвый `model:` во frontmatter `.openclaw/agents/*.md`.** Все 6 промптов содержат `model:` в YAML-frontmatter: `claude-sonnet-4-6` (analyst, developer, tester, deployer) и `claude-opus-4-7` (architect, reviewer). launcher **НЕ читает** frontmatter `model:` — это мёртвая декларация, которая лжёт о реально используемой модели и нарушает принцип «документация = golden source». Мина: если кто-то «починит» launcher читать frontmatter → все агенты молча упадут на устаревшие модели. - **P2. Нет валидации ИМЕНИ модели.** В отличие от effort (есть `VALID_EFFORTS`-гард, невалидный effort логируется и дропается), имя модели не валидируется. Опечатка в `agent_model_*` / project-override → `--model <мусор>` → CLI падает или тихо деградирует. Нарушение принципа never-break. ## 2. Решение Славы (08.06) — фиксированный скоп > G3 model-routing **НЕ включаем** — ВСЕ 6 агентов остаются на `claude-opus-4-8`. > Скоп: **G1** (убрать лживый `model:` из frontmatter) + **G2** (валидация имени > модели, never-break) + **опц. G4** (`fallback_model` — на усмотрение архитектора, > НЕ routing). **Эффорт НЕ трогать.** AC-4 (routing) снят. ## 3. Бизнес-цели | ID | Цель | Драйвер | |----|------|---------| | G1 | Устранить лживый frontmatter: убрать `model:` из всех 6 `.openclaw/agents/*.md`. config — единственный источник правды модели. | Наблюдаемость (frontmatter не лжёт) | | G2 | Добавить валидацию имени модели: невалидное имя → лог + откат на default, никогда не передаётся в `--model`. | Надёжность (never-break) | | G4 | (опц., решает архитектор) Задать `agent_fallback_model` для страховки доступности. | Надёжность (availability) | ## 4. Не-цели (явно вне скоупа) - **G3 routing НЕ включаем.** Все 6 агентов остаются `claude-opus-4-8`. AC-4 снят. - **Эффорт НЕ трогать** — уже корректно настроен (`thinking → high`, `tester/deployer → medium`). - **Не менять resolve-механизм ORCH-041** — он корректен. Меняются только данные (frontmatter, опц. config) + добавляется валидация. - **Не трогать non-self поведение** — per-project override (`projects.py agent_models`) для enduro-trails остаётся рабочим. ## 5. Заинтересованные стороны - **Owner (Слава)** — зафиксировал скоп; деплой через штатный «Confirm Deploy». - **Агенты оркестратора** — потребители resolve-механизма (self-hosting). - **Проект enduro-trails** — НЕ должен пострадать (общий инстанс/БД/очередь). ## 6. Риски и инварианты - **Self-hosting:** изменение применяется к БУДУЩИМ запускам агентов. НЕ ломать текущий конвейер; не ронять прод-контейнер. Деплой только через «Confirm Deploy». - **never-break:** невалидная модель/эффорт НЕ должны ронять запуск агента — деградация на default/CLI-дефолт + лог. - **frontmatter автогенерация:** убедиться, что инструмент (если автогенерит frontmatter) не вернёт `model:` обратно. Frontmatter остаётся описательным (`name`/`description`/`tools`). - **enduro per-project override** не должен сломаться валидацией (валидные имена проходят без изменения поведения). ## 7. Бизнес-эффект - Frontmatter перестаёт лгать → меньше риск «починки», ломающей агентов. - Опечатка в имени модели больше не роняет/деградирует запуск агента. - (опц.) fallback повышает доступность при перегрузке основной модели.