120 lines
9.5 KiB
Markdown
120 lines
9.5 KiB
Markdown
---
|
||
verdict: APPROVED # APPROVED | REQUEST_CHANGES — строго одно из двух, UPPERCASE
|
||
work_item: ORCH-109
|
||
stage: review
|
||
author_agent: reviewer
|
||
status: approved
|
||
created_at: 2026-06-14
|
||
model_used: claude-opus-4-8
|
||
type: review
|
||
work_item_id: ORCH-109
|
||
version: 3
|
||
---
|
||
|
||
# Review ORCH-109
|
||
|
||
## Summary
|
||
|
||
Две аддитивные изолированные правки подсистемы запуска (`launcher`) — **launch-стамп модели** в
|
||
`agent_runs.model` (D1/FR-1) и **поднятые per-role wall-clock бюджеты** developer/reviewer с
|
||
синхронным поднятием reaper (D3/D4/FR-3) — реализованы **корректно и точно по ADR**. Контракты
|
||
неприкосновенны: в `src/` изменены **только** `launcher.py` и `config.py`; ни одной строки
|
||
`STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / `_parse_*` / machine-verdict / `CREATE TABLE` /
|
||
`ALTER TABLE` в диффе нет (AC-9 верифицирован grep'ом по диффу). Зафиксированные маркер-инварианты
|
||
**ORCH-087** (стамп эффорта объединён в один `UPDATE`, `(effort or None)` сохранён) и **ORCH-065**
|
||
(reaper поднят синхронно `3600→5400`, `5400 > 3600+20=3620`) — целы. Покрытие исчерпывающее: новый
|
||
`tests/test_orch109_timeout_model.py` (TC-01…TC-12, детерминированный, без сети/CLI), обновлены
|
||
`tests/test_config.py` (reaper-дефолт 5400) и `tests/test_launcher.py` (лестница `_resolve_timeout`).
|
||
|
||
Независимая верификация reviewer'а: целевые тесты зелёные — `test_orch109_timeout_model.py` +
|
||
`test_config.py` + `test_launcher.py` = **75 passed**; зависимые подсистемы FR-2/FR-4
|
||
(`usage`/`notifications`/`tracker`) = **231 passed**. Полный регресс зелёный (см. `13-test-report.md`).
|
||
Открытых findings P0/P1/P2 нет → вердикт **APPROVED**.
|
||
|
||
## Оси проверки
|
||
|
||
1. **Соответствие ТЗ (02-trz / 03-acceptance):** FR-1…FR-6 реализованы; AC-1…AC-10 покрыты тестами
|
||
TC-01…TC-12 буквально по матрице AC↔FR.
|
||
- FR-1/AC-1 (TC-04): `_spawn` пишет резолвенную модель в `agent_runs.model` объединённым
|
||
`UPDATE agent_runs SET model=?, effort=? WHERE id=?` с `(model or None, effort or None, run_id)`
|
||
рядом со стампом эффорта; пустой резолв → `NULL`; стамп = `resolve_agent_model` (single source).
|
||
- FR-2/AC-2 (TC-06/07): `usage.record_usage` использует `model=COALESCE(?, model)` (сверено по
|
||
`src/usage.py`) — `usage=None`/`model=None` не затирает launch-стамп; непустая модель уточняет.
|
||
Кода `usage.py` PR не трогает (корректно — семантика уже верна), зафиксировано регресс-тестом.
|
||
- FR-3/AC-3 (TC-01/02): `_resolve_timeout` отдаёт поднятый бюджет developer/reviewer и неизменный
|
||
1800 прочим ролям (analyst/architect/tester/deployer/unknown/None); бюджеты конфигурируемы.
|
||
- FR-3/AC-4 (TC-03): малформный `agent_timeout_overrides_json` и непозитивный/нечисловой
|
||
выделенный ключ `[0,-5,"abc"]` → откат на глобальный дефолт + WARNING, never-break.
|
||
- NFR-4/AC-5 (TC-08): инвариант reaper подтверждён на shipped-дефолтах (`5400 > 3600+20`).
|
||
- FR-4/AC-6 (TC-09): строка стадии рендерит `· opus-4-8 · xhigh` для `exit_code=-9`; присутствует
|
||
negative-guard (немаркированный -9 → суффикс опущен).
|
||
- FR-4/NFR-6/AC-7 (TC-10): `get_running_agents` отдаёт модель для running-job (in-flight).
|
||
- FR-5/AC-8 (TC-11): timeout-killed прогон developer/reviewer не вызывает `_try_advance_stage`
|
||
(роутится в `_finalize_job`); присутствует позитивный контроль (clean exit → advance).
|
||
- AC-9 (TC-12) + AC-10: контракты/схема нетронуты; документация и регресс зелёные.
|
||
|
||
2. **Соответствие ADR (06-adr ADR-001 + сквозной adr-0040):** D1–D6 реализованы дословно. Лестница
|
||
`_resolve_timeout` (overrides_json → выделенный ключ роли → глобальный дефолт), выделенные ключи
|
||
`agent_timeout_developer_s=3600`/`agent_timeout_reviewer_s=3000`, `reaper_max_running_s` 3600→5400.
|
||
**Трассировка маркеров (TRACEABILITY):** правка касается блоков с маркерами ORCH-087 (стамп
|
||
эффорта) и ORCH-065 (reaper Tier-3) — оба зафиксированных инварианта сверены с их ADR и не
|
||
сломаны (эффорт-стамп сохранён в объединённом `UPDATE`; reaper-неравенство пересчитано и поднято
|
||
синхронно). Нарушений глобальных ADR нет.
|
||
|
||
3. **Качество кода:** never-raise сохранён (`try/except` + WARNING вокруг стамп-`UPDATE`;
|
||
непозитивный/нечисловой выделенный ключ → откат + WARNING). Докстринг `_resolve_timeout` и
|
||
паспорт-комментарии `config.py` точны. Тесты содержательны: изоляция стамп-сбоя (TC-05,
|
||
`_RaisingConn` бьёт только по launch-`UPDATE`), параметризация `[0,-5,"abc"]`, негативный guard
|
||
(TC-09b), позитивный контроль (TC-11c). **Регресс-тест-фиксатор инцидента ORCH-104** присутствует
|
||
(ORCH-019 BR-4 удовлетворён) — весь тест-файл пинит дефектное и исправленное поведение.
|
||
|
||
4. **Документация (приоритетная ось):** `src/` изменён → документация обновлена в том же PR
|
||
(golden source синхронизирован с кодом):
|
||
`CHANGELOG.md` / `CLAUDE.md` (паспорт) / `docs/architecture/README.md` (бюллет Agent Launcher +
|
||
ссылка на adr-0040) / `docs/architecture/internals.md` (оба упоминания «30 мин» → per-role) /
|
||
`README.md` front-page «### Watchdog» (per-role бюджеты + Tier-3 backstop 90м) / `.env.example`
|
||
(5 ключей agent-timeout + `ORCH_REAPER_MAX_RUNNING_S`=5400) / `config.py`-паспорт / детальный
|
||
ADR-001 + сквозной adr-0040. Обзорная витрина `docs/overview/` правки не требует — упоминания
|
||
watchdog концептуальны (sidecar-наблюдатель, «следит за процессом»), конкретного числа тайм-аута
|
||
витрина не несёт → устаревшего факта не возникает (ORCH-011/079 — нет finding). PR не закрывает
|
||
пункт `README.md` «Известные ограничения».
|
||
|
||
## Findings
|
||
|
||
### P0 — Blocker
|
||
- (нет)
|
||
|
||
### P1 — Must fix
|
||
- (нет)
|
||
|
||
### P2 — Should fix
|
||
- (нет)
|
||
|
||
### P3 — Nice-to-have
|
||
- [ ] ADR-001 (`status: proposed`) и adr-0040 (`Proposed`) на merge разумно перевести в `Accepted`
|
||
(косметика статуса ADR; на гейты/код не влияет, не блокер).
|
||
|
||
## Документация
|
||
|
||
**Обновлено в этом PR (golden source синхронизирован с кодом):**
|
||
- `CHANGELOG.md` — детальная запись ORCH-109 (`fix`, D1/D3/D4, FR-4/FR-5 структурно). ✅
|
||
- `CLAUDE.md` — паспорт (блок «Стек», абзац launcher). ✅
|
||
- `docs/architecture/README.md` — бюллет Agent Launcher (ссылка на adr-0040). ✅
|
||
- `docs/architecture/internals.md` — watchdog «30 мин» → per-role (стр. ~96 и ~262). ✅
|
||
- `README.md` — front-page «### Watchdog» (стр. ~295) → per-role бюджеты + Tier-3 backstop. ✅
|
||
- `.env.example` — новый блок agent-timeout (5 ключей) + `ORCH_REAPER_MAX_RUNNING_S` 3600→5400. ✅
|
||
- `src/config.py` — паспорт-комментарий ORCH-7/ORCH-109 + reaper-инвариант. ✅
|
||
- ADR — `docs/work-items/ORCH-109/06-adr/ADR-001-…` (детальный) + `docs/architecture/adr/adr-0040-…`
|
||
(сквозной). ✅
|
||
|
||
**Обзорная витрина `docs/overview/` (ORCH-011/ORCH-079):** правки не требует — упоминания watchdog
|
||
концептуальны, конкретного числа тайм-аута витрина не несёт, поэтому устаревшего факта не возникает.
|
||
|
||
**Прочее (не findings):**
|
||
- AC-9 верифицирован по диффу: в `src/` изменены только `launcher.py` и `config.py`; ни одной строки
|
||
`STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict/`CREATE TABLE`/`ALTER TABLE`.
|
||
- Целевой регресс reviewer'а зелёный: 75 (ORCH-109/config/launcher) + 231 (usage/notifications/
|
||
tracker) passed; полный регресс — `13-test-report.md`.
|
||
</content>
|
||
</invoke>
|