Files
transcriber/openspec/changes/archive/2026-08-13-telegram-enabled-flag/review/design-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

7.1 KiB

Ревью дизайна — telegram-enabled-flag

Метка medium, назначена агентом review-scope (размер среднее, сложность знакомое). Режим по графу. Состав по метке: specs (режим «дизайн ДО кода») и rubric. Триажа на этой стадии нет — сток стадии — шаг отработки замечаний.

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

Проход Находка Severity Исход
specs У выключенного входа нет оракула: «бот не заведён, отказа нет» остаётся верным и когда ветка встала после обращения, а обращение ушло боевым токеном в живой Telegram major принята. Заведён шов telegramFromConfig(cfg, newBot, logger), шаг 3.3 судит по счётчику вызовов, а не по исходу
specs ADR-2026-08-13-telegram-outage-does-not-block-startup утверждает, что старт роняет ровно один исход сборки клиента; после изменения их два minor принята. Шаг 4.7: новый ADR и парный статус прежнему
specs docs/architecture.md (перечень capability) и docs/review.md (рецепт живого прогона) останутся ложными: они учат поднимать сервис пустым токеном minor принята. Шаги 4.5 и 4.6
specs Ошибочный enabled = false из шаблона выкладки — оставшееся русло молчаливой потери бота — в рисках не назван minor принята. Строка в Risks / Trade-offs
rubric Отказ разбора файла настроек может унести секрет в журнал: toml.ParseError встраивает разбираемое значение в текст major снята из объёма, ушла в урожай. Путь существует сегодня (LoadConfig заворачивает через %w, main.go:49 печатает целиком) и этой работой не заводится; у починки своя цена — потеря подробности отказа
rubric Задача, принятая из Telegram до выключения входа, завершится, а ответ не уйдёт major снята: ложноположительная. Уже нормировано openspec/specs/pipeline/spec.md, «Недоставленный ответ не роняет шаг», сценарий «Вход отправителя не поднят»: WARN, метрика, идентификатор задачи. Проход читал только intake; specs пришёл к тому же выводу независимо
rubric Откат образа при enabled = false и непустом ключе тихо поднимает выключенного бота minor принята. Абзац в Migration Plan
rubric docs/conventions/config.md, раздел «Структура в коде», останется утверждать, что умолчание есть у каждого поля minor принята. Шаг 4.4 расширен на второй раздел

Правки, сделанные по урожаю

Дельта-спеки не менялись ни одной правкой — значит разметка не повторялась и метка осталась medium. Правки легли в design.md (шов сборки, два риска, абзац отката) и в tasks.md (шаги 2.2, 3.2, 3.3, 4.4, 4.5, 4.6, 4.7, рубрика в критерии приёмки).

Сознательно не сделано

Сценарий «Вход выключен» не получил строки **AND** признак поднятости входа Telegram равен нулю. Её держит соседнее требование «Поднятые входы видны наблюдателю», чей сценарий стоит на премиссе «сервис поднялся без Telegram» и новое состояние покрывает. Правка изменила бы дельта-спеку и потребовала бы повторной разметки, не дав сегодня ничего.

Границы спеки — что осталось неопределённым

  • Небулево значение признака (enabled = "yes") попадает в общий отказ разбора и имени ключа не называет, хотя оба соседних сценария отказа этого требуют.
  • Несколько негодных секций разом: [auth] и [telegram] проверяются порознь, и спека не говорит, обязан ли отказ перечислить все ключи.
  • update_timeout при выключенном входе — читается или игнорируется, не нормировано. Вреда нет, но вопрос стал видимым: сборка получает секцию целиком.
  • Проба готовности при выключенном входе ни одним требованием не связана с признаком. Граница существовала и до изменения.

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

  • Кода нет по построению: направление spec → code недоступно, судилось только задуманное.
  • Рубрика составлена не открывая код и дизайн — иначе она подстроилась бы под увиденное.
  • Решения (docs/adr/) и измеренные числа (docs/research/) прогон ревью не открывает: расхождение изменения с записанным решением ловит не он, а сверка документации. Здесь оно всё же всплыло — проход specs наткнулся на ADR через ссылку из design.md, а не обходом каталога.
  • Ничего не запускалось: openspec validate --strict — единственная выполненная команда.
  • review-architecture на предложении не запускался: он живёт с метки large. Вопрос «не появился ли второй способ делать то же самое» на этом изменении не задавал никто.
  • Шаблон настроек в pet-project-server лежит в чужом репозитории и во вход не входил ни одному проходу.