Files
houseplan-card/docs/reviews/CODE-REVIEW-520-r3.md
T
claude[bot] b2346eaac3
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Successful in 2m16s
Проверка (CI) / Классификация изменённых файлов (push) Successful in 1m55s
Проверка (CI) / HACS: валидация репозитория (push) Skipped
Проверка (CI) / Hassfest: манифест интеграции (push) Skipped
Проверка (CI) / Мутанты по диффу (1/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (2/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (3/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (4/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (5/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (6/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Skipped
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 52s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Skipped
docs: review document for #520
Issue: #520
User-Visible: no
2026-09-10 18:26:40 +00:00

231 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CODE-REVIEW-520-r3
Issue: #520 · Этап: code · Заход: r3 · Материал: `a325294d7a9d8ef4ecfeab2ed3e248318a650ab5`
Вердикт: **зелёный** · High: 0 · Medium: 0
## Скоуп
Третий заход код-ревью после жёлтого r2 (`docs/reviews/CODE-REVIEW-520-r2.md`,
единственная находка Medium-1: `node scripts/check-docs.mjs` красный на материале
ревью — диф трогает `src/houseplan-card.ts` и `src/config-adoption.ts`, что
инвалидирует отпечаток скриншотов документации, а ветка не привезла свой коммит
обновления).
Дельта r2→r3 — ровно один коммит правки `a325294d` поверх материала r2
(`462b5645`) плюс публикационный коммит документа r2 (`3066fec1`, без кода):
```
$ git diff --stat 462b5645..a325294d
docs/images/screenshots.json | 24 +--
docs/reviews/CODE-REVIEW-520-r2.md | 358 +++++++++
2 files changed, 370 insertions(+), 12 deletions(-)
```
Дельта **локальна** в смысле §2.9/§2.10: только `docs/images/screenshots.json`
(класс C, отпечаток + 11 `sourceSha256`), ни одного файла класса A/B, `dist/**`
и `custom_components/houseplan/frontend/**` не тронуты, продуктовый код между
r2 и r3 не менялся вовсе (`git diff 462b5645..a325294d -- src test scripts
custom_components` — пусто). Разбор в этом раунде сужен до дельты и до находки
r2 — остальное наследуется из r2 без повторной проверки (раздел ниже).
## Как проверялось
1. Найден вердикт предыдущего раунда (комментарий issue #11, 2026-09-10
17:47:34) и материал, на котором он получен: `462b56453cd6948c083e62ad8c92ec29aeb022b2`,
зафиксирован в `docs/reviews/CODE-REVIEW-520-r2.md` блоком «Материал раунда».
`git diff 462b5645..a325294d` — предмет этого раунда (см. «Скоуп»).
2. По единственной находке r2 показано, чем именно она закрыта — не заявлением
автора: `git diff 462b5645..a325294d -- docs/images/screenshots.json`
меняет ровно `sourceFingerprint` и 11 полей `sourceSha256`
(`ccbbfb4e5aa1… → c615d58061456…`), ни один `imageSha256` не изменился —
то есть ни один PNG не поменялся, менялся только отпечаток источников.
Прогнал сам:
```
$ node scripts/check-docs.mjs
Documentation checks passed (7 files, 12 external links).
```
Красный до фикса зафиксирован в документе r2 буквальным выводом той же
команды («ERROR screenshot source fingerprint is stale…») — «умеет падать»
доказано предыдущим раундом, здесь показан переход в зелёное на исправленном
материале.
3. Трейлеры коммита `a325294d`: `Issue: #520`, `User-Visible: no` — корректно,
диф не меняет ничего, что видит пользователь дома (только служебный
отпечаток документации); changelog не тронут — соответствует.
4. `dist/**` и `custom_components/houseplan/frontend/**` не входят в диф этого
коммита (`git show --stat a325294d`) — ожидаемо для чисто документационной
правки; сверил, что три копии бандла всё ещё совпадают побайтово:
`cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js`
— молча (совпадают).
5. `node scripts/process-gate.mjs` на диапазоне `origin/dev..HEAD` — «гейт
пройден, предупреждений 2» (те же WARN про `node_modules` вне классов
A/B/C/D на исторических коммитах `37ef970d`/`e181b08f`, уже закрыты и
разобраны в r1/r2 как гигиена ветки, не влияющая на финальное дерево).
6. Дешёвые гейты (`typecheck`, `npm test`, `npm run build` со сверкой копий
бандла) на точном материале `a325294d` подтверждены зелёным Validate:
https://github.com/Matysh/houseplan-card/actions/runs/34513504274
(`headSha` сверен через `gh run view --json headSha` — совпадает с
материалом раунда). Не перегонял третьей парой глаз — принято по инструкции
ревью, это не новый код с прошлого раунда (продуктовый код между r2 и r3
не менялся).
7. **Тело issue менялось повторно после r2.** Ревью r2 уже зафиксировало
расхождение с записанным хешем SPEC-REVIEW-520-r3 (#517: `60492a3aec5f…`
против тогдашнего `4524f04412...`). Между вердиктом r2 (17:47:34) и
материалом r3 тело изменилось **ещё раз** — автор сам называет это в
хендоффе (комментарий issue #12): добавлены AC7 и пункт риска про отпечаток
скриншотов, по прямому требованию находки Medium-1 r2. Текущий хеш тела:
`sha256sum` по тексту, полученному `gh issue view 520 --json body -q .body`
→ `f318b25f5815fa66aeaa7cbc5ce1d63e23fab0a8e50493962634b01e0ca86e96` —
отличается от обоих предыдущих записанных значений. Сверено построчно:
правка аддитивна — AC1–AC6, «Причина», «Контракт», «Риски» (кроме одного
нового пункта) не тронуты; новый AC7 («`check-docs` зелёный на материале
ревью») и новый риск-пункт об отпечатке скриншотов дословно описывают
именно то, что закрывает коммит `a325294d`, и ничего сверх этого. Новых
продуктовых развилок текст не вводит, `User-Visible: no` не меняется.
Возврата в `S4-spec-review` не требую — та же логика, что применил r2 к
первому расхождению (дисциплинированное обновление ТЗ вслед за находкой
кода, не смена скоупа).
## Закрытие раунда r2
| Находка r2 | Чем закрыта | Где это видно |
|---|---|---|
| Medium-1 — `node scripts/check-docs.mjs` красный на материале ревью: отпечаток скриншотов документации устарел (диф трогает `src/houseplan-card.ts`, `src/config-adoption.ts`) | Коммит `a325294d`: отпечаток обновлён через `npm run docs:accept -- --identical` (#512) — все 11 кадров пересняты и совпали с закоммиченными побайтово (ни один `imageSha256` не изменился), обновился только `sourceFingerprint` и 11 `sourceSha256` | Прогнал `node scripts/check-docs.mjs` на материале `a325294d` сам — «Documentation checks passed (7 files, 12 external links)»; `git diff 462b5645..a325294d -- docs/images/screenshots.json` показывает ровно 12 изменённых полей, ноль изменённых `imageSha256` |
Находка r2 закрыта полностью и минимально — правка не расширилась за пределы
её предмета.
## Унаследовано из r2 (без повторной проверки)
Продуктовый код между материалом r2 (`462b5645`) и материалом r3 (`a325294d`)
не менялся — дельта чисто документационная (см. «Скоуп»), поэтому из
`docs/reviews/CODE-REVIEW-520-r2.md` наследуется всё содержательное:
- **Находка r1 (High) и её закрытие.** Механизм регрессии (микрозадача после
`await` в `adoptAuthoritativeGated`, а не Lit `wrapped`) и хук `afterAdopt` —
r2 перепроверил независимым измерением на изолированном `git worktree`
(база `a44fbd37` vs `462b5645`), оба профиля (`interaction`, `isometric`),
`benchmark:compare` — все строки бюджета зелёные. Код с тех пор не менялся,
повторное измерение в этом раунде избыточно.
- **AC1, AC2, AC6** — тесты и все четыре мутанта (`adoption-bodies-declared-reactive`,
`adoption-notifies-no-host-on-config-replacement`, `adoption-tail-defers-caller-hook`,
`authoritative-load-seeds-devices-after-the-await`) перепрогнаны r2 лично,
«поймано 1 из 1» каждый; код, которого это касается, в дельте r2→r3
отсутствует.
- **AC3, AC4, AC5** — измерены r2 независимо (не на слово автора): 18 циклов /
3 сборки / 3 эпохи на обоих деревьях и обоих профилях, `benchmark:compare`
— 0 красных строк, `cache.entries.cleanFloor` 100 (interaction) / 60
(isometric). Перф-путь этой дельтой не задет.
- **Бюджет бандла** (потолок 300 300 → 300 400, +40 Б) и `test/bundle-assets.test.mjs`
(26/26 pass) — не тронуты дельтой.
- **17 из 17 «прямых совпадений» `smoke-select`** плюс 3 названных автором
сверх выборки — прогнаны r2 лично, все `OK`; исходный код, который они
проверяют, в этой дельте не менялся.
- **Гигиена ветки** (симлинк `node_modules`, исправление `.gitignore`) —
зафиксирована в r1, не менялась.
- **Первое расхождение тела issue с хешем SPEC-REVIEW-520-r3** (#517) —
разобрано r2, решение «возврата в spec не требую» подтверждено тем же
рассуждением и в этом раунде (см. п.7 «Как проверялось» — уже про второе,
новое расхождение).
- **Откат** — «один revert» из ТЗ технически устарел (теперь три файла, не
один), это отмечено уже r2 как факт вне AC; не предмет этого раунда.
Материал: `docs/reviews/CODE-REVIEW-520-r2.md`, SHA `462b56453cd6948c083e62ad8c92ec29aeb022b2`.
## Что проверено и корректно
- **AC7** (новый в теле issue, добавлен вслед за находкой Medium-1 r2) —
`node scripts/check-docs.mjs` зелёный на материале `a325294d`, прогнан
лично: «Documentation checks passed (7 files, 12 external links)».
«Чем краснеет» — устаревший `sourceFingerprint`, продемонстрировано самим
переходом красный (документ r2) → зелёный (этот документ) на одном и том же
коде отпечатка.
- Ни один `imageSha256` не изменился в диффе r2→r3 — визуальный контент
скриншотов не менялся, обновление чисто механическое (отпечаток источников).
- Три копии бандла (`dist/houseplan-card.js`,
`custom_components/houseplan/frontend/houseplan-card.js`, стендовая не
коммитится) совпадают побайтово — сверено `cmp`.
- Трейлеры `a325294d` — `Issue: #520`, `User-Visible: no`, корректно для
чисто документационной правки.
- `node scripts/process-gate.mjs` — гейт пройден, предупреждения те же, что
и в r1/r2 (гигиена исторических коммитов, не влияет на финальное дерево).
- Validate зелёный на точном материале раунда (`headSha` сверен явно, не
принят на слово) — typecheck/test/build подтверждены этим прогоном.
- Второе расхождение тела issue с записанным хешем ревью ТЗ — названо,
разобрано построчно (аддитивно, соответствует коммиту `a325294d`), решение
«без возврата в spec» обосновано.
## Чего не проверял
- **`npx tsc --noEmit`, `npm test` (весь набор), `npm run build` третьим
прогоном** — Validate зелёный на точном материале `a325294d`
(headSha сверен), продуктовый код между r2 и r3 не менялся; перегон дал бы
тот же результат, что уже подтверждён r2 и Validate.
- **Полное измерение перф-профилей (`benchmark:compare`)** — не перегонял: код
пути загрузки не менялся между r2 и r3, r2 уже воспроизвёл результат
независимо на изолированном `git worktree`, эта дельта его не касается.
- **Смоки `demo/smoke_*.mjs`** — не перегонял ни одного: диф r2→r3 не
затрагивает `src/**`/`demo/**`, `smoke-select` на этой дельте не даёт ни
одного совпадения (проверил: диф ограничен `docs/**`, инструмент по
символам кода не находит кандидатов).
- **`npm run golden:verify`** — не запускал: диф не меняет рендер ни байтом,
визуальная приёмка `--identical` уже доказала попиксельное совпадение всех
11 кадров с закоммиченными PNG.
- **`npm run invariants`, `python -m pytest tests_backend`** — geometry и
Python-бэкенд этой дельтой не затронуты (не были затронуты и всей веткой,
подтверждено r2).
## Гейты: что прогнал сам и почему
| Гейт | Прогнан | Результат |
|---|---|---|
| `node scripts/check-docs.mjs` | да (предмет находки r2, обязателен) | зелёный: «Documentation checks passed (7 files, 12 external links)» |
| `git diff 462b5645..a325294d` (полный, не только имена файлов) | да | 2 файла: отпечаток + публикационный документ r2 |
| `cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js` | да | совпадают побайтово |
| `node scripts/process-gate.mjs` | да | пройден, 2 предупреждения (унаследованы, не новые) |
| `gh run view 34513504274 --json headSha,conclusion` | да | `headSha` = материал раунда, `conclusion: success` |
| `sha256sum` тела issue | да | отличается от обеих предыдущих записей — находка по #517, разобрана в тексте (не блокирует) |
| `npx tsc --noEmit`, `npm test`, `npm run build` (свежий прогон) | нет | Validate зелёный на точном SHA, продуктовый код с r2 не менялся |
| Perf `benchmark:compare` (оба профиля) | нет | код пути загрузки не менялся с r2, где уже измерено независимо |
| `demo/smoke_*.mjs` | нет | дельта не касается `src/**`/`demo/**`, кандидатов ноль |
| `npm run golden:verify` | нет | визуальный контент не менялся, доказано `--identical` |
| `npm run invariants`, `pytest tests_backend` | нет | geometry/backend вне диапазона всей ветки |
## Вердикт
Зелёный. High: 0, Medium: 0. Единственная находка r2 (Medium-1, `check-docs`
красный из-за устаревшего отпечатка скриншотов) закрыта минимальной и точной
правкой — один файл, только отпечаток, ни одного изменённого PNG; перепроверено
прямым прогоном гейта на материале раунда, не на слово автора. Продуктовый код
не менялся с r2, чья находка High (регрессия первого кадра) и все AC1–AC6 уже
были независимо перепроверены измерением и остаются в силе. Новое, второе
расхождение тела issue с зафиксированным хешем ревью ТЗ (#517) названо и
разобрано — аддитивно, соответствует коду, возврата в spec не требует. Задача
готова к пре-релизной очереди.
---
## Материал раунда
- Ветка: `issue/520-first-frame`, коммит `a325294d7a9d8ef4ecfeab2ed3e248318a650ab5`.
- Родитель материала r2: `462b56453cd6948c083e62ad8c92ec29aeb022b2` (`docs/reviews/CODE-REVIEW-520-r2.md`).
- Тело issue на момент ревью: sha256 `f318b25f5815fa66aeaa7cbc5ce1d63e23fab0a8e50493962634b01e0ca86e96`
(получено `gh issue view 520 --json body -q .body | sha256sum`), отличается от
записанного в SPEC-REVIEW-520-r3 (`60492a3aec5f…`) и от значения, названного
в CODE-REVIEW-520-r2 (`4524f04412...`) — разобрано в тексте, возврата в spec
не требует.
- Вердикт этого документа: зелёный · High 0 · Medium 0
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/520-first-frame`, коммит `a325294d7a9d` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `f7b30b932911c9f15765594194a6a0b7852d9f1c`
```
git log --all --format='%H %T' | grep f7b30b932911
```
- Тело issue: `80073dd20133cdbba0bc717c7996f490c2d9010734fecedc11fcf8f894190143`
- Вердикт конвейера: `green` · High 0