Files
houseplan-card/docs/reviews/CODE-REVIEW-330-r4.md
T
claude[bot] 2d1ca74a7d
Проверка (CI) / Классификация изменённых файлов (push) Successful in 1m30s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 1m50s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m50s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 18s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 28s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 5m56s
Проверка (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) Failing after 6m29s
docs: review document for #330
Issue: #330
User-Visible: no
2026-08-28 00:56:30 +00:00

186 lines
15 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-330-r4
Issue: #330 — «Ограничения стыков (#329) блокируют event loop HA и дёргают ресайз на больших планах»
Этап: code (PROCESS.md §2.7)
Заход: r4 · блокирующих циклов израсходовано 3 из 4 (до этого раунда)
Ветка: `issue/330-junction-limits-performance`, HEAD ревью — `d33aa0a7`
## 0. Разбор по дельте — почему и от какого SHA
Предыдущий вердикт (code-review r3, 2026-08-28T00:49:49Z — жёлтый, High: 1,
Medium: 0) назван на HEAD `04bb54ae`. Проверено, что этот SHA — прямой предок
текущего HEAD и что ребейза не было:
```
$ git merge-base --is-ancestor 04bb54ae HEAD && echo ancestor
ancestor
$ git log --oneline 04bb54ae..HEAD
d33aa0a7 docs: refresh the screenshot pair after the cache-key fix (#330 r3-H1)
90a3313d docs: review document for #330
```
Также проверено, что `dev` не ушёл вперёд за это время:
```
$ git fetch origin dev --quiet
$ git log --oneline -1 origin/dev
eff786fa docs: review document for #62
$ git merge-base --is-ancestor origin/dev HEAD && echo "dev is ancestor of HEAD"
dev is ancestor of HEAD
```
Дельта — два коммита: `90a3313d` — публикация документа r3 (класс C, не код),
`d33aa0a7` — точечный фикс единственной находки r3 (H1). Контракт поведения не
менялся, новая подсистема не задета, объём дельты меньше даже r2→r3. Условия
§2.10/§7.2 для полного разбора не выполнены — разбираю по дельте
`git diff 04bb54ae..HEAD`.
## 1. Скоуп дельты
`git diff 04bb54ae..HEAD --stat`:
```
docs/images/screenshots.json | 22 ++--
docs/reviews/CODE-REVIEW-330-r3.md | 226 +++++++++++++++++++++++++++++++++++++
2 files changed, 237 insertions(+), 11 deletions(-)
```
Только r3-H1 (докс-гейт красный на HEAD предыдущего раунда):
- `docs/images/screenshots.json` — `sourceFingerprint` и все десять
`sourceSha256` заменены с устаревшего `2a5ae6c1…` на актуальный
`dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f` — ровно то
значение, которое r3 уже вычислил независимо (`visualFingerprint()` на
дереве r3, см. документ r3 §3) как «реальное». Ни один `imageSha256`
не изменился ни в одной из десяти сцен — предсказание r3 («UI не менялся,
PNG, вероятно, останутся байт-в-байт те же») подтвердилось буквально.
- `src/**`, `test/**`, `demo/**`, `scripts/**`, `custom_components/**`,
`dist/**` — не тронуты вовсе. Никакого продуктового или тестового кода в
дельте нет.
- `docs/reviews/CODE-REVIEW-330-r3.md` — публикация документа предыдущего
раунда (класс C, инфраструктурный шаг, не предмет код-ревью).
## 2. Закрытие раунда r3
| Находка r3 | Чем закрыта | Где это видно |
|---|---|---|
| H1 (в скоупе) — `node scripts/check-docs.mjs` завершался `exit 1`: записанный `sourceFingerprint` (`2a5ae6c1…`) разошёлся с реальным `visualFingerprint()` дерева (`dbac4a84…`) после того, как `04bb54ae` поменял `src/houseplan-card.ts` без пересчёта скриншот-манифеста | Манифест пересчитан прогоном `npm run build && node demo/docs/capture.mjs` и принят: новый `sourceFingerprint`/все `sourceSha256` равны `dbac4a84…` — ровно значению, которое r3 назвал ожидаемым. `imageSha256` не изменился ни в одной сцене, то есть пересчитан именно отпечаток источника, а не подменены сами PNG | `docs/images/screenshots.json` (диф выше); я прогнал `node scripts/check-docs.mjs` на текущем HEAD лично (не со слов автора) |
Находка закрыта по существу и подтверждена исполнением, не только чтением
коммита.
## 3. Как проверялось (дельта, r4)
Validate на этом SHA (`d33aa0a7`) уже зелёный (см. вводную задачи, ссылка на
прогон), поэтому `tsc`/`npm test`/`npm run build` + сверка бандла не
перегоняю — они не относятся к предмету этой дельты (дельта не трогает
`src/**`/`test/**`) и уже подтверждены на этом самом SHA.
Единственный релевантный дельте гейт — сам докс-гейт, ради которого сделан
коммит:
| Гейт | Команда | Результат |
|---|---|---|
| Докс-гейт | `node scripts/check-docs.mjs` | `Documentation checks passed (7 files, 10 external links).`, exit 0 |
| Ручная сверка значения фингерпринта | `git diff 04bb54ae..HEAD -- docs/images/screenshots.json` | все 11 вхождений `sourceFingerprint`/`sourceSha256` заменены на один и тот же новый хеш; все 10 `imageSha256` не изменились |
| Trailers коммитов дельты | `git show 90a3313d -s --format=%B`, `git show d33aa0a7 -s --format=%B` | оба несут `Issue: #330`, `User-Visible: no` — корректно: `90a3313d` публикует документ ревью (класс C, не продукт), `d33aa0a7` пересчитывает служебный отпечаток без изменения видимого результата (PNG идентичны) |
| Рёбейз/уход dev | `git merge-base --is-ancestor 04bb54ae HEAD`, `git fetch origin dev && git merge-base --is-ancestor origin/dev HEAD` | оба — да; условие полного разбора (§2.10, ребейз на ушедший вперёд dev) не выполнено |
Дельта не трогает геометрию, рендер, стили, слои, публичный контракт,
`custom_components/**` и ни один файл, упомянутый в §5 текста ревью
(инварианты модели, смоки, golden, perf-профили, бэкенд-тесты) — поэтому эти
гейты не перегоняю, наследую решениеr3 не гонять их (см. §5 ниже).
## 4. Находки
Находок нет. Единственная находка предыдущего раунда (r3-H1) закрыта точным,
минимальным коммитом, который меняет ровно то, что было названо дефектным
(отпечаток источника), и ничего больше.
## 5. Унаследовано из r3 (без повторной проверки)
Дельта r4 не касается ни одной строки продукта, теста или конфигурации —
наследую весь корпус r3 целиком, включая то, что сам r3 унаследовал из r2:
- **Архитектура срезов §4.1–§4.7** (executor-цепочка, rev-кэш `previous`,
byNode-индекс П3, bucket-решётка П4, §4.6 «v9 как есть», общий проход §4.7)
— признана верной в code-review r2 (`docs/reviews/CODE-REVIEW-330-r2.md`,
HEAD `85636a65`) и подтверждена неизменной в r3
(`docs/reviews/CODE-REVIEW-330-r3.md`, HEAD `04bb54ae`, §5). Ни r3, ни r4 её
не трогают.
- **AC1 (event loop/executor)** — `pytest -k 330` → `1 passed`, исполнено в
r2, не затронуто с тех пор (`custom_components/**` не в дельте ни r3, ни
r4).
- **AC2/AC3/AC5 (линейный П3/П4, rev-кэш бэкенда, эквивалентность §4.6)** —
паритет-тесты TS↔Python, `pytest tests_backend -q` (423 passed), исполнены
в r2, не затронуты в r3/r4.
- **AC4 (баланс кэша фронта)** — закрыто по существу в r3 (см. таблицу закрытия
r2→r3 в `docs/reviews/CODE-REVIEW-330-r3.md` §2): ключ кэша заменён на
identity документа + `spacePhysicalGeometryFingerprint`, мутант
`junction-limit-baseline-cache-stale` ловится смоком, `mutation-gate.mjs
--id=junction-limit-baseline-cache-stale` зелёный. Дельта r4 не трогает
`src/houseplan-card.ts`, `demo/smoke_junction_limits.mjs`,
`test/junction-limits.test.mjs`, `scripts/mutation-gate.mjs` — код кэша
байт-в-байт тот же, что был подтверждён исполнением в r3.
- **AC7/перф-контракт §5, включение в `validate.yml`** — подтверждено
исполнением в r2 и r3 (`benchmark:junction-limits` → `pass: true`, запас
≥2.6×). Не в дельте r4.
- **golden:verify** — не гонял, как и в r2/r3: ни один раунд с r1 не касался
рендера/геометрии/стилей/слоёв, r4 тем более (дельта — только
`screenshots.json`, а он не входит в golden-контур).
- **Полная матрица `demo/smoke_*.mjs` и полный `mutation-gate.mjs`** — не
гонял целиком: предрелизные гейты (PROCESS.md §8), не гейт ревью. По дельте
r4 гонять нечего — она не содержит кода, который могла бы затронуть
какая-либо смок-проверка.
- **`pytest tests_backend`** — не гонял; дельта r4 не содержит ни одного
файла `.py`.
- **`npm run invariants -- --config <...>`** — не гонял; дельта не вводит и
не меняет геометрию, `layout`, `marker.space`, `open_spans` или записи
толщины ни в r3, ни в r4.
- **Одно число — один источник** — неприменимо: дельта r4 не вводит и не
меняет ни одной пользователю видимой величины. Более того, она подтверждает
обратное намеренно: `imageSha256` (то, что реально видит пользователь на
скриншотах) не изменился ни на бит — изменился только служебный
`sourceFingerprint`/`sourceSha256`, внутренний отпечаток дерева исходников
для докс-гейта, невидимый конечному пользователю карточки.
- **CHANGELOG** — не требуется ни для `90a3313d` (публикация документа
ревью, класс C, не входит в DoD задачи по видимому поведению), ни для
`d33aa0a7` (`User-Visible: no`, подтверждено фактом: PNG идентичны,
меняется только служебный манифест).
## 6. Что проверено и корректно (эта дельта)
- Значение нового `sourceFingerprint` в `docs/images/screenshots.json`
совпадает с тем, которое r3 независимо вычислил как «реальное»
(`dbac4a84…`) на том же дереве до этого коммита — не просто «файл
изменился», а изменился на правильное значение.
- Ни один `imageSha256` не менялся — фикс не подменяет и не портит сами
скриншоты, трогает только служебное поле идентификации источника.
- `node scripts/check-docs.mjs` зелёный на текущем HEAD, прогнан лично.
- Trailers обоих коммитов дельты корректны для их класса изменений.
- Дельта не расширяет и не сужает скоуп задачи: единственная цель коммита —
закрыть ровно ту находку, которая была названа, ничего лишнего не задето.
## 7. Чего не проверял и почему
- `npx tsc --noEmit`, `npm test`, `npm run build` + сверка бандла — Validate
зелёный на этом самом SHA (`d33aa0a7`, ссылка в вводной задачи), а дельта
не трогает ни `src/**`, ни `test/**` — перегонять нечего нового.
- `pytest tests_backend`, `golden:verify`, инварианты модели, смоки помимо
докс-гейта, perf-бенчи — дельта r4 не содержит ни одного файла, который
могли бы затронуть эти гейты (только `docs/images/screenshots.json` и
публикация документа ревью); все они наследуются из r2/r3 без повторного
прогона (см. §5).
- Ручное тестирование в браузере — вне цикла ревью по регламенту; предмет
этого раунда — сугубо служебный докс-манифест, для него замена (докс-гейт)
прогнана.
## 8. Итог
High: 0. Medium: 0. Единственная находка r3 (H1) закрыта точным,
минимальным, верифицированным коммитом — значение фингерпринта совпало с
независимо вычисленным ожиданием, PNG не изменились, докс-гейт зелёный на
исполнении, не со слов автора. Весь остальной корпус задачи (§4.1–§4.7,
AC1–AC7, AC4-фикс r2→r3) наследуется без повторной проверки — дельта r4 его
не касается ни одной строкой. Зелёный вердикт, бюджет циклов не тратится.