13 KiB
BRD — ORCH-067: Telegram tracker (bump + статусы Plane + кликабельный номер задачи)
Work Item: ORCH-067
Тип: Багфикс + enhancement
Приоритет: высокий
Компонент: Telegram live-tracker и уведомления оркестратора (src/notifications.py)
Расширяет: открытый баг seq=55 («bump не сработал, регресс ORCH-042»)
1. Бизнес-контекст и проблема
Оркестратор ведёт по одной «живой карточке» (live-tracker) на каждую задачу в Telegram
(src/notifications.py). Карточка тихо обновляется на каждом переходе стадии, а отдельными
пингами шлются только события, требующие внимания владельца (approve-gate, деплой-фейл,
падение агента, ошибка задачи).
Сейчас есть четыре боли:
-
bump не работает в проде. Диагностика оператора: код режима
bumpвupdate_task_trackerкорректен (delete старого → sendMessage вниз → repointtracker_message_id), НО в продеtracker_mode="edit"(дефолтsrc/config.py:408), аORCH_TRACKER_MODE=bumpне выставлен. Карточка обновляется edit-in-place и остаётся «вверху» ленты, тонет под новыми сообщениями — наблюдатель не видит актуального состояния без скролла. -
Карточка показывает внутренние названия стадий, а не Plane-статусы. После ввода осмысленной статусной модели Plane (ORCH-066) карточка по-прежнему рендерит внутренние ярлыки стадий (Анализ/Архитектура/…), а текущий статус задачи в терминах, понятных наблюдателю в Plane (To Analyse → Analysis → In Review → … → Done), в шапке карточки не отражён. Особенно теряется состояние ожидания согласования BRD = Plane-статус
In Review: сейчас это лишь строка «✅/⏸️ Подтверждение BRD … ⏳», не выраженная как полноценный статус. -
Номер задачи в карточке некликабелен.
ORCH-066в карточке — обычный текст; чтобы открыть задачу в Plane, наблюдателю приходится искать её вручную. -
Номер задачи некликабелен и во всех остальных уведомлениях орка (approve-requested, QG-fail, deploy SUCCESS/FAIL, Needs Input, прод-деплой и т. п.) — везде, где упоминается
work_item_id, это просто текст.
2. Цель
Сделать live-tracker и уведомления орка наблюдаемыми «из коробки»:
- bump работает по умолчанию (карточка падает вниз свежим сообщением при каждом обновлении, ровно одна карточка на задачу, без спама и дублей);
- карточка явно показывает текущий Plane-статус по модели ORCH-066, включая человеческие
гейты (
⏸️ In Review— согласование BRD,⏸️ Awaiting Deploy— ожидание Confirm Deploy,❓ Needs Input— нужны уточнения); - номер задачи кликабелен в карточке и во всех Telegram-уведомлениях орка и ведёт на страницу задачи в Plane.
3. Заинтересованные стороны
- Owner (Слава) — основной потребитель карточки и уведомлений; источник 4 требований.
- Агенты конвейера — косвенно (карточка отражает их прогресс; поведение агентов не меняется).
- Другие проекты (enduro-trails) — общий инстанс/БД; изменения не должны вызывать регресс.
4. Объём работ (scope)
4.1. Требование 1 — bump по умолчанию
- Режим
bumpдолжен быть поведением по умолчанию: при каждом обновлении карточка удаляется и пересоздаётся внизу ленты, одна карточка на задачу, тихо (disable_notification), без дублей. - Инвариант «одна карточка на задачу» сохраняется в обоих режимах (
editостаётся как опция через env). - Транзиентный фейл
sendне должен обнулятьtracker_message_idи плодить дубли (инвариант уже заложен в коде — сохранить).
4.2. Требование 2 — статусы карточки как в Plane (модель ORCH-066)
- В шапке/верхней части карточки явно отображается текущий Plane-статус задачи по модели ORCH-066.
- Полный маппинг состояний (имена — финальные из модели ORCH-066):
Ветки:
To Analyse → Analysis → In Review (⏸️ ожидание согласования BRD) → Architecture → Development → Code-Review → Testing → Awaiting Deploy (⏸️ ожидание Confirm Deploy) → Deploying → Monitoring after Deploy → DoneNeeds Input(аналитик задал вопросы),Blocked,Rejected,Cancelled. - Человеческие гейты отражаются как ПОЛНОЦЕННЫЕ статусы с паузой:
- согласование BRD → «⏸️ In Review — ожидание согласования BRD»;
- ожидание прод-деплоя → «⏸️ Awaiting Deploy — ожидание Confirm Deploy»;
- вопросы аналитика → «❓ Needs Input — нужны уточнения».
- Существующая семантика строки «Подтверждение BRD» сохраняется (время ожидания/«твоё время»), но статус карточки при этом явно показывает In Review (approve-pending).
4.3. Требование 3 — кликабельный номер задачи в карточке
work_item_id(напр.ORCH-066) в карточке — гиперссылка на страницу задачи Plane:https://<PLANE_WEB_BASE>/<workspace_slug>/projects/<project_id>/issues/<issue_id>/.- Источники частей URL:
PLANE_WEB_BASE— из конфигурации (env, полеplane_web_url/ORCH_PLANE_WEB_URL; значение прод —plane.mva154.duckdns.org); fail-safe: не задан → номер без ссылки;workspace_slug—plane_workspace_slug(уже есть в settings, прод —ag_proj);project_id— резолвится per-task по репозиторию задачи (ORCH / Sandbox);issue_id(UUID) — из БД: колонкаtasks.plane_issue_id.
- Рендер через
<a href="...">ORCH-NNN</a>(parse_mode=HTMLуже включён); HTML в title/тексте экранируется, чтобы не сломать разметку.
4.4. Требование 4 — кликабельный номер во ВСЕХ уведомлениях орка
- Единый хелпер (напр.
plane_issue_link(work_item_id, plane_issue_id, project_id) -> html) строит кликабельный номер с fail-safe; применяется во всех точкахsend_telegram/notify_*, где упоминаетсяwork_item_id(approve-requested, QG-fail, deploy SUCCESS/FAIL, Needs Input, прод-деплой, alert'ы launcher/merge_gate/job_reaper/ security_gate/reconciler/main).
5. Вне объёма (out of scope)
- Транспорт
send_telegram/edit_telegram/delete_telegram(parse_mode HTML уже есть) — не трогать. - Инвариант «одна карточка на задачу» — не нарушать (не плодить дубли).
- Логика
disable_notification(карточка тихая; пингуют только alert-хелперы) — не трогать. STAGE_TRANSITIONS, Quality Gates, схема БД — НЕ менять.- Изменение поведения агентов/конвейера.
6. Зависимости
- Маппинг статусов (требование 2) опирается на статусную модель ORCH-066. ORCH-066 уже в конвейере на стадии deploy. Эту задачу делать ПОСЛЕ прода ORCH-066, чтобы имена статусов совпали. Если ORCH-066 ещё не в проде на момент разработки — использовать согласованные финальные имена из модели: To Analyse, Analysis, Code-Review, Awaiting Deploy, Deploying, Monitoring after Deploy, In Review, Needs Input, Blocked, Cancelled, Done.
- Конфигурация
plane_web_url/plane_workspace_slugуже существует вsrc/config.py(ORCH-017); реестр проектовsrc/projects.py(get_project_by_repo().plane_project_id) уже даёт per-task project_id.
7. Fail-safe (обязательно)
- Нет
PLANE_WEB_BASE/ нетplane_issue_id/ нетproject_id/ loopback-база → показывать номер БЕЗ ссылки, не падать. - HTML-экранирование пользовательского текста (title и пр.) во всех сообщениях с
parse_mode=HTML. - Bump: транзиентный фейл
sendне обнуляетtracker_message_idи не плодит дубли. - Любая ошибка построения статуса/ссылки никогда не должна ронять рендер карточки или отправку уведомления (degrade gracefully).
8. Критерии успеха (Definition of Done)
- Bump работает из коробки: карточка падает вниз при обновлении, одна на задачу.
- Карточка показывает Plane-статус новой модели, включая
⏸️ In Review(согласование BRD),⏸️ Awaiting Deploy,❓ Needs Input. - Номер задачи кликабелен в карточке И во всех уведомлениях орка (ведёт на страницу Plane).
- Fail-safe покрыт тестами (нет URL/plane_id/project → без ссылки, не падает; HTML-экранирование).
pytest tests/ -qзелёный.- Документация обновлена в том же PR:
CLAUDE.md(раздел нотификаций/tracker),CHANGELOG.md, ADR per-work-item.
9. Риски
- Регресс enduro-trails. Смена дефолта
tracker_modeна bump меняет поведение для всех проектов. Митигация: bump уже реализован и протестирован концептуально; инвариант «одна карточка» сохранён; env-переключательeditостаётся. - Поломка HTML-разметки при неэкранированном title → сообщение не доставится. Митигация:
обязательное
html.escape+ тесты. - Источник «истинного» Plane-статуса для веток, не выводимых из
tasks.stage(Needs Input/Blocked/Rejected/Cancelled, Deploying/Monitoring), при запрете на изменение схемы БД — архитектурное решение (ADR), с обязательным fail-safe (без сети не падать). - Self-hosting. Орк правит сам себя; обязательна страховка через staging (8501) перед прод-деплоем; прод-контейнер не ронять в рамках задачи.