12 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-091 | analysis | analyst | ready-for-review | 2026-06-09 | 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 (косметика, но вводит в заблуждение). Заголовок-строка статуса карточки (
📍 <status_label>) застревает на «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_CHANGESreview → 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(заполняет архитектор).