mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 14:39:22 +00:00
docs(review): record independent green #800 r3
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
# Независимое локальное код-ревью #800 — r3
|
||||
|
||||
Вердикт: зелёный · заход r3 · блокирующих циклов 2/4 · High: 0 · Medium: 0 · Low: 0 · маршрут: fix.
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Дата: 2026-10-05. Независимый код-ревьюер: `/root/code_review_800`,
|
||||
не автор ТЗ, ревью ТЗ или продуктовой реализации.
|
||||
- Предыдущий раунд: [CODE-REVIEW-800-r2.md](CODE-REVIEW-800-r2.md), SHA
|
||||
`4a7abf531bc9bf750073fb7ac7f4a1d9777e83ed`.
|
||||
- Итоговый материал: `07c885435aa6ba8e0dafecf6e06f722f4818202b`;
|
||||
дерево `158399fd47ecd4db4d262e14ed068dea7ce66305`.
|
||||
- Дельта: `git diff 4a7abf531..07c885435` — 9 файлов,
|
||||
200 добавленных и 11 удалённых строк, включая отчёт r2/INDEX.
|
||||
- Продуктовая правка находится в `67af859e8c28bb80cb294bdbb2b0062c0aad0099`.
|
||||
Следующий коммит `07c885435` меняет только fixture в
|
||||
`demo/smoke_zigbee_topology_hover.mjs`; отсутствие product/backend delta
|
||||
проверено `git diff --quiet 67af859e..07c885435 -- src custom_components tests_backend`.
|
||||
- HEAD и чистота рассматриваемых product/test путей повторно сверены перед
|
||||
итогом. Терминальные трейлеры обоих коммитов корректны; продуктовая правка
|
||||
содержит оба changelog, fixture-only коммит — `User-Visible: no`.
|
||||
|
||||
ТЗ не менялось. Разбор по дельте PROCESS §2.10: исправление временного
|
||||
capability-отказа и его async-соседей, плюс корректность fixture. Новых
|
||||
подсистем, геометрии, радио-команд и продуктового скоупа нет. Основание
|
||||
локального порядка — [разрешение владельца для #800](https://github.com/Matysh/houseplan-card/issues/800#issuecomment-5998860326).
|
||||
Ревьюер не правил продукт, не запускал мутанты, не делал commit/push,
|
||||
не менял issue/метки и не выполнял merge/release.
|
||||
|
||||
## Закрытие M1 из r2
|
||||
|
||||
`capability()` теперь сохраняет ссылку на ожидаемый Promise, а при отказе
|
||||
очищает `cache.capability` **только если это всё ещё тот же Promise**
|
||||
(`src/zigbee-topology-runtime.ts:151–159`). Отказ пробрасывается текущему
|
||||
действию; автоматического повторного чтения или публикации нет. Следующее
|
||||
явное действие делает новое чтение. Проверка identity не позволяет позднему
|
||||
отказу старой сессии стереть более свежую проверку.
|
||||
|
||||
Новый unit `#800 explicit retry recovers after config not_ready during
|
||||
same-WS integration reload` воспроизводит полный сценарий r2: closed →
|
||||
явный start/not_ready → готовый replacement → явный retry → новая подписка
|
||||
и новый job → streamed result. Проверяются числа чтений, публикаций,
|
||||
дедупликация одновременных действий и отсутствие auto-retry между действиями.
|
||||
|
||||
Ревьюер повторил свою production-source пробу r2 без записи файлов:
|
||||
после временного отказа `config reads=2`, `server starts=1`, phase error;
|
||||
после явного retry на восстановленном backend — `config reads=3`,
|
||||
`server starts=2`, phase loading, `jobId=new-job`. На материале r2 этот же
|
||||
сценарий оставался в error с 2/1. **M1 закрыта.**
|
||||
|
||||
Зарегистрирован guard
|
||||
`zigbee-background-reload-error-poisons-explicit-retry`: он компилирует
|
||||
production TypeScript перед unit и убирает очистку rejected capability.
|
||||
Статическая проверка якоря зелёная; исполнение мутанта остаётся ночи.
|
||||
|
||||
## Отдельно: гонка старой hover-fixture
|
||||
|
||||
На `67af859e` снова воспроизвёлся timeout проверки искусственного возраста
|
||||
ZHA. Fixture ждала текст `backend_required`, уже сохранённый от прежнего
|
||||
наблюдателя; новая проверка capability могла ещё завершиться и заменить
|
||||
локально подставленный snapshot обычным runtime notification.
|
||||
|
||||
Коммит `07c885435` учитывает реальные незавершённые `config/get` вызовы,
|
||||
ждёт их завершения, одну очередь event loop и `updateComplete`, и лишь затем
|
||||
ставит age-fixture. Нет увеличения smoke timeout или изменения product timer.
|
||||
Оставлены assertions fresh → stale и `zhaCalls === 1`; добавлена проверка,
|
||||
что итоговый `obtainedAt` равен точному подставленному времени. То есть
|
||||
ожидаемый пользовательский исход не ослаблен.
|
||||
|
||||
Исправленный fixture прошёл два предварительных прогона и отдельный прогон
|
||||
на итоговом exact-SHA после его сборки. Первоначальный красный прогон не
|
||||
переименован в зелёный: зелёным является именно исправленный материал.
|
||||
|
||||
## Проверки
|
||||
|
||||
| Команда / проверка | Результат и источник |
|
||||
| --- | --- |
|
||||
| `git diff --check 4a7abf531..07c885435` | PASS, ревьюер |
|
||||
| `node --test test/zigbee-topology-runtime-routes.test.mjs test/zigbee-topology.test.mjs test/zigbee-provider-routes.test.mjs test/zigbee-topology-style.test.mjs` | 57/57 PASS, исполнено ревьюером; эти product/test файлы после `67af859e` не менялись |
|
||||
| `node scripts/mutation-gate.mjs --check` | PASS, ревьюер; прежние 4 предупреждения inventory, мутанты не исполнялись |
|
||||
| `npm run gate:small` на чистой WSL-копии exact `67af859e` | PASS, все 9 шагов, 77 с; прочитан `C:/Temp/hp800-gate-small-wsl-r3.log` |
|
||||
| `npm run gate:small` повторно на exact `07c885435` | PASS, все 9 шагов, 71 с; прочитан `C:/Temp/hp800-gate-small-wsl-final.log`. Build/typecheck, npm test, integrity/budget, no-new-any/private-writes, smoke-select, lint:unused |
|
||||
| `python -m pytest tests_backend -q --tb=short` с coverage в HA harness | 1007 PASS, 1 SKIP, 24,96 с; прочитан `C:/Temp/hp800-backend-coverage-r3.log`. По проверке автора line coverage 88,93% при floor 87,2%; Python в этой дельте не менялся |
|
||||
| `node demo/smoke_zigbee_topology_job.mjs` | 18/18 PASS; прочитан `C:/Temp/hp800-smoke-job-r3.log`. Включены временный not_ready и следующий явный retry на том же WS |
|
||||
| `node demo/smoke_general_settings_form.mjs` | 30/30 PASS; прочитан `C:/Temp/hp800-smoke-general-r3.log` |
|
||||
| `node demo/smoke_zigbee_topology_hover.mjs` на exact `07c885435` | PASS; прочитан `C:/Temp/hp800-smoke-hover-exact-final.log`; все итоговые флаги true |
|
||||
| Визуальное чтение новых артефактов production settings | Ревьюер просмотрел `narrow-light-wait.png`, `narrow-dark-wait.png`, `desktop-ready.png` из `/home/matysh/hp800-final-oct5/artifacts/zigbee-topology-800/`: действия/подсказки не обрезаны, waiting/ready различимы, cancel виден |
|
||||
| Независимая production-runtime проба из r2 | PASS на новом runtime, результат 3 чтения / 2 публикации / новый job после явного retry |
|
||||
|
||||
WSL-команды и browser прогоны исполнял автор, ревьюер изучил указанные логи,
|
||||
assertions и изображения; это не выдаётся за собственный второй полный
|
||||
прогон. Exact-SHA исходная копия — `/home/matysh/hp800-final-oct5`, Node
|
||||
22.23.2, HA 2026.8.3. Backend/новый job/general smoke относятся к
|
||||
`67af859e`; их исполняемые входы не менялись в fixture-only `07c885435`.
|
||||
Полный дешёвый гейт и исправленный hover дополнительно повторены именно на
|
||||
последнем SHA.
|
||||
|
||||
smoke-select снова перечисляет те же 14 имён. Решения по каждой строке
|
||||
находятся в [r1](CODE-REVIEW-800-r1.md) и не изменились: два Zigbee smoke
|
||||
применимы и исполнены; совпадения общих имён lifecycle/snapshot/keyOf не
|
||||
означают изменения независимых геометрических/dialog подсистем. Полная
|
||||
матрица остаётся предрелизной обязанностью.
|
||||
|
||||
## Защитные AC, затронутые дельтой
|
||||
|
||||
| AC / защита | Доказательство | Чем краснеет |
|
||||
| --- | --- | --- |
|
||||
| AC2/AC4/AC6: явный retry после временного reload-отказа | Новый runtime unit, production-source probe, browser `retryDuringReloadDoesNotStartRadioOrDisableRetry` и следующий new-session assertion | `zigbee-background-reload-error-poisons-explicit-retry`; exact reads/publications/job/result не допускают старый cached rejection |
|
||||
| Нет авто-скана/авто-retry | Тот же unit и browser smoke | Между отказом и новым действием publications остаётся 1 в unit / 2 в smoke; setup сам число чтений не увеличивает |
|
||||
| Старый async ответ не ломает нового владельца | Сохранённые 4 reload/ACK/foreign-closed/inflight tests из r2, все 57 unit зелёные; чтением identity guard capability Promise | Foreign/stale событие не меняет revision; old finally/ACK не удаляет новую команду/feed; новый cache не очищается чужим rejected Promise |
|
||||
| AC6: возраст ZHA без нового чтения | Исправленный hover smoke | Сначала fresh, затем stale при единственном `zha/devices`; точный `ageFixtureTime` не заменён runtime notification |
|
||||
|
||||
## Унаследовано из r2 и r1
|
||||
|
||||
Из [r2](CODE-REVIEW-800-r2.md) на `4a7abf531bc9bf750073fb7ac7f4a1d9777e83ed`
|
||||
приняты без нового полного разбора закрытия r1 M2/M3/L1: event-loop witness
|
||||
600/900 секунд и его mutant, backend closed/same-socket lifecycle, разрешение
|
||||
metadata/registry/bundle gate, документация RU/EN/STATUS и обоснованная база
|
||||
размера. Эти механизмы дельта не меняет; обязательные гейты всё равно повторены.
|
||||
|
||||
Из [r1](CODE-REVIEW-800-r1.md) на `379de706d29f4b1547c3b162c1c205654487c6b8`
|
||||
унаследованы J7/скоуп, admin-only, topic/transaction/retained guards,
|
||||
ограниченные ресурсы, last-good/stale, 599/600 cancel/id/race, provider error
|
||||
и MQTT disconnect, optional MQTT/API floor, отсутствие persisted runtime,
|
||||
ZHA cached read и неизменность маршрутов/LQI, локали и единый elapsed formatter.
|
||||
|
||||
Новых находок нет. Числа и пользовательский сценарий имеют те же источники,
|
||||
новой миграции/геометрии/постоянного polling нет. Полная радиосеть владельца,
|
||||
реальный touch/скринридер, полный golden/performance и GitHub Validate/артефакты
|
||||
кандидата беты этим отчётом не проверены. Локальное код-ревью завершено;
|
||||
зелёный вердикт разрешает следующий процессный шаг, но не подтверждает заранее
|
||||
факт merge или публикации.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Индекс ревью
|
||||
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 304, issue: 152. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 305, issue: 152. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
|
||||
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|
||||
|---|---|---|---|---:|---:|---|---|
|
||||
@@ -10,6 +10,7 @@
|
||||
| #800 | [SPEC-REVIEW-800-r1.md](SPEC-REVIEW-800-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #800 | [CODE-REVIEW-800-r1.md](CODE-REVIEW-800-r1.md) | code · r1 | 🟡 жёлтый | 0 | 3 | живой браузер остаётся на умершем job после reload интеграции; AC1 не имеет свидетеля, чувствительного к прежнему 600-секундному deadline; материал не проходит обязательный gate:small; English guide всё ещё обещает прекращение ожидания через 10 минут | `custom_components/houseplan/zigbee_topology.py` `scripts/mutation-registry.mjs` `test/data-hp-contract.test.mjs` `test/reviews-index.test.mjs` `PREFLIGHT-SPEC-800.md` `test/smoke-select.test.mjs` `docs/USER-GUIDE.md` |
|
||||
| #800 | [CODE-REVIEW-800-r2.md](CODE-REVIEW-800-r2.md) | code · r2 | 🟡 жёлтый | 0 | 1 | временный not_ready во время reload навсегда блокирует явный retry | `src/zigbee-topology-runtime.ts` |
|
||||
| #800 | [CODE-REVIEW-800-r3.md](CODE-REVIEW-800-r3.md) | code · r3 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #799 | [CODE-REVIEW-799-r1.md](CODE-REVIEW-799-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #798 | [SPEC-REVIEW-798-r1.md](SPEC-REVIEW-798-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #798 | [CODE-REVIEW-798-r1.md](CODE-REVIEW-798-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
|
||||
Reference in New Issue
Block a user