# 🧹 Ловить гейтом расхождение спеки с маршрутами

- **Тип:** chore
- **Категория:** Ядро
- **Зачем:** Рукописная спека — источник истины, а расходится она с кодом молча: без гейта решение о рукописной спеке не держится
- **Теги:** goal:read-api, sprint:2026-08-04

Маршрут, которого нет в спеке, и поле ответа, которого спека не обещала, красят
гейт — рукописный контракт перестаёт расходиться с кодом молча.

Это не украшение к спеке, а то, чем держится решение писать её руками. Без
проверки рукописная спека расходится с первого же маршрута, и потребитель,
сгенерировавший по ней клиент, узнаёт об этом последним.

Класс отказа тот же, что у остальных безусловных шагов гейта проекта: не виден
глазами и стоит дорого. Место ему там же.

Двигает строку «Завершения» цели: «Контракт чтения читается машиной».

## Критерии приёмки

- добавленный маршрут без правки спеки красит гейт — оракул: намеренно
  рассогласованный маршрут в прогоне гейта
- переименованное поле ответа красит гейт — оракул: намеренное переименование в
  прогоне гейта
- проверка укладывается в бюджет гейта — оракул: замер шага по логу
  `tmp/gate/`
- проверка работает без внешней сети — оракул: прогон гейта в контейнере без
  доступа наружу

## Рамки

Трогает `Taskfile` и шаги гейта, кода маршрутов не касается. Берётся после
спеки: проверять нечего, пока нет источника истины.
