## Why Веб уже показывает, с какой именно записью метабазы сматчилась загрузка: страница `/download/{id}` и экран ревью выводят provider, id и — если URL строится — ссылку на страницу записи (`internal/httpapi`: `matchURL`/ `providerURL`, шаблон `download_main.html`). В Telegram матч показан беднее: карточка ревью (`internal/tgbot/render.go`, `baseLine`) выводит только `provider id` из **сырого** распознавания и **без ссылки**, а уведомление о готовности матч не показывает вовсе. Из-за этого ошибочную привязку (не тот фильм/сезон) из бота не видно — приходится открывать веб. ## What Changes - **Карточка подтверждения (review)** в боте показывает матч со **ссылкой** на запись метабазы (когда URL строится) — как веб: `provider id ↗`. Без URL — тем же текстом, что и раньше. - **Уведомление о готовности** (`renderDone`) показывает строку матча (provider, id, ссылка) — чтобы ошибочную привязку было видно и в финальном пинге. - **Provider/id берутся эффективные** (`ReviewData.Provider`/`ProviderID`, с учётом ручных правок), консистентно с веб-страницей и экраном ревью, а не из сырого распознавания. - **Единый билдер URL:** канонический `providerURL` и выбор ссылки матча `matchURL` переезжают из `internal/httpapi` в ядро `internal/worker` (`worker.ProviderURL` + метод `(*ReviewData).MatchURL()`), чтобы оба транспорта (веб и Telegram) строили ссылку одинаково. httpapi делегирует туда. - **Экранирование:** provider, id и URL — недоверенные, экранируются перед вставкой в HTML-сообщение (инвариант «выход LLM недоверенный»); ссылка рисуется только при непустом URL. URL — в контексте атрибута `href`: помимо `<`/`>`/`&` экранируется и кавычка (иначе изготовленный id разорвёт атрибут и Telegram отклонит сообщение). ## Capabilities ### New Capabilities Нет. ### Modified Capabilities - `notifications`: добавляется требование к **содержанию** уведомлений/ подтверждений — показ записи матча метабазы (provider, id, ссылка) в карточке ревью и уведомлении о готовности, эффективным провайдером, с экранированием. Условия и события доставки (падение, review, готовность, рассинхрон) без изменений. ## Impact - **Спеки:** дельта `notifications` — ADDED «Показ записи матча метабазы» + MODIFIED «Экранирование внешнего текста» (в перечень добавлены id матча и URL, экранирование учитывает контекст `href`/кавычку). - **Код:** `internal/worker/review.go` (новые `ProviderURL` + метод `MatchURL`), `internal/httpapi/review.go`/`download.go` (делегируют в worker; локальные `providerURL`/`matchURL` удаляются, `sourceMatchURL` зовёт `worker.ProviderURL`), `internal/tgbot/render.go` (`baseLine` по `ReviewData` со ссылкой; строка матча в `renderDone`). - **Тесты:** тесты `providerURL`/`matchURL` переезжают в `internal/worker`; `internal/tgbot` — проверка ссылки и экранирования в строке матча. - **Миграции БД:** нет (данные матча уже в БД).