# Недоступность Telegram подъёму сервиса не мешает

- **Дата:** 2026-08-13
- **Источник:** openspec/changes/archive/2026-08-13-start-without-telegram-token/design.md
- **Статус:** устарело — вход Telegram убран решением [ADR-2026-08-15-telegram-intake-removed-temporarily](ADR-2026-08-15-telegram-intake-removed-temporarily.md); довод устоял и понадобится возврату входа

## Решение

Старт роняет только один исход сборки клиента бота — ответ Telegram «такого бота
нет». Всё прочее, включая недоступность Telegram и истёкший срок ожидания, даёт
подъём без Telegram: сервис работает по HTTP и говорит о неподнятом входе
записью журнала и метрикой.

## Почему

Очевидный подход был обратный, и он же стоял в первой редакции дизайна: любой
отказ сборки бота роняет старт, потому что «сервис, молча потерявший бота после
опечатки в токене, перестаёт отвечать своим отправителям, и узнать об этом было
бы неоткуда».

Ревью кода показало цену этого подхода. Цитата из источника:

> при `api.telegram.org`, отвечающем молчанием, процесс висит в `getMe` без
> ограничения времени: HTTP-вход не открыт, панель не открыта, `/health` не
> отвечает вовсе, воркеры не запущены, в журнале — ни строки.

То есть перезапуск в минуту чужой аварии оставлял без работы приём по HTTP,
панель и конвейер, которому Telegram не нужен вовсе. Паспорт при этом называет
основным входом приложение, а бот и HTTP API — дополняющими его.

Тем же ревью снят довод, на котором держалась прежняя редакция. Она утверждала,
что «Telegram не признал бота» и «до Telegram не дошли» различать нечем. Цитата
из источника:

> Различать есть чем: ответ Bot API приезжает своим типом с кодом, транспортный
> отказ — нашим после чистки, и одно от другого отделяется проверкой типа.
> Утверждение держалось на незнании библиотеки, а не на её устройстве.

Решение владельца: недоступность Telegram на старт приложения не влияет.

Из него следует второе, без которого оно невыполнимо: ожидание при сборке
ограничено сроком. Пока срока не было, недоступность не отличалась от подъёма.
Срок стоит только на сборке — длинный опрос им не ограничен, иначе он рвался бы
на каждом круге.

## Последствия

- `+` авария Telegram не роняет основной вход, панель и конвейер: сервис
  поднимается и обрабатывает уже принятое;
- `+` опечатка в токене по-прежнему заметна: Telegram отвечает отказом, и старт
  не проходит;
- `+` молчащий Telegram больше не вешает подъём бессрочно;
- `−` долгая недоступность Telegram даёт сервис, работающий без бота, а
  отправители в это время не получают ответов. Замена «узнать неоткуда» —
  запись журнала при старте и признак поднятости входа метрикой;
- `−` токен, не разбирающийся как часть адреса (перенос строки из шаблона
  выкладки), Telegram не отвергает — его отвергает разбор адреса, и такой случай
  попадает в недоступность, а не в ошибку настройки. Заметен он записью журнала,
  а не отказом старта.

*Уточнено 2026-08-13:* исходов сборки клиента, роняющих старт, стало два —
к ответу «такого бота нет» добавился пустой ключ доступа при включённом входе.
Решение это не меняет: пустой ключ ошибкой настройки и был, просто прежде он
выражал ещё и отказ от входа, а теперь отказ выражает признак `telegram.enabled`
и до сборки клиента не доходит вовсе. Недоступность Telegram по-прежнему подъёму
не мешает — ровно как решено здесь. Разведение двух значений — отдельная запись,
[ADR-2026-08-13-telegram-intent-declared-not-inferred](ADR-2026-08-13-telegram-intent-declared-not-inferred.md).
