# 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).
