architect(ET): auto-commit from architect run_id=414

This commit is contained in:
2026-06-09 01:19:58 +03:00
committed by stream
parent f452626bb8
commit a482b36dae
2 changed files with 85 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
# ADR-001: Подавление Telegram link-preview в низкоуровневых примитивах нотификаций
## Статус
Accepted
## Контекст
С ORCH-067 карточка трекера и notify-сообщения несут кликабельный номер задачи
`<a href="https://plane.mva154.duckdns.org/.../issues/<id>/">ORCH-NNN</a>`. Telegram
Bot API по умолчанию (при отсутствии ключа `disable_web_page_preview`) разворачивает
web-page-preview для первой ссылки в сообщении — под каждым сообщением трекера
раскрывается баннер «Plane — Modern project management». В дефолтном режиме `bump`
(ORCH-067) карточка пересоздаётся на каждом переходе, поэтому баннер дублируется на
каждой задаче и каждом обновлении, засоряя ленту (жалоба Owner, 08.06).
Код-аудит (`src/notifications.py`) подтвердил причину: JSON-payload обоих
низкоуровневых примитивов — `send_telegram()` (`POST /sendMessage`, стр. 55-60) и
`edit_telegram()` (`POST /editMessageText`, стр. 168-173) — **не содержит** ключ
`disable_web_page_preview`. Все вышестоящие нотификации (`update_task_tracker` в обоих
режимах, `notify_approve_requested`, `notify_error`, alert'ы стадий из
`launcher`/`stage_engine`) проходят через эти два примитива.
## Решение
Добавить `"disable_web_page_preview": True` в JSON-payload `httpx.post` обоих примитивов:
`send_telegram()` и `edit_telegram()`. Изменение — **на уровне низкоуровневого
примитива**, а не на уровне каждого вызова, потому что:
1. **Единая точка** — все исходящие сообщения трекера/нотификаций идут через эти две
функции; правка двух строк гасит баннер у ВСЕХ потребителей (карточка `bump`/`edit`,
notify-хелперы, alert'ы) без изменения их кода.
2. **Безусловно, без флага** — превью Plane не нужно никому (это не данные, а навигация
по ссылке, которая остаётся кликабельной). Kill-switch не вводится: риск регрессии
нулевой, правка обратима одной строкой. Это согласуется с принципом «минимум
зависимостей/конфигурации».
3. **Top-level флаг, а не `link_preview_options.is_disabled`** — top-level
`disable_web_page_preview` остаётся валиден и обратносовместим в Bot API; это
минимальная правка без введения вложенной структуры.
`parse_mode: "HTML"` сохраняется в обоих payload (иначе `<a href>` перестанет
рендериться — ссылка должна остаться кликабельной). `disable_notification`,
bump/edit-логика, repoint `tracker_message_id`, delete-семантика, контракты возврата
(`send_telegram → message_id|None`, `edit_telegram → EDIT_*`) — не затрагиваются.
## Последствия
**Плюсы:**
- Баннер link-preview исчезает под карточкой трекера (оба режима) и под всеми
notify/alert-сообщениями — одна правда в двух примитивах.
- Ссылка на задачу остаётся кликабельной (HTML сохранён).
- Нулевой риск: ключ аддитивный, контракты примитивов и инвариант «одна карточка на
задачу» не меняются; `never-raise` (`try/except`) сохранён.
**Минусы / ограничения:**
- Поведение безусловное — нет конфигурации «вернуть превью». Сознательный выбор:
превью трекера не имеет ценности, флаг был бы лишней поверхностью.
**Не затрагивается:** `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, схема БД, `parse_mode`,
`disable_notification`, транспортные хелперы `delete_telegram`/repoint-логика. Глобальный
ADR не требуется — решение локально для `src/notifications.py`, не сквозное.
## Self-hosting
Изменение не требует немедленного рестарта прод-контейнера и не меняет топологию.
Деплой — штатный через staging (8501) → `Confirm Deploy` (ORCH-059). По ORCH-026
(сериализация merge одного репо) задача мержится после освобождения конвейера
`orchestrator` (координация с ORCH-074 — см. BRD §7).

View File

@@ -0,0 +1,22 @@
# 10-Tech Risks — ORCH-080
Work Item ID: ORCH-080
Зона: `src/notifications.py` (две строки в `send_telegram`/`edit_telegram`)
Косметическая правка UX (LOW). Топология, схема БД, стадии, QG — не меняются.
Риск регрессии оценён как **нулевой**; ниже — остаточные пункты для внимания.
| # | Риск | Вероятность | Влияние | Митигация |
|---|------|-------------|---------|-----------|
| R-1 | Опечатка ключа/значения (`disable_web_page_preview`) — баннер не гаснет | Низкая | Низкое (косметика) | unit-тест AC-1/AC-2 инспектирует `httpx.post.call_args.kwargs["json"]`; ручная верификация на staging (AC-3) |
| R-2 | Случайное удаление `parse_mode: "HTML"` → ссылка `<a href>` ломается | Очень низкая | Среднее (теряется кликабельность) | AC-4: unit-тест на наличие `parse_mode: "HTML"` в обоих payload; `test_notify_issue_links.py` остаётся зелёным |
| R-3 | Merge-конфликт с ORCH-067/ORCH-074 в `src/notifications.py` | Низкая | Низкое | По ORCH-026 сериализация merge одного репо; запуск после доезда ORCH-74 в `main` (BRD §7); pre-merge rebase (ORCH-043) |
| R-4 | Регрессия контракта возврата примитивов (`message_id|None` / `EDIT_*`) | Очень низкая | Среднее | Правка строго аддитивна (новый ключ в payload), возвраты не трогаются; AC-5 + существующие тесты трекера |
| R-5 | Telegram депрекейтит top-level `disable_web_page_preview` в пользу `link_preview_options` | Очень низкая | Низкое (forward-compat) | Top-level флаг остаётся валиден и обратносовместим; миграция на `link_preview_options.is_disabled` — отдельная задача при необходимости |
## Инварианты, которые НЕЛЬЗЯ нарушить
- `never-raise` обоих примитивов (`try/except` сохранён).
- `parse_mode: "HTML"` в обоих payload (иначе `<a href>` ломается).
- `disable_notification` в `send_telegram` (карточка тихая).
- Инвариант «одна карточка на задачу» (bump/edit) — не затрагивается.
- Контракты возврата: `send_telegram → message_id|None`, `edit_telegram → EDIT_*`.