work_item: ORCH-109 stage: analysis author_agent: analyst status: ready-for-review created_at: 2026-06-14 model_used: claude-opus-4-8 title: "Timeout budgets + launch-time model telemetry для developer/reviewer" framework: pytest scope: > Покрывает: launch-time стамп модели в agent_runs.model (FR-1), сохранение launch-стампа постфактум-enrich'ем (FR-2), конфигурируемый поднятый тайм-аут developer/reviewer без влияния на прочие роли (FR-3) + never-break на малформном конфиге, reaper-инвариант (NFR-4), видимость модели+эффорта в строке трекера при timeout-kill (FR-4) и in-flight в get_running_agents (NFR-6), guard анти-salvage — timeout-killed прогон не продвигает стадию (FR-5). Вне покрытия: model-routing, salvage недоделанной работы, изменения STAGE_TRANSITIONS/QG_CHECKS/схемы (их и не должно быть). notes: > Тесты детерминированы, без сети/LLM/subprocess Claude CLI: используют временную SQLite-БД и синтетические agent_runs-ряды; настройки подменяются через monkeypatch/override settings. Полный регресс tests/ должен оставаться зелёным; новый файл tests/test_orch109_timeout_model.py. Любой найденный разрыв в FR-5 закрывается guard'ом + тестом; если разрыва нет — TC-08 фиксирует существующую гарантию как анти-регресс. tests: - id: TC-01 type: unit description: "_resolve_timeout('developer') и ('reviewer') возвращают поднятый сконфигурированный бюджет" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-02 type: unit description: "_resolve_timeout для analyst/architect/tester/deployer возвращает глобальный agent_timeout_seconds (1800) — прочие роли не затронуты" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-03 type: unit description: "Малформный/невалидный timeout-конфиг -> _resolve_timeout откатывается на глобальный дефолт + WARNING, без исключения (never-break)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-04 type: integration description: "Launch стампит agent_runs.model: после стамп-блока _spawn строка прогона имеет model == resolve_agent_model(agent) (непустую), рядом с effort" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-05 type: unit description: "Стамп модели изолирован: сбой записи (битый conn) не пробрасывает исключение из launch-пути (never-raise, NFR-2)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-06 type: unit description: "record_usage(run_id, None) и record_usage с model=None НЕ затирают launch-стампнутую модель (COALESCE preserve, FR-2)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-07 type: unit description: "record_usage с непустой model в usage-JSON уточняет/проставляет agent_runs.model (enrich по-прежнему работает)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-08 type: unit description: "Sanity reaper-инварианта: reaper_max_running_s > max(резолвенный тайм-аут всех ролей) + agent_kill_grace_seconds (NFR-4)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-09 type: integration description: "Строка стадии трекера (_stage_line) для agent_runs с exit_code=-9 и launch-стампнутыми model+effort рендерит ' · · ' (model не null)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-10 type: integration description: "get_running_agents отдаёт непустую model для running-job с launch-стампнутой моделью (in-flight видимость /metrics /queue, NFR-6)" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-11 type: integration description: "Анти-salvage: прогон developer/reviewer с exit_code=-9 не продвигает стадию (development->review / review->testing) автоматически; следует retry/fail-пути" module: tests/test_orch109_timeout_model.py expected: PASS - id: TC-12 type: integration description: "Анти-регресс контрактов: STAGE_TRANSITIONS/QG_CHECKS/check_* и схема agent_runs не изменены (модель пишется в существующую колонку, миграции нет)" module: tests/test_orch109_timeout_model.py expected: PASS