From 852da919b9c56c6177c12898502fe8a4c5cf9f95 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Tue, 9 Jun 2026 21:40:07 +0300 Subject: [PATCH] analyst(ET): auto-commit from analyst run_id=504 --- docs/work-items/ORCH-091/01-brd.md | 137 ++++++++++++++++++ docs/work-items/ORCH-091/02-trz.md | 112 ++++++++++++++ .../ORCH-091/03-acceptance-criteria.md | 111 ++++++++++++++ docs/work-items/ORCH-091/04-test-plan.yaml | 76 ++++++++++ 4 files changed, 436 insertions(+) create mode 100644 docs/work-items/ORCH-091/01-brd.md create mode 100644 docs/work-items/ORCH-091/02-trz.md create mode 100644 docs/work-items/ORCH-091/03-acceptance-criteria.md create mode 100644 docs/work-items/ORCH-091/04-test-plan.yaml diff --git a/docs/work-items/ORCH-091/01-brd.md b/docs/work-items/ORCH-091/01-brd.md new file mode 100644 index 0000000..0ae77bf --- /dev/null +++ b/docs/work-items/ORCH-091/01-brd.md @@ -0,0 +1,137 @@ +--- +work_item: ORCH-091 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-09 +model_used: claude-opus-4-8 +--- + +# 01 — BRD (бизнес-требования): ORCH-091 — Карточка трекера: фикс «To Analyse» на deploy-staging, отражение откатов, суммирование метрик по попыткам + +Work Item: **ORCH-091** · Repo: **orchestrator** · Стадия: analysis + +## 1. Бизнес-контекст и проблема + +Live Telegram-карточка задачи (ORCH-067, единственная карточка на задачу, рендер +`src/notifications.py::render_task_tracker`) — основной канал, по которому Owner/Слава +наблюдают прогресс конвейера. Карточка обязана показывать **честную** текущую картину. +Объединены три верифицированных по коду и БД прода (09.06) дефекта одной карточки +(ORCH-072 закрыт как дубль; ORCH-091 расширена до полного объёма): + +- **Дефект 1 (косметика, но вводит в заблуждение).** Заголовок-строка статуса карточки + (`📍 `) застревает на «To Analyse», когда задача реально на стадии + `deploy-staging`. Корень верифицирован: словарь `_STAGE_STATUS_LABEL` + (`src/notifications.py` ~стр. 940) содержит 8 ключей (`created/analysis/architecture/ + development/review/testing/deploy/done`), а реальные значения `tasks.stage` — это ключи + `STAGE_TRANSITIONS` (`src/stages.py`), среди которых есть `deploy-staging`. Ровно эта + стадия не покрыта → `.get(stage, _DEFAULT_STATUS_LABEL)` отдаёт дефолт «To Analyse» + (`_DEFAULT_STATUS_LABEL`, ~стр. 950). Программно проверено: из 9 реальных стадий не + покрыта **ровно одна** — `deploy-staging` (предпоследняя перед прод-деплоем, видна + чаще всего). Сам дефолт-«To Analyse» — мина на будущее: любая новая стадия даст ложный + «первый статус». + +- **Дефект 2 (ложная картина при откате).** При rollback по конвейеру (напр. merge-gate + `deploy-staging → development`, ORCH-43; или REQUEST_CHANGES `review → development`) + верхние строки `✅ пройдено` (Код-ревью / Тестирование / Внедрение) НЕ снимаются, а внизу + снова `🔄 Разработка`. Абсурд: «Внедрение готово ✅, но идёт Разработка 🔄». Корень: + цикл рендера в `render_task_tracker` (~стр. 474–505) выводит `✅`-строку для каждой + стадии `_TRACKER_STAGES`, у чьего агента есть завершённый прогон (`last_done`), без + учёта позиции стадии относительно текущей. + +- **Дефект 3 (реальное занижение тоталов, не косметика).** Строка стадии берёт ПОСЛЕДНИЙ + прогон агента (`run = last_done.get(agent)`, ~стр. 475; `_stage_line`), теряя предыдущие + попытки. На задаче с ретраями метрики стадии занижены. Верифицировано на ORCH-069 + (`task_id=54`, прод 09.06): developer = 3 прогона Σ $3.98 (карточка показывала ~$0.00 за + «Разработка»), reviewer = 3 Σ $2.10, tester = 2 Σ $1.03, deployer = 2 Σ $1.59. Источник + истины — таблица `agent_runs` (`cost_usd`, `input_tokens`, `output_tokens`, + `cache_read_tokens`, `cache_creation_tokens`, `started_at`/`finished_at`). + +> **Замечание (факт кода, не противоречие).** Блок тоталов задачи (`💰`/`🔢`/`⏱ Агенты`) +> в текущем worktree уже суммирует ВСЕ прогоны (`render_task_tracker` ~стр. 388–404). +> Заниженной остаётся **строка стадии** (`_stage_line` показывает только последний прогон). +> Требование G4/AC-5 формулируется на уровне строки стадии и инварианта сходимости тоталов +> с `SUM(agent_runs)` — реализация/архитектура подбора агрегата за архитектором. + +## 2. Объём (scope) + +### В объёме +- Покрытие `_STAGE_STATUS_LABEL` всеми ключами `STAGE_TRANSITIONS` из единого + программного источника истины (не «на глаз», не дублирующим списком). +- Осмысленный staging-лейбл для `deploy-staging`, согласованный с моделью статусов + ORCH-066/059. +- Нейтральный фолбэк для истинно неизвестной/битой стадии (вместо «To Analyse»). +- Отражение откатов: снятие `✅` со стадий ПОСЛЕ текущей позиции задачи. +- Метрика строки стадии = Σ всех `agent_runs` стадии (💰 стоимость / 🔢 токены / ⏱ время), + с сохранением сходимости тоталов задачи с `SUM(agent_runs)` по `task_id`. +- Тесты на полноту карты стадий, суммирование метрик, отражение отката; `CHANGELOG.md`. + +### Вне объёма +- Изменение `STAGE_TRANSITIONS`, схемы БД, реестра `QG_CHECKS`/`check_*`, транспорта + нотификаций (`send/edit/delete_telegram`). +- Live-overlay ветки (Needs Input / Blocked / Rejected / Cancelled / Confirm Deploy / + Deploying / Monitoring) — работают, не трогаем. +- Архитектурное решение «как реализовать» (ordering-источник, форма агрегата) — + зона архитектора (`06-adr/`). + +## 3. Заинтересованные стороны +- **Заказчик / приёмка:** Owner (homenet542), Слава (нашёл дефекты 08.06). +- **Затрагивается:** все наблюдатели карточек конвейера всех проектов (общий прод-инстанс, + self-hosting). Косметика карточки — для всех репо (orchestrator + enduro-trails). + +## 4. Бизнес-требования (BR) + +- **BR-1 (Деф.1, G1)** — `_STAGE_STATUS_LABEL` покрывает КАЖДЫЙ ключ `STAGE_TRANSITIONS`; + полнота гарантируется программно (итерация по единому источнику истины `src/stages.py`), + а не статичным списком. Для каждой реальной стадии `plane_status_label` возвращает + непустой осмысленный лейбл (не дефолт-«To Analyse», кроме реального `created`). +- **BR-2 (Деф.1, G1)** — `stage='deploy-staging'` → осмысленный staging-лейбл (напр. + «Deploying (staging)» / «⏳ Staging»), согласованный с моделью статусов ORCH-066/059. +- **BR-3 (Деф.1, G2)** — фолбэк для истинно неизвестной/битой стадии — нейтральный (напр. + «В работе» / stage capitalized), НЕ «To Analyse», чтобы будущая стадия не давала ложный + «первый статус». `plane_status_label` остаётся never-raise. +- **BR-4 (Деф.2, G3)** — при откате стадии карточка отражает ФАКТИЧЕСКУЮ текущую позицию: + с стадий ПОСЛЕ точки отката снимается `✅`; текущая стадия отрисовывается как активная + (`🔄`). Сценарий-эталон: после `deploy-staging → development` Разработка = `🔄`, + Тестирование/Внедрение — НЕ `✅`. +- **BR-5 (Деф.3, G4)** — метрика строки стадии = СУММА всех `agent_runs` этой стадии + (по `task_id` + агент стадии) по трём метрикам: 💰 `Σ cost_usd`, 🔢 `Σ (input + output + + cache_read + cache_creation)`, ⏱ `Σ (finished_at − started_at)`. Тоталы задачи = суммы по + всем стадиям и попыткам, сходятся с `SUM(agent_runs)` по `task_id`. + +## 5. Нефункциональные требования (NFR) + +- **NFR-1 (надёжность)** — `render_task_tracker` и `plane_status_label` остаются + **stateless / never-raise**: любая ошибка деградирует к безопасному выводу, конвейер + никогда не блокируется рендером карточки. +- **NFR-2 (совместимость / регресс)** — существующие метки и строки НЕ меняются: In Review + (brd-clock), Awaiting Deploy (`deploy`), Done, live-overlay ветки, строка `Подтверждение + BRD`, формат строк стадий/тоталов, эффорт-суффикс (ORCH-087). Изменение аддитивно. +- **NFR-3 (источник истины)** — полнота карты стадий выводится из `STAGE_TRANSITIONS` + программно; запрещено дублировать перечень стадий руками (анти-рассинхрон на будущее). +- **NFR-4 (self-hosting)** — изменения только в `src/notifications.py` + тесты + доки; без + правки `STAGE_TRANSITIONS`/схемы БД/QG; без рестарта прод-контейнера в рамках задачи. + +## 6. Допущения и ограничения +- `tasks.stage` принимает строго значения-ключи `STAGE_TRANSITIONS` (включая + `deploy-staging`, `cancelled`). Это инвариант движка стадий. +- `cancelled` (ORCH-090) — системный терминал; его статус-лейбл уже рисуется live-overlay + (`_LIVE_BRANCH_LABELS['cancelled']`). Для offline-фолбэка `plane_status_label` он не + должен давать «To Analyse» (покрывается BR-3 нейтральным фолбэком; явный лейбл для + `cancelled` — на усмотрение архитектора, без конфликта с overlay). +- Источник метрик — `agent_runs`; стадия `deploy-staging` и `deploy` обслуживаются одним + агентом `deployer` — агрегат по агенту корректно покрывает обе (вопрос разнесения + staging/prod-прогонов по строкам — зона архитектора, не требование BRD). +- Telegram-ограничение 48ч на удаление сирот (ORCH-087) — вне объёма. + +## 7. Критерии успеха +Карточка показывает корректный статус-заголовок на всех стадиях (включая `deploy-staging`), +не «лжёт» о пройденных стадиях после отката, и метрики строки стадии + тоталы сходятся с +`SUM(agent_runs)` по `task_id`. Полный регресс `pytest tests/ -q` зелёный. Детальные +PASS/FAIL — `03-acceptance-criteria.md`. + +## 8. Риски +- Рассинхрон карты стадий с `STAGE_TRANSITIONS` в будущем (митигируется NFR-3 + тест полноты). +- Регресс существующих меток/строк при правке цикла рендера (митигируется NFR-2 + тесты). +- Неверная точка отсчёта «позиции» стадии для отката (ordering) → неверное снятие `✅`. +Детали — `10-tech-risks.md` (заполняет архитектор). diff --git a/docs/work-items/ORCH-091/02-trz.md b/docs/work-items/ORCH-091/02-trz.md new file mode 100644 index 0000000..a6826e5 --- /dev/null +++ b/docs/work-items/ORCH-091/02-trz.md @@ -0,0 +1,112 @@ +--- +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). diff --git a/docs/work-items/ORCH-091/03-acceptance-criteria.md b/docs/work-items/ORCH-091/03-acceptance-criteria.md new file mode 100644 index 0000000..d2730db --- /dev/null +++ b/docs/work-items/ORCH-091/03-acceptance-criteria.md @@ -0,0 +1,111 @@ +--- +work_item: ORCH-091 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-09 +model_used: claude-opus-4-8 +--- + +# 03 — Критерии приёмки (Acceptance Criteria): ORCH-091 — Карточка трекера: статусы, откаты, метрики + +Work Item: **ORCH-091** · Repo: **orchestrator** · Стадия: analysis + +Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL** +(что считается провалом). Reviewer/тестер проверяет их буквально по файлам репозитория и +по выводу тестов. + +--- + +## AC-1 — Полнота карты статусов по `STAGE_TRANSITIONS` (Деф.1 / BR-1) + +**Условие:** для КАЖДОГО ключа `src/stages.py::STAGE_TRANSITIONS` `plane_status_label` +возвращает непустой осмысленный лейбл. +- **PASS:** параметризованный тест итерирует по всем ключам `STAGE_TRANSITIONS` и для каждого + (кроме реального `created`) получает непустой лейбл ≠ `_DEFAULT_STATUS_LABEL`-«To Analyse». + Полнота карты выведена программно из `STAGE_TRANSITIONS`, а не статичным списком в тесте. +- **FAIL:** хотя бы одна стадия из `STAGE_TRANSITIONS` отдаёт «To Analyse» (кроме `created`); + либо полнота проверяется захардкоженным списком, не связанным с `STAGE_TRANSITIONS`. + +--- + +## AC-2 — Staging-лейбл для `deploy-staging` (Деф.1 / BR-2) + +**Условие:** `stage='deploy-staging'` даёт осмысленный staging-лейбл. +- **PASS:** `plane_status_label` для строки со `stage='deploy-staging'` возвращает осмысленный + staging-лейбл (напр. «Deploying (staging)» / «⏳ Staging»), отличный от «To Analyse» и от + лейбла стадии `deploy` (`⏸️ Awaiting Deploy …`). +- **FAIL:** возвращает «To Analyse», пустую строку, либо лейбл, неотличимый от `deploy`. + +--- + +## AC-3 — Нейтральный фолбэк для неизвестной стадии (Деф.1 / BR-3) + +**Условие:** истинно неизвестная/битая стадия → нейтральный фолбэк, never-raise. +- **PASS:** для строки с заведомо несуществующим `stage` (напр. `"__bogus__"`) + `plane_status_label` возвращает нейтральный лейбл (НЕ «To Analyse») и не бросает исключение; + для битого входа (None/нет ключа `stage`) тоже не падает. +- **FAIL:** неизвестная стадия даёт «To Analyse»; либо функция бросает исключение на + битом/неизвестном входе. + +--- + +## AC-4 — Отражение отката в строках стадий (Деф.2 / BR-4) + +**Условие:** после rollback `deploy-staging → development` карточка показывает фактическую +позицию. +- **PASS:** для задачи с завершёнными прогонами reviewer/tester/deployer, но текущим + `stage='development'`, `render_task_tracker` рисует Разработку как активную (`🔄`), а + Тестирование и Внедрение — НЕ как `✅ пройдено`. Стадии до development (Анализ, Архитектура) + остаются `✅`. +- **FAIL:** карточка одновременно показывает `✅ Внедрение/Тестирование/Код-ревью` и + `🔄 Разработка` (картина «Внедрение готово ✅, но идёт Разработка»). + +--- + +## AC-5 — Суммирование метрик стадии по попыткам (Деф.3 / BR-5) + +**Условие:** стадия с N попытками показывает СУММУ метрик по всем N `agent_runs`. +- **PASS:** для стадии с N>1 `agent_runs` строка стадии показывает Σ времени, Σ токенов + (`input+output+cache_read+cache_creation`) и Σ стоимости по всем N прогонам. На фикстуре + по образцу ORCH-069 (developer: 3 прогона, суммарно ≈ $3.98) строка «Разработка» отражает + ≈ $3.98, а не стоимость последнего прогона. Тоталы задачи (💰/🔢/⏱ Агенты) сходятся с + `SUM(agent_runs)` по `task_id` (по стоимости, токенам, длительностям). +- **FAIL:** строка стадии показывает метрики только последнего прогона (занижение); либо + тоталы задачи не сходятся с `SUM(agent_runs)`. + +--- + +## AC-6 — Регресс существующих меток (NFR-2) + +**Условие:** существующие индикаторы карточки не изменены. +- **PASS:** In Review (brd-clock, `_IN_REVIEW_LABEL`), Awaiting Deploy (`deploy`), Done, + live-overlay ветки (Needs Input / Blocked / Rejected / Cancelled / Confirm Deploy / + Deploying / Monitoring), строка `Подтверждение BRD`, формат строк стадий/тоталов и + эффорт-суффикс — рендерятся как прежде; существующие тесты карточки зелёные. +- **FAIL:** изменён текст/формат любой из перечисленных меток; падает существующий тест + карточки. + +--- + +## AC-7 — Тесты и документация (G/AC-7) + +**Условие:** добавлены тесты и обновлена документация. +- **PASS:** `pytest tests/ -q` зелёный; добавлены тесты на полноту карты стадий (AC-1/2/3), + суммирование метрик (AC-5), отражение отката (AC-4); `CHANGELOG.md` содержит запись + ORCH-091; `render_task_tracker`/`plane_status_label` остаются never-raise. +- **FAIL:** регресс `pytest tests/ -q`; отсутствует любой из обязательных новых тестов; не + обновлён `CHANGELOG.md`. + +--- + +## Сводная матрица AC ↔ FR/BR +| AC | Покрывает | +|----|-----------| +| AC-1 | BR-1 / FR-1 | +| AC-2 | BR-2 / FR-2 | +| AC-3 | BR-3 / FR-3 | +| AC-4 | BR-4 / FR-4 | +| AC-5 | BR-5 / FR-5 | +| AC-6 | NFR-2 (регресс) | +| AC-7 | NFR-1 + цель G/AC-7 (тесты, доки, never-raise) | diff --git a/docs/work-items/ORCH-091/04-test-plan.yaml b/docs/work-items/ORCH-091/04-test-plan.yaml new file mode 100644 index 0000000..cba4286 --- /dev/null +++ b/docs/work-items/ORCH-091/04-test-plan.yaml @@ -0,0 +1,76 @@ +work_item: ORCH-091 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-09 +model_used: claude-opus-4-8 +title: "Карточка трекера: полнота статусов, отражение откатов, суммирование метрик по попыткам" +framework: pytest +scope: > + Юнит-покрытие чистых функций src/notifications.py (plane_status_label, + render_task_tracker) и интеграция рендера от состояния БД (tasks + agent_runs). + Вне покрытия: транспорт Telegram (send/edit/delete), live-overlay ветки (сеть), + STAGE_TRANSITIONS/QG/схема БД (не трогаются). +notes: > + Полнота карты статусов должна выводиться программно из src/stages.py::STAGE_TRANSITIONS + (а не из захардкоженного списка стадий). Метрики читаются из таблицы agent_runs: + cost_usd, input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, + started_at/finished_at. Фикстура-эталон сумм — ORCH-069 (developer: 3 прогона ≈ $3.98). + Полный регресс pytest tests/ -q должен оставаться зелёным; существующие тесты карточки + (test_tracker_status_line, test_telegram_tracker, test_tracker_effort_time) не должны + ломаться. + +tests: + - id: TC-01 + type: unit + description: "Полнота: для каждого ключа STAGE_TRANSITIONS (программная итерация) plane_status_label возвращает непустой лейбл, не 'To Analyse' (кроме created). AC-1" + module: tests/test_tracker_status_line.py + expected: PASS + + - id: TC-02 + type: unit + description: "stage='deploy-staging' -> осмысленный staging-лейбл, отличный от 'To Analyse' и от лейбла стадии 'deploy'. AC-2" + module: tests/test_tracker_status_line.py + expected: PASS + + - id: TC-03 + type: unit + description: "Истинно неизвестная стадия ('__bogus__') -> нейтральный фолбэк (не 'To Analyse'); never-raise на битом/None входе. AC-3" + module: tests/test_tracker_status_line.py + expected: PASS + + - id: TC-04 + type: unit + description: "Регресс ветки plane_status_label: analysis + открытый brd-clock -> In Review; deploy -> Awaiting Deploy; done -> Done; created -> To Analyse. AC-6" + module: tests/test_tracker_status_line.py + expected: PASS + + - id: TC-05 + type: integration + description: "Откат deploy-staging->development: задача stage='development' с завершёнными прогонами reviewer/tester/deployer -> Разработка активна (🔄), Тестирование/Внедрение НЕ как ✅; Анализ/Архитектура остаются ✅. AC-4" + module: tests/test_tracker_rollback_metrics.py + expected: PASS + + - id: TC-06 + type: integration + description: "Суммирование метрик стадии: developer с 3 agent_runs (фикстура ORCH-069) -> строка 'Разработка' показывает Σ стоимости ≈ $3.98, Σ токенов, Σ времени, а не последний прогон. AC-5" + module: tests/test_tracker_rollback_metrics.py + expected: PASS + + - id: TC-07 + type: integration + description: "Сходимость тоталов: тоталы карточки (💰/🔢/⏱ Агенты) равны SUM(agent_runs) по task_id (cost_usd, токены, длительности) при наличии ретраев. AC-5" + module: tests/test_tracker_rollback_metrics.py + expected: PASS + + - id: TC-08 + type: integration + description: "render_task_tracker never-raise: битые/частичные строки tasks/agent_runs (NULL timestamps, отсутствующий stage) -> возвращает строку-фолбэк без исключения. NFR-1 / AC-7" + module: tests/test_tracker_rollback_metrics.py + expected: PASS + + - id: TC-09 + type: unit + description: "Регресс существующих строк карточки: формат строк стадий, эффорт-суффикс (ORCH-087), строка 'Подтверждение BRD', блок тоталов — без изменений. AC-6" + module: tests/test_telegram_tracker.py + expected: PASS