Files
transcriber/openspec/changes/archive/2026-08-13-telegram-enabled-flag/review/code-review.md
T
av cd57b68215 config: включение Telegram разведено с ключом доступа
- в секции [telegram] заведён обязательный ключ enabled: умолчания у него нет,
  файл без него негоден; bot_token стал только ключом доступа и при
  enabled = false не читается вовсе, а пустой при enabled = true роняет старт
- выключенный вход даёт подъём одним входом без единого обращения к Telegram и
  записью INFO вместо прежнего WARN: это выбор владельца, а не отклонение
- отказ разбора файла настроек больше не пересказывает toml — её ParseError
  несёт в тексте разбираемое значение, и оборванная строка секретного ключа
  уносила его в журнал; теперь называются путь, строка, столбец и последний ключ
2026-08-13 21:46:14 +03:00

8.5 KiB

Ревью кода — telegram-enabled-flag

Метка medium, режим по графу. Состав: autotests, specs, code, basics, triage. Проходы adversary, ops, architecture не запускались — живут с метки large.

План с исходом по каждой теме

Тема Дом Глубина Кто закрывает Исход
requirements openspec/specs/intake/spec.md + дельта разбор specs закрыта, 3 находки
autotests CLAUDE.md, «Гейт» autotests закрыта, 3 находки
conventions docs/conventions/config.md разбор code закрыта, 3 находки
architecture docs/architecture.md, «Компоненты», «Единые точки» разбор basics закрыта, находок нет
security docs/security.md разбор basics закрыта, находок нет
operations docs/architecture.md, «Эксплуатация» разбор basics закрыта, 2 находки

Тем без отчёта нет, тем без дома нет, своих тем проекта нет.

Состояние гейта

Зелёные: build, vet, gofmt, tests (-race, флака нет при -count=1 трижды), golangci-lint (0 issues), shell, dockerfile, go-version, migrations, openspec, vulns.

Красные: docs и tasks — «проект приведён к раскладке версии 3, текущая — 4». Краснота унаследована: проход autotests воспроизвёл её в отдельном рабочем дереве на чистом 903941f без диффа. Чинится операцией upgrade скилла av-dev:canon и к этой работе не относится.

vulns: единственная уязвимость GO-2026-5932 в golang.org/x/crypto/openpgp недостижима из кода и уже названа в CLAUDE.md.

Находки и что с ними сделано

15 сырых находок, после дедупликации по причине — 8 живых.

Находка Severity Исход
telegramFromConfig не прогонялся с включённым входом (покрытие 2 0) major починено до остальных проходов: два теста на связку «собрать клиента → разобрать исход»
Ветка decodeError с пустым последним ключом не покрыта (1 0) major починено: тест на опечатку «незакрытая скобка секции»
1 Раздел «Эксплуатация» предписывает обратный порядок выкладки — по нему сервис не поднимется вовсе major принята, docs/architecture.md переписан: порядок задаётся по ключу, а не по файлу, плюс два случая отката
2 Сторож инварианта «секрет не покидает конфиг» зелен по построению major принята, проверка переписана честно; оракул триажа — мутация Validate() на утечку оставляла её зелёной
3 Шапки ErrEmptyToken и AbsentMessageSender защищают снятое поведение minor принята, обе переписаны под новый разрез
4 Признак поднятости входа не держится ни одной проверкой minor принята, утверждение о нуле добавлено в тест выключенного входа
5 Новый абзац конвенции снимает с учёта непроверяемую границу update_timeout minor принята, утверждение сужено до двух ключей
6 Норма «отказ разбора не несёт значения» живёт вне спек, дом не назначен minor принята как развилка (а): дом назначен явно в design.md — инвариант плюс конвенция
Смена версии библиотеки разбора могла бы вернуть утечку гипотеза действия не требует: ловится добавленными проверками, подтверждено мутацией
Третий случай отката: образ старше 2026-08-13 гипотеза свёрнуто в находку 1, записано вопросом владельцу

Проход security находок не дал: починку утечки он проверил по исходникам библиотеки независимо и признал разрез верным.

Сигнал о заниженной метке

review-code подал сигнал: изменение вводит обязательный ключ настроек без умолчания, уже выложенный файл после этого не грузится, а имя ключа конфига проект числит необратимым. На метке large порядок выкладки и откат закрывал бы отдельный проход ops. Сигнал материализовался находкой 1 — её нашёл basics попутно, а не проход, для неё предназначенный. review-basics возражений по метке не подавал. Метка прогона не пересматривалась: правило запрещает.

Границы покрытия

  • Три прохода не запускалисьadversary, ops, architecture. Уносят с собой враждебный разбор входов, отдельный разбор выкладки и отката, и независимый разбор архитектурного решения.
  • Ни один из четырёх проходов не сообщил свой потолок и остаток за срезом. Это находка о самом прогоне: без такой строки «находок больше нет» неотличимо от «больше не поместилось». У basics риск выше прочих — одна квота на три темы.
  • Решения проекта не сверялись: docs/adr/ — процессный документ, прогон его не открывает. Расхождение с ADR-2026-08-13-telegram-outage-does-not-block-startup, который это изменение частично отменяет, ловит не ревью, а сверка документации.
  • Записанные наблюдения не использовались: docs/research/ не открывался.
  • Поимённая сверка с руководствами по стилю Go не задавалась никем — в частности, для шва-параметра вместо интерфейса.
  • Альтернативной реализации, с которой можно сдиффить решения, у конвейера нет — проход независимой реализации снят по стоимости.
  • Живьём проверяемо не всё. Подъём, отказ старта, маршруты и остановка — проверены. Приём из Telegram, расшифровка и заливка — нет: боевым токеном запускаться запрещено, ключи Yandex выдуманы, распознавание подменяется в коде. Новый разрез при включённом входе с настоящим ботом не проверялся ничем, кроме подставной сборки клиента.
  • Шаблон настроек в pet-project-server лежит в чужом репозитории и во вход не входил ни одному проходу.