# 02 — ТЗ: ORCH-081 (ORCH-52h) **Work Item:** ORCH-081 · **Тип:** багфикс конфигурации · **Repo:** orchestrator Документ описывает ТРЕБУЕМОЕ ПОВЕДЕНИЕ и затронутые модули. Конкретный механизм (field_validator vs изменение резолвера) — на усмотрение архитектора; ниже зафиксированы инварианты, которым любая реализация обязана удовлетворять. ## 1. Задействованные модули | Модуль | Роль в задаче | |--------|----------------| | `src/config.py` (`Settings`) | дефолты эффорта; устойчивость к пустому env (ядро фикса) | | `src/agents/launcher.py` | `resolve_agent_effort` / `_resolve_agent_attr` (цепочка резолва), `VALID_EFFORTS`, сборка `--effort` в `_spawn` | | `.env.example` | канон-шаблон значений эффорта по ролям | | `docs/architecture/README.md` | таблица «Модель и эффорт по ролям» (строки ~47–54) | | `CHANGELOG.md` | запись о фиксе | | `tests/test_resolve_agent_effort.py` | расширить кейсами пустого env | ## 2. Корень бага (точная механика) `launcher._resolve_agent_attr` (строки ~104–114): ``` per_agent = getattr(settings, f"agent_effort_{agent}", "") # '' в проде -> falsy -> skip default = getattr(settings, "agent_effort_default", "") # '' в проде -> falsy -> skip return "" # уровень 4: без флага ``` Pydantic: `ORCH_AGENT_EFFORT_*=` (пустая строка в env) перебивает дефолт класса → поле `= ''`. Поскольку пустым оказывается **и** `agent_effort_default`, у резолва нет непустого «пола» для отката → `''` → `--effort` не передаётся. ## 3. Требования к фиксу (вариант c) ### FR-1. Непустой floor на каждую роль при пустом env При ЛЮБОЙ комбинации пустых `ORCH_AGENT_EFFORT_*` (включая `ORCH_AGENT_EFFORT_DEFAULT=`) `resolve_agent_effort(agent)` обязан вернуть целевое непустое значение для каждой из 6 ролей: | agent | результат | |-------|-----------| | analyst | `high` | | architect | `high` | | developer | `xhigh` | | reviewer | `high` | | tester | `medium` | | deployer | `medium` | Замечание для реализации: floor должен быть **per-role**, а не единым на default — иначе пустой `ORCH_AGENT_EFFORT_TESTER=` снапнется на `high` вместо `medium`. Т.е. «пустая строка трактуется как не-задано» применяется так, чтобы каждая роль получала СВОЙ канонический дефолт, а не общий. ### FR-2. Приоритет резолва сохраняется Порядок не меняется: project-override (`projects_json.agent_efforts`) > per-agent env > default > floor. Непустой явный env/override по-прежнему ПОБЕЖДАЕТ floor (оператор может осознанно задать, напр., `ORCH_AGENT_EFFORT_DEVELOPER=high`, и это применится). ### FR-3. Валидация невалидного значения не регрессирует Значение вне `VALID_EFFORTS` (`low|medium|high|xhigh|max`) по-прежнему логируется (`logger.warning`) и **дропается** → `''` (без флага). Floor НЕ должен «спасать» явную опечатку (`turbo`/`ultra`) — поведение ORCH-41 сохраняется (never-break, мусор не уезжает в CLI). ### FR-4. `developer → xhigh` зафиксирован явно `config.py`: `agent_effort_developer` со значением `xhigh` (сейчас `high`). `.env.example`: `ORCH_AGENT_EFFORT_DEVELOPER=xhigh` (сейчас `high`) + правка комментария про split (developer теперь xhigh, не в группе «thinking → high»). ### FR-5. `xhigh` принимается CLI-слоем Подтвердить, что `xhigh` присутствует в `VALID_EFFORTS` (`src/agents/launcher.py:22` — уже `frozenset({"low","medium","high","xhigh","max"})`, **присутствует**; добавления не требуется, только верификация тестом). Эффорт реально собирается в команду: `_spawn` строит `effort_flag = f"--effort {effort} "` при непустом `effort` (строка ~434) — путь проброса не менять, только убедиться тестом сборки флага. ## 4. Изменения API / схемы БД - **API endpoints:** нет. - **Схема БД:** нет. - **Конфиг (env-контракт):** значения `ORCH_AGENT_EFFORT_*` неизменны по ИМЕНАМ; меняется лишь дефолт `developer` (high → xhigh) и устойчивость к пустым значениям. Обратная совместимость: непустой явный env работает 1:1 как раньше. ## 5. Требования к QG checks Новых QG checks не требуется. Гейты конвейера не затрагиваются. ## 6. Артефакты pipeline (обновить в ТОМ ЖЕ PR) - `src/config.py` — дефолт developer + устойчивость к пустому env. - `src/agents/launcher.py` — если фикс кладётся в резолвер (на усмотрение архитектора). - `.env.example` — `ORCH_AGENT_EFFORT_DEVELOPER=xhigh` + правка комментария split. - `docs/architecture/README.md` — таблица эффорта: developer `high` → `xhigh`; при необходимости — ремарка про floor/устойчивость к пустому env. - `CHANGELOG.md` — запись (`fix:`). - `tests/test_resolve_agent_effort.py` — новые кейсы (см. 04-test-plan.yaml). ## 7. Операционная часть (вне PR-кода, для деплой-лога) - Реальные значения — в прод-`.env` на хосте (gitignored). Рекомендуется привести прод-`.env` к каноне `.env.example` (developer=xhigh, остальные непустые), НО фикс обязан работать и без этого (FR-1). Не коммитить секреты/хост-env в git. - Деплой — через `deploy-staging` (8501) → `Confirm Deploy`. Прод-контейнер не ронять вне штатного хука. ## 8. Definition of Done AC-1…AC-5 из `03-acceptance-criteria.md` выполнены; `pytest -q` зелёный; документация (README + `.env.example` + CHANGELOG) синхронизирована в том же PR; never-break соблюдён.