tasks: заведён остаток работы о гейте, контексте и токене

- четыре новые записи: проверить шаг migrations так же, как шаг сверки версий Go;
  свести шесть расхождений между документами канона; запретить обращаться к Bot
  API мимо клиента бота; разведка о шагах гейта, теряющих предмет
- context-cancel-in-pipeline приведена к правде: дописан перечень сделанного
  попутно, критерий с оракулом «тест на трёх прерываниях подряд» разбит надвое —
  проверена была только его узкая половина
This commit is contained in:
av
2026-08-13 10:55:38 +03:00
parent f4d8c7ed50
commit eacaf76d5f
6 changed files with 230 additions and 7 deletions
@@ -0,0 +1,50 @@
# 🧹 Запретить обращаться к Bot API мимо клиента бота
- **Тип:** chore
- **Категория:** Очередь — Класс уже дал утечку токена; сегодня его держат две проверки на сегодняшних местах, а не правило.
- **Зачем:** Чистка отказа от адреса с токеном живёт в клиенте; свой http.Client в транспорте вернёт утечку молча — правило noctx такую подмену не ловит, а класс уже стоил одного дефекта.
Токен бота стоит в пути каждого обращения к Bot API, а `http.Client` кладёт
адрес запроса в `*url.Error` целиком. Поэтому 2026-08-13 чистка перенесена на
границу клиента: `internal/adapter/telegram`, `NewBot` — свой `Do` разворачивает
отказ в первопричину, а подменённый логгер вычищает токен из строк самой
библиотеки. Случай записан в журнал дефектов
[review.md](../../docs/review.md), 2026-08-13.
Держится это на двух стыках, и оба обходятся одной строкой: скачивание записи
берёт клиента у бота (`c.bot.Client.Do`), а не общий, и бот заводится единой
точкой, а не `tgbotapi.NewBotAPI`. Проверки на оба стыка есть
(`internal/controller/tg/download_test.go`,
`internal/adapter/telegram/bot_test.go`), но они судят **сегодняшние** места:
новый файл в транспорте, заведший свой клиент, они не увидят.
Ступень по лестнице механизации — четвёртая: свойство о структуре, а не о
вызове, и выражается тест-сканером в `internal/archrules`.
## Затрагивает
- `internal/archrules` — новое правило-сканер и его перечень предметов;
- `internal/controller/tg` — как поднадзорный пакет;
- `internal/adapter/telegram` — как единственное законное место, где клиент
заводится;
- [go-linters.md](../../docs/conventions/go-linters.md) — строка в перечне
механизированного и снятие соответствующей прозы.
## Критерии приёмки
- Свой `http.Client`, `http.DefaultClient` или `tgbotapi.NewBotAPI` в
`internal/controller/tg` роняет проверку и называет файл. Оракул — мутация:
внести каждую из трёх форм по очереди, все три краснеют.
- Законное употребление в `internal/adapter/telegram` проверку не роняет.
Оракул — тот же прогон на нетронутом дереве, зелёный.
- Правило не молчит, потеряв предмет: переименованный или исчезнувший пакет
роняет проверку, а не проходит обходом по пустому перечню. Оракул — мутация с
переименованием каталога.
- Правило записано строкой в `go-linters.md`, и проза, которую оно заменило,
оттуда снята. Оракул — чтение записи.
## Рамки
Боевым токеном не запускаться: сканер читает исходники, живого бота ему не
нужно. Внутренний логгер библиотеки правилом не выражается — его сторожит
проверка `TestLibraryLoggerIsActuallyInstalled`, и это остаётся так.