- в секции [telegram] заведён обязательный ключ enabled: умолчания у него нет, файл без него негоден; bot_token стал только ключом доступа и при enabled = false не читается вовсе, а пустой при enabled = true роняет старт - выключенный вход даёт подъём одним входом без единого обращения к Telegram и записью INFO вместо прежнего WARN: это выбор владельца, а не отклонение - отказ разбора файла настроек больше не пересказывает toml — её ParseError несёт в тексте разбираемое значение, и оборванная строка секретного ключа уносила его в журнал; теперь называются путь, строка, столбец и последний ключ
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лежит в чужом репозитории и во вход не входил ни одному проходу.