111 lines
7.2 KiB
Markdown
111 lines
7.2 KiB
Markdown
# 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 соблюдён.
|
||
</content>
|