--- type: review work_item_id: ORCH-087 verdict: APPROVED version: 1 --- # Review ORCH-087 ## Summary Задача закрывает три проблемы live-трекера: (G1) осиротевшие «замёрзшие» карточки, (BR-EFF) эффорт в строке стадии, (BR-G5) честное итоговое время, плюс попутный CI-фикс пути per-run логов. Реализация соответствует ТЗ, ADR-001 и критериям приёмки. Все 1090 тестов зелёные. Документация (CLAUDE.md, README.md, docs/architecture/README.md, CHANGELOG.md, ADR) обновлена в том же PR. Машина стадий и реестр QG не тронуты; миграции аддитивны/идемпотентны; never-raise сохранён. Найдена одна косметика P3 (неточный inline-комментарий), не влияющая на поведение. Блокеров нет. ## Соответствие ТЗ / ADR - **G1 (BR-G1, AC-1.x):** аддитивный леджер `tracker_messages(task_id, message_id, created_at, deleted_at)` + хелперы `add_tracker_message` / `get_open_tracker_messages` / `mark_tracker_message_deleted` (`src/db.py`). На каждом bump зачищаются ВСЕ незакрытые mid (union скаляр+леджер). Контракт `delete_telegram` (True=gone вкл. `_DELETE_GONE_MARKERS`, False=transient) совпадает с логикой `if delete_telegram(old): mark_deleted(...)`; transient остаётся открытым для ретрая. Новый mid в леджер ТОЛЬКО при `send is not None` (R-3/BR-6). Скаляр `tracker_message_id` сохранён (BC). ✔ соответствует ADR §G1 (вариант A1). - **G3 (AC-3.x):** ключ `confirm_deploy` добавлен в `_LIVE_BRANCH_LABELS` — цикл `Awaiting Deploy → Deploying → Confirm Deploy → Monitoring → Done` полон. ✔ - **BR-EFF (AC-E.x):** колонка `agent_runs.effort TEXT` (`_ensure_column`, идемпотентно); стамп фактического `resolve_agent_effort` в `launcher._spawn` через `UPDATE` по `run_id` (never-block, обёрнут try/except); рендер `· {model} · {effort}`, пустой → опускается. ✔ - **BR-G5 (AC-5.x):** done-строка переписана на три подписанных метрики `⏱️ Агенты · твоё{~cap} · общее с ожиданием`; кап `tracker_brd_review_cap_s` (дефолт 2ч, маркер `~`); `_capped_review_str` never-raise; agent-сумма не регрессировала. ✔ - **BR-G6 (AC-6.x):** `src/reconciler.py` / `tests/test_reconciler.py` НЕ тронуты; `git merge-base --is-ancestor origin/main HEAD` → true; origin/main содержит merge ORCH-086; маркеры ORCH-086 (`skipped_terminal_total`/`state_uuid`/terminal) на месте. ✔ - **Инварианты (AC-X.5):** `STAGE_TRANSITIONS` / `QG_CHECKS` без изменений; миграции `CREATE TABLE/INDEX IF NOT EXISTS` + `_ensure_column` — аддитивны/идемпотентны (enduro не трогается); `disable_notification` / `plane_issue_link` / `disable_web_page_preview` — сохранены. ✔ - **ADR (AC-0.x):** ADR-001 отвечает на 4 вопроса §4 BRD, содержит таблицу staging- воспроизведения и known-limitation Telegram 48ч (AC-1.4). Код фикса соответствует ADR. ✔ ## Findings ### P0 — Blocker - (нет) ### P1 — Must fix - (нет) ### P2 — Should fix - (нет) ### P3 — Nice to have - [ ] `src/notifications.py` (~стр. 460, докстринг блока рендера эффорта): комментарий утверждает «Historical rows with NULL effort fall back to the config-resolved effort for the agent», но `_run_effort` фолбэка на `resolve_agent_effort` НЕ делает — при пустом/NULL effort возвращает `""` и суффикс опускается. Поведение корректно и соответствует AC-E.4 (fallback по ТЗ §5 был «Допустим», не обязателен); неточен лишь комментарий — стоит убрать вводящую в заблуждение фразу или реально добавить фолбэк. Не влияет на работу. ## Документация Обновлена в ТОМ ЖЕ PR (AC-X.3 выполнен): - `CLAUDE.md` — §Нотификации/Telegram live-tracker (зачистка сирот, эффорт, честное время). - `docs/architecture/README.md` — компонент Notifications + отдельный раздел ORCH-087. - `README.md` — таблица env (`ORCH_RUNS_DIR`). - `CHANGELOG.md` — `## [Unreleased]` запись (ORCH-087 трекер + CI-фикс пути логов). - ADR `06-adr/ADR-001-tracker-orphan-cleanup.md` — присутствует, покрывает G0/механизм/формулу. Замечаний по документации нет.