docs(review): self-review LED mutation witness by owner exception (#791)

This commit is contained in:
Matysh
2026-10-04 17:13:49 +03:00
parent 9deb1dcfd6
commit 05c8e164c2
+78
View File
@@ -0,0 +1,78 @@
# Code review #791 — missing LED runtime owner witness
Вердикт: зелёный · High: 0 · Medium: 0 · Low: 0.
## Основание и материал
Саморевью по прямому решению владельца от 2026-10-04:
«модель ревью всё еще недоступна, делай саморевью».
Это исключение для #791, не вердикт недоступной модели конвейера.
Дополнительно другой агент независимо прочитал окончательный дифф: находок нет.
- Issue: https://github.com/Matysh/houseplan-card/issues/791
- Ветка: `issue/791-led-unbound-mutation-guard`.
- Материал: `9deb1dcfd6f049d1e79cb2252a129bf8ecbb4ba7`.
- Дерево материала: `86933107884a58e73ea5670869aab7c2e386adcb`.
- База: `14f5b90c24193335ec978545b5ec933be3de2031`.
- Скоуп: тест, определение одного мутанта, реестр браузерных свидетелей.
Классов A/D нет; пользовательское поведение не меняется.
## Причина и корректность исправления
Ночь [37182609291](https://github.com/Matysh/houseplan-card/actions/runs/37182609291)
зафиксировала выживание `led-unbound-in-view`. Browser fixture с `marker: null`
отбрасывается ранним `!stored.marker`, до проверки отсутствующего устройства,
которую снимает мутант. Это не доказательство, что защита не нужна.
Новый тест исполняет импортированный compiled `ledFrame` с непустой ссылкой,
которой нет в runtime roster. Он проверяет точную единственную пару strip/owner,
а не только отсутствие исключения: валидный сосед должен сохранить on, Glow
и RGB. Также проверяются null-binding, inactive, реально присутствующий owner
другого пространства и неизменность входа. При drop-all положительная проверка
падает. Backend-нормализация отсутствующего конфигурационного маркера в null
не подменяется: тест судит defensive runtime boundary.
Guard перенесён в Node: проверяемый результат — общий frame, который используют
полоса, свет и hit path, а не CSS или input браузера. Существующий browser smoke
не ослаблен и не удалён. Количество browser guards уменьшается на один.
Патч мутанта содержит стираемое non-null assertion на `byId.get`, чтобы strict
TypeScript не отклонил подготовку раньше oracle. При отсутствующем владельце
дальше выполняется `device.hidden`: ожидаемый результат — runtime failure в
новом тесте. Это проверено чтением, не запуском мутанта. Source-text assertions
вместо исполнения consumer не добавлены.
## Исполненные проверки
WSL Ubuntu/ext4, Node 22.23.2, SHA материала выше.
| Команда | Результат |
| --- | --- |
| `npm run gate:small -- --smokes` | PASS, 54 с, 0 отказов: build/typecheck, unit, bundle integrity/budget, lint и прочие обязательные проверки |
| `node --test test/led-strip-runtime.test.mjs` | PASS, 22/22 |
| `node scripts/mutation-gate.mjs --id=led-unbound-in-view --check` | PASS; якорь уникален, guard валиден; 236 browser guards, прежний warning о превышении ориентира 200 |
| `git diff --check` | PASS |
| `node scripts/process-gate.mjs --range origin/dev..HEAD --issues --report` | PASS; B/C-инфраструктура законно без S до ревью |
### Защита — чем доказана и чем краснеет
| Контракт | Доказательство | Чем краснеет |
| --- | --- | --- |
| Отсутствующий runtime owner не ломает frame и не создаёт View-ленту | Новый исполнимый тест #791, точный surviving roster | `led-unbound-in-view`; поимку проверяет ночь, локально мутант не запускался |
| Валидный сосед не теряется | Та же проверка требует `valid/m1`, on, Glow и `#80d5ff` | Пустой/ошибочный roster или потеря состояния/цвета не равны ожидаемому результату |
## Риски и пределы проверки
Данные: проверены отсутствующий runtime owner, чужое пространство и валидный
сосед. Объём/runtime: продукт неизменен, отдельный дорогой browser guard заменён
чистым runtime suite; численная экономия ночного прогона не измерялась.
Async, права, геометрия, визуал и host/input не меняются; новых обещаний о них нет.
Одно число — один источник: пользовательских величин в диффе нет.
Golden, performance, полный browser smoke и HA-harness не запускались для этой
дельты; `smoke-select` сообщает отсутствие исполняемого frontend-диффа.
Mutation execution оставлено ночи по PROCESS §2.7/#709: локальный зелёный
`--check` не выдан за фактическую поимку. После публикации потребуется зелёный
Validate на точном кандидате слияния. Changelog не нужен: `User-Visible: no`.
Открытых находок нет. Закрытие issue — после беты, не по этому вердикту.