7.6 KiB
DEV TASK: orchestrator — фикс трекера (дубли сообщений + отставание)
Репо: slin@82.22.50.71:/home/slin/repos/orchestrator (пароль motoZ@yaz2010).
Push в main запрещён (pre-receive hook) → только PR в Gitea.
Gitea токен: docker exec orchestrator printenv ORCH_GITEA_TOKEN.
Одна ветка fix/tracker-edit-not-modified от актуального main, один PR.
Baseline pytest на этом проде: 259 passed + 9 failed (9 = off-limits HMAC/401, НЕ чинить).
КОНТЕКСТ / БАГ (подтверждён на живой задаче ET-013)
Живой Telegram-трекер (PR #21, src/notifications.py) на боевом прогоне ET-013 повёл себя так:
- За прогон: 21 editMessageText, но 7 sendMessage — трекер 7 раз прислал НОВОЕ сообщение вместо редактирования одного. Слава жалуется: «сообщение не одно, а при изменении приходит новое».
- Часть
editMessageTextпадает с HTTP 400 Bad Request. Это НЕ сбой Telegram — это ответ"message is not modified"(текст трекера не изменился между переходами, напр. повторный цикл review→development→review рисует ту же строку).
Корень (точно)
edit_telegram (notifications.py ~76-97):
data = resp.json()
return bool(data.get("ok")) # 400 "not modified" -> ok:false -> возвращает False
Возвращает False на ЛЮБОМ 400. А update_task_tracker (~374-392) трактует False как
«edit не удался» → вызывает send_telegram(...) (новое сообщение) и перезаписывает
tracker_message_id. Итог: дубли + старый трекер «осиротевает» и больше не обновляется
(отстаёт от реальности — застрял на снимке Review, хотя был ещё цикл dev→review).
ЧТО СДЕЛАТЬ (3 правки)
Правка 1 — edit_telegram: "not modified" = успех, НЕ дубль
В edit_telegram разобрать тело ответа Telegram. Если ok:false, но
description содержит "message is not modified" (или "exactly the same") —
вернуть True (редактировать нечего, всё в порядке, дубль НЕ нужен).
Логировать на DEBUG, не на WARNING.
Правка 2 — fallback на новое сообщение ТОЛЬКО при реально пропавшем сообщении
Сейчас update_task_tracker: if edit_telegram(...) == False -> send_telegram (новое).
Изменить логику так, чтобы новое сообщение слалось только когда исходное реально
нельзя редактировать:
"message to edit not found"/"message can't be edited"/"MESSAGE_ID_INVALID"→ сообщение пропало/удалено → fallback на новое (как сейчас), обновить tracker_message_id.- Любой другой провал edit (сеть, таймаут, временный 5xx, неизвестный 400) → НЕ слать новое, просто залогировать и выйти (трекер дорисуется на следующем переходе). Плодить дубли на временных ошибках нельзя.
Реализация: пусть edit_telegram возвращает не голый bool, а различимый результат —
например enum/строку ("ok" | "not_modified" | "gone" | "failed"), либо tuple
(ok: bool, gone: bool). update_task_tracker шлёт новое сообщение только при gone.
"ok" и "not_modified" → ничего не делать. "failed" → лог + выход без нового сообщения.
Никогда не падать (текущий стиль fire-and-forget сохранить).
Правка 3 — повторные циклы стадии видимы (чтобы текст реально менялся)
Чтобы трекер не «застывал» на повторных проходах одной стадии (review↔development),
у АКТИВНОЙ стадии в render_task_tracker показывать признак повторного захода/попытки,
например: 🔄 Review · попытка 2 … идёт (номер попытки = число записей agent_runs этого
агента по задаче, или attempts из jobs если доступно). Завершённые стадии (✅) НЕ трогать —
формат финальной строки прежний. Это и делает текст уникальным между циклами (меньше
not-modified), и честно показывает Славе, что идёт переработка.
- Если данных о попытке нет — рисовать как раньше (
🔄 Review … идёт), без «попытка N». - Считать попытку аккуратно: повторный запуск ТОЙ ЖЕ стадии (например 2-й review), а не суммарно все агенты. Бери число прогонов агента этой стадии для текущей задачи.
НЕ ТРОГАТЬ
- Формат завершённых строк (
✅ Stage Nм · in↓/out↑ · $ · model), блок Итого, «Ревью БРД», short_model_name, миграции, usage_comment/Plane-комменты, PLANE_STATES, HMAC, queue, launcher deployer-guard, отдельные алерты (approve/deploy-fail/agent-fail/error). - disable_notification трекера (всегда silent).
ТЕСТЫ (обязательно, мокать httpx)
edit_telegram: ответ 400"message is not modified"→ трактуется как успех (не gone, не дубль).edit_telegram: 400"message to edit not found"→ gone.edit_telegram: 200 ok → ok.edit_telegram: таймаут/5xx → failed (не gone).update_task_tracker: edit not_modified → НЕ зовёт send_telegram (нет дубля).update_task_tracker: edit gone → зовёт send_telegram + обновляет tracker_message_id.update_task_tracker: edit failed (временная) → НЕ зовёт send_telegram.render_task_tracker: повторный заход стадии (2 review-рана) →попытка 2в активной строке; один заход → без «попытка N»; завершённые строки без изменений.- Полный pytest зелёный кроме тех же 9 off-limits.
СДАЧА
- Ветка
fix/tracker-edit-not-modified, один PR в Gitea. НЕ мержить сам — на ревью Стрим. - Отчёт:
tasks/orchestrator/reports/dev-2026-06-04-tracker-edit-fix.md— commit-хеш, PR-номер, вывод pytest, что изменилось в каждой из 3 правок, до/после по логике (когда теперь шлётся новое сообщение, а когда нет). - Сообщить: PR-номер, результат pytest, краткое описание фикса.