WEB board

всеканоны и докиворкеры↗ iOS↗ Легаси
WEB-070 · Задача · Инфраструктура · web

[GATE-2] Fail-closed boot: default=warn → enforce в production + prod receipt

Закрыт P1 · важно ведёт: backup-opus
Суть
envContract.ts + instrumentation.ts есть, НО resolveMode() по умолчанию warn даже в production (enforcement opt-in), тест закрепляет «production defaults to warn»; envContract.test.mjs сейчас падает SyntaxError до тестов. ОСТАЛОСЬ: (а) починить тест, (б) BOOT_CONTRACT_MODE=enforce на прод + заполнить required env, (в) негативный старт (убрать required var → boot обязан умереть ДО бинда порта) на стенде, (г) prod receipt. Код-часть — в посадку landing30.

Эпик: WEB-282. Норматив: PROD-MIGRATION-PLAN-R4.md §7. Аудит-срез: M4 MIGAUDIT-REPORT.md (20.08). Owner 20.08: «по гейтам дожимайте все до конца».

## 21.08 — ГЕЙТ СРАБОТАЛ НА ЖИВОЙ ПОСАДКЕ (первое боевое применение)
При посадке тридцатой fail-closed boot **остановил** запуск релиза `51d5b74f` в production/enforce с двумя фатальными претензиями и напечатал каждую с именем и группой. Порт не биндился, служба ушла в рестарт-цикл, прод откачен на `f1e49bca` за ~90 секунд.
Подтверждено на живом коде: фатальны только `missing_required` и `missing_conditional` (`envContract.ts:40-41`), `bad_secret_format` — предупреждение.
Одна претензия оказалась настоящей (`APP_URL` действительно отсутствовал на проде — добавлен), вторая — дефектом широкого триггера (**WEB-307**).
Вывод для приёмки гейта: механизм работает и печатает измеренное значение, как требует правило 10. Осталось сузить триггер и повторить посадку.

## 23.08 board-triage (волна btriage, отчёт BOARD-TRIAGE-REPORT.md на A1; применено координатором)
Закрыт: live-контроль 30-й посадки 0 fatal в body + текущий /api/ready/paid mode=enforce, failures=[].
Воркер
не привязан — привязать: curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \ -d '{"issueId":"WEB-070","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-23T00:36:34.405Z