diff --git a/tasks/orchestrator/DEV_TASK_ORCH109_TIMEOUT_MODEL_TELEMETRY.md b/tasks/orchestrator/DEV_TASK_ORCH109_TIMEOUT_MODEL_TELEMETRY.md new file mode 100644 index 0000000..f34cea4 --- /dev/null +++ b/tasks/orchestrator/DEV_TASK_ORCH109_TIMEOUT_MODEL_TELEMETRY.md @@ -0,0 +1,136 @@ +# DEV TASK: ORCH-109 timeout budgets + launch-time model telemetry + +**Статус:** Ready for dev +**Проект:** orchestrator +**Фаза:** hotfix / resilience +**BRD:** Plane ORCH-109 + +--- + +## Цель + +Сделать так, чтобы developer/reviewer не умирали на тяжёлых задачах от слишком короткого watchdog timeout, а telemetry/tracker всегда показывали реальную модель даже для run без финального usage JSON. + +## Архитектура + +Фикс делится на два слоя. Слой 1 — конфигурационный: увеличить timeout budget per-agent override для developer/reviewer, не меняя поведение остальных ролей. Слой 2 — кодовый: resolved model должен штамповаться в `agent_runs.model` в момент launch, рядом с `effort`, а post-run parse usage/model должен остаться enrich-слоем, а не единственным источником истины. + +Нужен минимальный, surgical change без перестройки pipeline. Важно не сломать текущую логику usage parsing, tracker render и retry/fail contracts. + +## Стек / Зависимости + +- Python 3 +- SQLite +- Claude CLI launcher +- Existing orchestrator tests + +--- + +## Инфраструктура + +| Параметр | Значение | +|----------|----------| +| Сервер | `slin@82.22.50.71` | +| Рабочая директория | `/home/slin/repos/orchestrator/` | +| Деплой | git commit в feature branch, стандартный pipeline/PR | +| URL | Plane project ORCH / prod orchestrator container | + +--- + +## Файловая карта + +| Действие | Файл | Ответственность | +|----------|------|-----------------| +| Изменить | `src/agents/launcher.py` | stamp resolved model at launch; optional timeout/review guard if needed | +| Изменить | `src/config.py` | document/possibly support timeout overrides behavior if test gaps found | +| Изменить | `src/usage.py` | keep model enrich non-destructive, no regression | +| Изменить | `src/notifications.py` | tracker/status rendering should use stamped model on timeout runs | +| Изменить | `tests/*` | cover launch-time model stamp and timeout/tracker behavior | +| Изменить | docs if relevant | config/docs update | + +--- + +## Задачи + +### Task 1: Launch-time model stamp + +**Файлы:** +- Изменить: `src/agents/launcher.py` +- Проверить: `src/usage.py`, `src/notifications.py` + +**Шаги:** + +- [ ] **1.1** Найти место, где в `_spawn()` уже резолвятся `model` и `effort`. +- [ ] **1.2** В этот же момент записать `model` в `agent_runs.model` (resolved model or `NULL` if intentionally omitted and CLI default is used). +- [ ] **1.3** Не ломать существующий `record_usage(... model=COALESCE(?, model) ...)`: post-run parse должен только дополнять/уточнять, но не затирать launch-time truth на `NULL`. +- [ ] **1.4** Убедиться, что timeout-killed run с пустым логом всё равно имеет `agent_runs.model` и `effort`. + +**Критерий готовности:** run, умерший без финального JSON, имеет непустой `model` в `agent_runs`, если модель была резолвнута при запуске. + +--- + +### Task 2: Timeout budgets for developer/reviewer + +**Файлы:** +- Изменить: `src/config.py` (если нужно только docs/tests — ок) +- Изменить: tests around timeout resolve if present + +**Шаги:** + +- [ ] **2.1** Проверить текущую механику `agent_timeout_overrides_json` в `Launcher._resolve_timeout()`. +- [ ] **2.2** Если тестового покрытия нет — добавить. +- [ ] **2.3** Зафиксировать в docs/комментариях expected prod usage: developer/reviewer overrides above global default. + +**Критерий готовности:** override budget для developer/reviewer читается предсказуемо и покрыт тестом. + +--- + +### Task 3: Tracker / status resilience on timeout runs + +**Файлы:** +- Изменить: `src/notifications.py` +- Проверить: `src/usage.py` +- Тесты: relevant tracker rendering tests + +**Шаги:** + +- [ ] **3.1** Проверить рендер stage line для случая `exit_code=-9/143`, empty usage, model stamped at launch. +- [ ] **3.2** Добавить/обновить тест: timeout run shows `model · effort` and does not render `null`. +- [ ] **3.3** Если текущий flow после timeout developer автоматически уводит задачу дальше в review по багу, локализовать root cause и предложить отдельным коммитом в этой же ветке только если изменение маленькое и безопасное. Если нет — зафиксировать в отчёте как отдельный follow-up. + +**Критерий готовности:** tracker/comment для timeout run не показывает `null model`. + +--- + +## Проверка (Acceptance) + +| # | Проверка | Команда / Действие | Ожидаемый результат | +|---|----------|-------------------|---------------------| +| 1 | Unit/integration tests | `cd /home/slin/repos/orchestrator && pytest -q` | Тесты на изменённые области проходят | +| 2 | Launch-time stamp | тест/inspection для `_spawn()` | `agent_runs.model` заполнен сразу после launch | +| 3 | Timeout render | tracker render test на timeout run | Видно short model name + effort, не `null` | +| 4 | No usage JSON fallback | simulated empty log / `record_usage(None)` | launch-time model не теряется | +| 5 | Docs/config | inspect changed docs/comments | override usage documented | + +--- + +## Ограничения и контекст + +- ⚠️ НЕ ломать текущий `record_usage(... COALESCE(?, model) ...)` без причины — он уже защищает от затирания `model` на `NULL`. +- ⚠️ НЕ менять retry/fail contract без необходимости; timeout semantics (`-9`, watchdog) завязаны на pipeline. +- ⚠️ Изменения должны быть минимальные, не архитектурный рефакторинг. +- ⚠️ Продовый инцидент-референс: ORCH-104, runs `658`, `659`, `660`; developer/reviewer убивались watchdog’ом на 1800s. +- 🚫 Не трогать unrelated Plane/webhook/gitea logic. + +--- + +## Деплой-чеклист + +- [ ] Код написан и тесты на затронутый участок проходят +- [ ] Документация/комментарии обновлены +- [ ] Нет регрессии в tracker/status rendering +- [ ] Отчёт с перечислением изменённых файлов и прогоном тестов приложен + +--- + +*Создано: 2026-06-13 | Автор ТЗ: Стрим | Исполнитель: Dev-агент*