- в конфиг добавлены секция [auth.test_headers] и предохранитель [server] debug: заголовки входа подставляет слой транспорта, второго процесса локальный запуск больше не требует - подкоманда devtools proxy удалена целиком: всё, ради чего её поднимали, делает сам сервис - адресного предохранителя нет по решению владельца — цена названа в ADR и в модели угроз
68 lines
5.6 KiB
Markdown
68 lines
5.6 KiB
Markdown
# Разбор TOML: незнакомый ключ и незнакомая секция не отказ, а тишина
|
||
|
||
Отвечает на вопрос, возникший по ходу задачи `config-test-headers-login`: что
|
||
делает декодер настроек с ключом и секцией, которых структура не знает, и виден
|
||
ли этот случай хоть чем-нибудь. Наблюдение понадобилось потому, что ревью нашло
|
||
опечатку в имени новой секции `[auth.test_headers]`, проходящую молча, и без
|
||
разреза нельзя было сказать, где кончается предмет задачи и начинается свойство
|
||
самой библиотеки.
|
||
|
||
Соседняя записка о той же библиотеке — [toml-decode-errors.md](toml-decode-errors.md)
|
||
— разбирает семейства **отказов**; здесь предмет обратный: случай, отказа не
|
||
дающий.
|
||
|
||
## Как снималось
|
||
|
||
Прогонами на зависимости, зафиксированной в `go.mod`:
|
||
`github.com/BurntSushi/toml` версии **v1.5.0**. Оба уровня снял триаж ревью
|
||
2026-08-23, отчёт —
|
||
[triage-2026-08-23.md](../../openspec/changes/archive/2026-08-23-config-test-headers-login/review/triage-2026-08-23.md),
|
||
находка 2 и факт, подтверждённый разбором прохода `operations`. Временные файлы
|
||
прогонов удалены, бинарник поднимался в каталог вне репозитория, не в `data/`.
|
||
|
||
- **Модульный.** Вход
|
||
`[server]\ndebug = true\n[auth]\n[auth.test_headrs]\n"Remote-User" = "dev"` —
|
||
опечатка в имени секции.
|
||
- **Сквозной.** Настоящий бинарник на конфиге с той же опечаткой, порт 18099,
|
||
каталог данных вне репозитория; проба `curl /app/me`.
|
||
|
||
## Что выяснилось
|
||
|
||
- **Незнакомая секция и незнакомый ключ отказа не дают: `decode err=<nil>`.**
|
||
Разбор проходит целиком, поля структуры остаются нулевыми, и отличить «в файле
|
||
этого нет» от «в файле это написано с опечаткой» по результату разбора нельзя.
|
||
В прогоне: `Server.Debug=true len(TestHeaders)=0`.
|
||
- **Потерянное называет только `MetaData.Undecoded()`.** Он возвращает перечень
|
||
путей, которых структура не знала: `[auth.test_headrs
|
||
auth.test_headrs.Remote-User]`. Значение это в проекте не читает никто — ни
|
||
загрузка настроек, ни проверки старта.
|
||
- **Контроль показывает, что дело в уровне, а не в разборе вообще.** Ту же
|
||
опечатку **внутри** известной секции (`Remote-Usr` вместо `Remote-User`)
|
||
ловит проверка старта — `auth: секция [auth.test_headers] называет
|
||
заголовок, которого сервис не читает: Remote-Usr`, — потому что судит её код
|
||
проекта, а не библиотека. Ошибка в имени самой секции до этого кода не
|
||
доходит.
|
||
- **Сквозной прогон следа не оставляет вовсе.** Бинарник поднимается без
|
||
предупреждения, `curl /app/me` отвечает `401`, а в журнале стоит только
|
||
`INFO "Incoming request" … http.status_code=401`.
|
||
- **Отсюда направление отката бинарника безопасно.** Прежний образ, получивший
|
||
конфиг с ключами, которых его структура ещё не знает, эти ключи игнорирует и
|
||
поднимается. Свойство держится ровно на тишине выше: перечень
|
||
`MetaData.Undecoded()` никто не судит.
|
||
|
||
## Что из этого следует для кода
|
||
|
||
Свойство сегодня используется, а не терпится: правило выкладки «конфиг после
|
||
образа» опирается именно на него, и его дом — [../architecture.md](../architecture.md),
|
||
«Эксплуатация». Здесь записано, чем свойство обеспечено и как проверено, а не
|
||
надо ли его менять.
|
||
|
||
Отсюда же цена любой будущей проверки `MetaData.Undecoded()`: непонятый ключ,
|
||
роняющий старт, закрывает опечатки во всех секциях разом — и тем же движением
|
||
снимает безопасность отката, потому что прежний образ перестанет поднимать
|
||
конфиг новее себя. Разменивать одно на другое — отдельное решение владельца,
|
||
а не попутная правка.
|
||
|
||
**Наблюдение привязано к версии.** Версия, начавшая судить незнакомые ключи
|
||
сама, сменит оба следствия разом — молчаливую опечатку и безопасный откат.
|