WEB-302 · Дефект · Инфраструктура · web
STAND-BUILD-RECEIPT ставит PASS по одному критерию «rc=0»: неработающий стенд доехал до подписи владельца
Закрыт
P0 · горит
ведёт: backup-opus
Суть
## Суть
`STAND-BUILD-RECEIPT.json` объявляет `result: PASS`, если **все команды сборки вернули rc=0**. Ничто не проверяет, что собранный стенд вообще запускается. Именно поэтому стенд с 21 неразрешимым пакетом из 31 прошёл сборку, прошёл гейт preflight (12 проверок из 12, включая tree sha и build receipt) и был **подписан владельцем** — и умер на первом require.
Это ровно наш выстраданный класс: **верификатор, который сверяет форму и не требует существа**. Ревизор ловил нас на нём четырежды; здесь мы поймали себя сами, но уже после того, как дважды позвали владельца подписывать.
## Что должен требовать receipt, чтобы стать PASS
1. Стенд поднялся на своём порту и ответил **200 на `/api/health`**.
2. Статический обход всех top-level пакетов и их `dependencies` дал **0 неразрешимых** (инструмент уже написан в rolesbattery — переиспользовать, не писать заново).
3. `find <stand> -type l | wc -l` == 0 (требование «symlink запрещён» проверяется, а не декларируется).
## Обязательное условие приёмки
**Негативный тест** (правило смены: верификатор без негативного теста бесполезен): искусственно сломать вход — удалить один peer-каталог или не поднимать сервер — и показать, что гейт ПАДАЕТ. Без этого тикет не закрывается.
Правило 10: никаких `catch {}` без лога и маячка; отказ печатает измеренное значение и лимит.
Источник: волна rolesbattery, отчёт M4 `/Users/milamarty/work/ROLESBATTERY-REPORT.md`, run-каталог `/Volumes/M4Ext/ops/paidlegs/rolesrun-20260821/` (21.08 01:42).
Доказательства
[2026-08-25 ~10:25] WEB302_DONE (r9r5-court, commit 38f9c51, локально). STAND-BUILD-RECEIPT требует СУЩЕСТВО не форму: PASS только после 3 fail-closed измерений — (1) стенд поднялся HTTP 200 /api/health; (2) verify_stand_selfcontained.mjs unresolved=0 (переиспользован rolesbattery walker); (3) find -type l==0. create_rolesv10_manifest отвергает старый all-zero receipt; отказы печатают измеренное+лимит. ОБЯЗАТЕЛЬНОЕ условие приёмки ВЫПОЛНЕНО: негативы падают предметно (удалён peer→rc1 unresolved=1 FAIL; сервер не поднят→health=000 FAIL; +symlink), закреплены постоянными тестами; позитив PASS. Регрессии 4/4+6/6+17/17. → review.
[25.08 ~12:55] Коммит 38f9c51 слит в court-main (merge 0895412) вместе с rolesv12 и WEB-090; войдёт в свежий аудиторский пакет rolespack13. Статус review сохраняется — ждёт приёмки.
[2026-08-25 22:57Z] Автор web302: receipt=PASS только после ВСЕХ 3 измерений (не только rc=0); добавлен недостающий verify_stand_selfcontained.mjs walker. → review, ждёт независимой приёмки (негатив: rc=0 но упавшие функц.проверки→FAIL).
[2026-08-26 00:43Z] acc302 NO-GO (независимо): отсутствие self-contained verifier даёт status=NOT-RUN, а не FAIL — значит стенд без verifier может проскочить. Фикс web302fix: NOT-RUN обязательного измерения = FAIL, receipt=PASS только если ВСЕ 3 реально прошли.
[2026-08-26 00:49Z] ФИКС web302fix: verifier отсутствует -> FAIL (NOT-RUN устранён), все 3 обязательных измерения фейл-гейтят, receipt=PASS только если все реально прошли. Сценарии: работает->PASS, verifier нет->FAIL, verifier упал->FAIL, rc=0 но функц.провалены->FAIL. -> review на re-accept.
[2026-08-26 01:20Z] ПРИНЯТ acc302b (повторно, другой приёмщик): GO. Прежний NO-GO класс закрыт — verifier отсутствует→FAIL (не NOT-RUN), verifier упал→FAIL, rc=0+функц.провал→FAIL, рабочий→PASS. → done.
Починено в
a453b16
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-302","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-26T00:21:48.355Z