--- work_item: ORCH-091 stage: analysis author_agent: analyst status: ready-for-review created_at: 2026-06-09 model_used: claude-opus-4-8 --- # 02 — ТЗ (TRZ): ORCH-091 — Карточка трекера: полнота карты статусов, отражение откатов, суммирование метрик по попыткам Work Item: **ORCH-091** · Repo: **orchestrator** · Стадия: analysis > ТЗ описывает **конкретные изменения к реализации**, выведенные из BRD и фактического кода. > Архитектурное обоснование/решения (выбор ordering-источника для отката, форма агрегата > метрик, явный лейбл для `cancelled`) — задача архитектора (`06-adr/`). ## 1. Сводка изменения Три точечные правки в `src/notifications.py` (рендер live-карточки ORCH-067), все аддитивные, без изменения транспорта, схемы БД, `STAGE_TRANSITIONS` и `QG_CHECKS`: 1. **Полнота карты статусов (Деф.1).** `_STAGE_STATUS_LABEL` должен покрывать все ключи `STAGE_TRANSITIONS` (источник истины — `src/stages.py`), добавить `deploy-staging` → осмысленный staging-лейбл; нейтральный фолбэк вместо «To Analyse» для неизвестной стадии. 2. **Отражение откатов (Деф.2).** Цикл рендера строк стадий перестаёт показывать `✅` для стадий, расположенных ПОСЛЕ текущей позиции задачи в конвейере. 3. **Суммирование метрик стадии (Деф.3).** Строка стадии агрегирует ВСЕ `agent_runs` агента стадии (Σ стоимость/токены/время) вместо последнего прогона; тоталы сходятся с `SUM`. ## 2. Задействованные модули / пути | Путь | Действие | |------|----------| | `src/notifications.py` | изменить: `_STAGE_STATUS_LABEL` (~940), `_DEFAULT_STATUS_LABEL` (~950), `plane_status_label` (~990), `render_task_tracker` (рендер строк стадий ~474–505, агрегат метрик ~388–404 / `_stage_line` ~445–466) | | `src/stages.py` | **только чтение** — импорт ключей `STAGE_TRANSITIONS` как источника истины для полноты карты (НЕ изменять) | | `tests/test_tracker_status_line.py` | изменить/дополнить: полнота карты, staging-лейбл, нейтральный фолбэк | | `tests/test_telegram_tracker.py` (или новый `tests/test_tracker_rollback_metrics.py`) | дополнить/создать: откат + суммирование метрик | | `CHANGELOG.md` | изменить: запись ORCH-091 | ## 3. Функциональные требования ### FR-1 — Полнота `_STAGE_STATUS_LABEL` по `STAGE_TRANSITIONS` (BR-1) - Для каждого ключа `STAGE_TRANSITIONS` (`created, analysis, architecture, development, review, testing, deploy-staging, deploy, done, cancelled`) `plane_status_label` возвращает непустой осмысленный лейбл. - Полнота гарантируется **программно** от единого источника `src/stages.py::STAGE_TRANSITIONS` (итерация/проверка пересечения ключей), а не статичным дублирующим списком (NFR-3). - Сохранить спецветки `plane_status_label`: `analysis` + открытый brd-clock → `_IN_REVIEW_LABEL` (без изменений). ### FR-2 — Staging-лейбл для `deploy-staging` (BR-2) - `stage='deploy-staging'` → осмысленный лейбл (предлагается «Deploying (staging)» или «⏳ Staging»; финальный текст согласует архитектор с моделью статусов ORCH-066/059). - НЕ равен «To Analyse» и НЕ равен лейблу `deploy` (`⏸️ Awaiting Deploy …`). ### FR-3 — Нейтральный фолбэк (BR-3) - Для строки `tasks.stage`, отсутствующей в карте (истинно неизвестная/битая/будущая стадия), `plane_status_label` возвращает нейтральный лейбл (напр. «В работе» или капитализированный stage), НЕ «To Analyse». - `created` сохраняет осмысленный «To Analyse» как реальный первый статус. - `plane_status_label` остаётся never-raise (любой сбой → безопасный лейбл). ### FR-4 — Отражение откатов в строках стадий (BR-4) - В `render_task_tracker` строка `✅ <стадия>` НЕ отрисовывается для стадии, позиция которой в конвейере ПОЗЖЕ текущего `tasks.stage`, даже если у её агента есть завершённый `agent_run`. - Текущая стадия рисуется активной (`🔄`) по существующей логике `is_active_stage`. - Стадии ДО текущей позиции (фактически пройденные) сохраняют `✅` со своими метриками. - Источник порядка стадий — конвейер `STAGE_TRANSITIONS` (а не индекс в `_TRACKER_STAGES`); конкретный механизм определения позиции — за архитектором. Учесть, что `deploy-staging` отсутствует в `_TRACKER_STAGES` и `_STAGE_ACTIVE_AGENT` (обе стадии staging/deploy → агент `deployer`): решение не должно ломать существующий рендер строки «Внедрение». ### FR-5 — Суммирование метрик стадии по попыткам (BR-5) - Строка стадии показывает СУММУ по всем `agent_runs` агента стадии (по `task_id`): - 💰 стоимость = `Σ cost_usd`; - 🔢 токены = `Σ (input_tokens + output_tokens + cache_read_tokens + cache_creation_tokens)` (вход — через существующий `_input_total`; формат строки `↓/↑` сохранить); - ⏱ время = `Σ _duration_seconds(started_at, finished_at)` по всем прогонам стадии. - Тоталы задачи (💰/🔢/⏱ Агенты) остаются суммой по всем стадиям/попыткам и сходятся с `SUM(agent_runs)` по `task_id` (инвариант сходимости). - Модель/эффорт/счётчик «попытка N» в строке стадии сохранить (ORCH-087): при N≥2 показывать актуально (модель — допускается из последнего прогона; согласовать с архитектором). ## 4. Изменения API Нет. Эндпоинты не затрагиваются (рендер карточки вызывается из конвейера). Диагностический блок `GET /queue` не меняется. ## 5. Изменения схемы БД Нет. Используются существующие колонки `agent_runs` (`cost_usd`, `input_tokens`, `output_tokens`, `cache_read_tokens`, `cache_creation_tokens`, `started_at`, `finished_at`, `agent`, `task_id`, `exit_code`) и `tasks` (`stage`, `brd_review_started_at/ended_at`). ## 6. Требования к новым/изменённым QG checks Нет. `QG_CHECKS` / `check_*` / `_parse_*` / `STAGE_TRANSITIONS` не затрагиваются. Изменение касается только слоя индикации (карточка), не управляющего слоя конвейера. ## 7. Совместимость / регресс - **Обратная совместимость:** все существующие метки и строки карточки неизменны (NFR-2): In Review (brd-clock), Awaiting Deploy (`deploy`), Done, live-overlay ветки (Needs Input / Blocked / Rejected / Cancelled / Confirm Deploy / Deploying / Monitoring), строка `Подтверждение BRD`, формат строк стадий и тоталов, эффорт-суффикс. - **Область раската:** косметика карточки для всех проектов общего инстанса (self-hosting + enduro-trails). Чисто индикативный слой — управляющий конвейер не затронут. - **Обратимость:** изменение docs/code-only в одном модуле; откат = revert PR. Kill-switch не требуется (нет нового поведения конвейера; рендер never-raise деградирует безопасно). - **Артефакты pipeline:** создаются/обновляются стандартные analysis-доки (`01..04`); на стадии review — `12-review.md`; на testing — `13-test-report.md`. Новых типов артефактов не вводится. - **Анти-стейл/трассировка:** правится код, помеченный ORCH-067/ORCH-087 — перед правкой читать их ADR (`docs/work-items/ORCH-067|ORCH-087/06-adr/`) и не ломать инварианты (single-card, never-raise, разделение offline-ядра и live-overlay).