mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Failing after 26m52s
Проверка (CI) / Классификация изменённых файлов (push) Failing after 38s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Skipped
Проверка (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) / Смоки в браузере (шард 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) / Геометрия: TS/Python parity исполнена (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Skipped
Проверка (CI) / Доказательство выполненных проверок (push) Failing after 19s
Issue: #627 User-Visible: no
129 lines
22 KiB
Markdown
129 lines
22 KiB
Markdown
# CODE-REVIEW-627-r3
|
||
|
||
Материал: `b921ba71847df37416bed1c15e3d645953ffa1c9` (рабочая копия уже на нём; `git fetch`/`checkout` не выполнялись). Дерево `c76d64409884dfb646eb723f3e868003e923cce9`. Заход r3, блокирующих циклов израсходовано 1 из 4 (полный трек, лимит 4).
|
||
|
||
r2 (`docs/reviews/CODE-REVIEW-627-r2.md`, материал `47d07281b6ce…`, дерево `e19b817f43f3…`) был зелёным и цикла не образовал (#227). r3 существует не потому, что r2 что-то вернул автору, а потому, что автор запушил новый коммит: `b921ba71` — ребейз ветки на ушедший вперёд `origin/dev` (успевший вобрать #642, «диалог «Оптимизировать планы» — свой модуль») с пересборкой бандла и пересчётом потолков. `47d07281` в текущей истории не резолвится (ребейз его осиротил) — по [§2.10] это не находка, а обычное дело; материал ищется по дереву. Дерево, эквивалентное содержимому `47d07281`, живо в текущей истории как `70fe860bac6259fc1f32114a6b3fe191fe8d966a` (коммит «test(smoke): danger confirmation waits for the composite language gate (#627 r1 M1)», тот же M1-фикс, что и в r2), поэтому дельта раунда объявлена как `git diff 70fe860b..b921ba71`.
|
||
|
||
## Скоуп
|
||
|
||
ТЗ #627 (полный трек, из аудита T9 M2-A): не новая функциональность, а бюджетно-техническая работа над уже закрытыми job'ами J4/J6 (`docs/SCOPE.md`) — держит `bundle-budget.mjs` честным гейтом ленивых графов онбординга/редактора, без новой видимой поверхности. `User-Visible: no` на всех трёх коммитах — корректно, ниже подтверждено.
|
||
|
||
**Объявление дельты** (`git diff 70fe860b..b921ba71 --stat`): 74 файла — `scripts/bundle-budget.mjs` (17 строк: константа потолка + комментарий-причина), `scripts/monolith-baseline.json` (одно число), и 72 файла механической пересборки (`dist/**`, `custom_components/houseplan/frontend/**`, три копии бандла синхронны). `src/**/*.ts`, `test/**`, `demo/**` дельтой не тронуты — подтверждено и `git diff --stat`, и `node scripts/smoke-select.mjs --base 70fe860b --head b921ba71`:
|
||
|
||
```
|
||
Исполняемого frontend-диффа нет (src/**/*.ts не тронут).
|
||
Browser-smoke этим диффом не выбираются — это не «пропустить проверки»,
|
||
а «выбирать нечего»: смоки проверяют собранную карточку.
|
||
Тронуто файлов: 76.
|
||
```
|
||
|
||
Дельта локальна по содержимому (две строки логики — числовая константа и её обоснование), хотя коммит и называется «ребейз». Тем не менее я разобрал её не по минимуму, а вместе с двумя пробелами доказательств, унаследованными от r1/r2 (см. «Как проверялось»): впервые в истории задачи собранный бандл — совместный продукт #627 и #642 (до этого коммита #642 жил только в `origin/dev`, `82a48ee0` был выпущен поверх него, но ни разу не гонялся в браузере после реального слияния кода обеих задач в одно дерево), и два смока, тронутых ещё исходным коммитом `82a48ee0` и прямо относящихся к контракту задачи, ни разу не запускались ни в r1, ни в r2. Формально это не входит в дельту r3, но раз я всё равно поднимал браузер для проверки собранного дерева — закрыл оба пробела тем же прогоном; см. ниже.
|
||
|
||
## Как проверялось
|
||
|
||
Дешёвые гейты подтверждены зелёным Validate на этом самом SHA (run [36025312110](https://github.com/Matysh/houseplan-card/actions/runs/36025312110), `conclusion: success`, `headSha` = `b921ba71847df37416bed1c15e3d645953ffa1c9` — проверено напрямую через `gh run view --json`). Разбивка по джобам:
|
||
|
||
| Джоб | Результат |
|
||
|---|---|
|
||
| Классификация изменённых файлов | success |
|
||
| Предполёт: документация, провенанс, процесс | success |
|
||
| Переиспользование: это дерево уже проверено | success |
|
||
| Мутанты по диффу (6/6 шардов) | success |
|
||
| **Фронтенд: типы, юниты, мутанты, синхрон бандла** | **success** |
|
||
| Hassfest / HACS / pytest / geometry parity / browser smokes (3 шарда) / perf-smoke / golden | **skipped** (`workflow_dispatch`, не `heavy`) |
|
||
| Доказательство выполненных проверок | success |
|
||
|
||
Джоб «Фронтенд» содержит `npm test` → `npm run build` → `bundle-tree.mjs` + `npm run bundle:budget` → `npm run lint:unused` (в этом порядке, `.github/workflows/validate.yml:779-791`) — то есть typecheck, юниты, сборка, гейт потолка `LAZY_EDITOR_GZIP_CEILING` и гейт связности монолита (`bundleBytes` против `scripts/monolith-baseline.json`) уже подтверждены на этом точном SHA. Их я не перегонял.
|
||
|
||
Прогнано лично на `b921ba71` (дёшево, для точных чисел в этом документе и потому что новых чисел для CI-подтверждения годится не «похоже», а «совпало»):
|
||
|
||
| Гейт | Команда | Результат |
|
||
|---|---|---|
|
||
| Bundle sync (проверка свежести/синхрона копий) | `node scripts/bundle-sync.mjs` | `git status --short` пуст и до, и после — закоммиченный `dist/` уже байт-в-байт синхронен с `custom_components/**` и распакован в `demo/srv/assets` |
|
||
| Bundle budget | `npm run bundle:budget` | `lazy editor: 228621 B gzip (потолок 229600 B ±2000)`, `lazy onboarding: 27468 B gzip (потолок 28500 B ±2000)`, `initial View: 289418 B gzip (потолок 290400 ±2000)` — совпадает с числами коммита `b921ba71` дословно |
|
||
| Мёртвый код и связность монолита | `npm run lint:unused` | `monolith: delegates=154 portMembers=348 hostRefs=4869 portPrivates=94 harnessPrivates=101 bundleBytes=2508211` / `ok все числа равны базе` |
|
||
|
||
Арифметика коммита проверена построчно:
|
||
- `LAZY_EDITOR_GZIP_CEILING`: 229600, полоса 2000 → нижняя граница 227600; при замере 228621 запас сверху 229600−228621=**979**, запас снизу 228621−227600=**1021** — совпадает с текстом комментария в `scripts/bundle-budget.mjs:572` дословно.
|
||
- `monolith-baseline.json` `bundleBytes`: база `origin/dev` (`0f234f76`, тот же коммит, что и merge-base ветки с `origin/dev`) — `2499182` (проверено `git show 0f234f76:scripts/monolith-baseline.json`), текущее — `2508211`, разница `+9029` — совпадает с текстом коммита («десять новых чанков словарей и записи манифеста»); остальные пять чисел монолита (`delegates`/`portMembers`/`hostRefs`/`portPrivates`/`harnessPrivates`) не изменились ни на йоту относительно базы `dev` — тоже заявлено в коммите и подтверждено прогоном.
|
||
- Комментарий к `LAZY_EDITOR_GZIP_CEILING` над константой (строки 559–567 до правки) на промежуточном коммите `82a48ee0` содержит незаполненные плейсхолдеры `XXX` («замер XXX», «Центр оставляет XXX Б сверху и XXX Б до нижней границы») — артефакт промежуточного состояния ветки после первого ребейза на `origin/dev` с #642, где числа ещё не были пересчитаны. Это не находка: `82a48ee0` не является вершиной ни одного опубликованного ревью (ни r1, ни r2 его не рецензировали как отдельный SHA — их материал уже был позже осиротевшим `40959feb`/`47d07281`), а в материале **этого** раунда, `b921ba71`, плейсхолдеры заменены настоящими числами, что я и проверил выше побайтово. Упоминаю, чтобы явно снять вопрос, а не оставить его как тихо замеченную странность.
|
||
|
||
Смоки. `smoke-select` для дельты `70fe860b..b921ba71` не выбирает ничего (см. выше) — формально этого достаточно. Тем не менее я поднял браузер (нужно было для проверки живой пересборки бандла) и заодно закрыл два пробела в доказательствах, оставленные r1/r2:
|
||
|
||
| Смок | Почему запущен | Результат |
|
||
|---|---|---|
|
||
| `smoke_lazy_admin_locale.mjs` | Ядро AC4–AC7; первый прогон на дереве, где бандл собран **совместно** с #642 | OK, все 38 полей `true` |
|
||
| `smoke_danger_confirmation.mjs` | M1 (r1) / его фикс (r2) — держится ли регрессия закрытой на пересобранном бандле | OK, все 25 полей `true`, включая `{de,fr}GateSettledBeforeAsking` |
|
||
| `smoke_optimize_geometry_preflight.mjs` | Тронут `82a48ee0` (добавлено ожидание языкового гейта перед `card._editorRuntime.optimizePlans.open()` — новый порт из #642); **ни r1, ни r2 не упоминают этот файл ни разу** (`grep -n optimize` по обоим документам — пусто), хотя правка именно этого файла явно перечислена в теле коммита `b921ba71` («smoke_optimize_geometry_preflight: …, разрешено в коммите задачи») без единой ссылки на прогон | OK, все 16 полей `true` — пробел закрыт |
|
||
| `smoke_dialog_segments_i18n.mjs` | Единственный смок, явно названный в **ТЗ issue** («План автотестов»: «...`smoke_dialog_segments_i18n` (4 локали × 4 диалога; переключение языка должно ждать гейт)») для риска ровно той же природы, что и M1; тронут `82a48ee0`, но ни r1, ни r2 его не упоминают | OK, все 60 полей `true` — пробел закрыт |
|
||
| `smoke_color_picker.mjs`, `smoke_free_walls.mjs`, `smoke_space_scale_defaults.mjs`, `smoke_summary_panel.mjs`, `smoke_toggle_confirmation.mjs`, `smoke_ux_fixes.mjs` | Ещё 6 смоков получили тот же защитный «дождаться `aria-busy`» патч в `82a48ee0` (за пределами явного списка ТЗ — самостоятельный аудит автора), ни один не упомянут ни в r1, ни в r2 | Все 6 — OK, без единого `false`-поля |
|
||
|
||
Итого 9 браузерных смоков лично прогнаны на `b921ba71`, все зелёные без единого красного поля — включая четыре, которые пять раундов до этого (r1: три коммита, r2, теперь r3-до-этого-прогона) молча пропускали.
|
||
|
||
### Чего не проверял
|
||
|
||
- Индивидуальные прогоны 5 мутантов #627 по `--id` (`onboarding-loader-skips-namespace-ensure` и др.) — на этом SHA не перегонял; `src/**` в дельте `70fe860b..b921ba71` не тронут, а мутанты гейтят именно `src/**`. Опираюсь на личный прогон r1 (на уже осиротевшем SHA, но тем же дереве `src/**`) плюс на «Мутанты по диффу (6/6 шардов) — success» в CI на `b921ba71` — это диффовый прогон относительно доказанного предка, не индивидуальный запуск по `--id`, но за отсутствием изменений `src/**` он лишь переподтверждает то же дерево, а не проверяет что-то новое.
|
||
- `golden:verify`, перф-смок, `pytest tests_backend`, Hassfest/HACS, `geometry parity` — все skipped в CI (не `heavy`, `workflow_dispatch`) и не гейт этой дельты: ни эталонов рендера, ни Python, ни геометрии дифф не касается.
|
||
- Полный `smoke-select --base origin/dev --head HEAD` (а не `--base 70fe860b`) — не гонял: он воспроизвёл бы ровно то же самое (дельта `origin/dev..HEAD` содержит src-правки #627, уже разобранные в r1), а не что-то специфичное для этого раунда.
|
||
- Остальные ~250 несвязанных смоков вне плана ТЗ и списков связей — не прогонял, это предрелизная обязанность, не гейт ревью.
|
||
- Живой стенд Home Assistant — не поднимал.
|
||
|
||
## Находки
|
||
|
||
Нет. High 0, Medium 0.
|
||
|
||
Low-наблюдение, снятое без действия: патч «подождать `aria-busy` до 250×20мс» теперь инлайново продублирован в 12 файлах `demo/smoke_*.mjs` (проверено `grep -rl "hasAttribute('aria-busy')"`), при том что `demo/serve.mjs` уже экспортирует несколько общих утилит смоков (`watchPage`, `check`, `checkAll`, `reportPageErrors`, `finish`) — общий хелпер сюда напрашивается. Не поднимаю до Medium: сам приём (а не его вынесение в хелпер) был явно одобрен r1 как решение M1 («чинится тем же приёмом, что уже применён к девяти другим смокам»), дублирование не в дельте r3 (весь список — из `82a48ee0`, уже принятого в r1/r2), и это стиль тестового харнесса, а не продуктовый код.
|
||
|
||
## Что проверено и корректно
|
||
|
||
| AC | Проверено в r3 | Итог |
|
||
|---|---|---|
|
||
| AC1 (`bundle-budget.mjs` печатает и гейтит онбординг) | Не тронут дельтой; CI (`Фронтенд` job) переподтвердил `npm run lint:unused`/`bundle:budget` на этом SHA | Унаследовано + переподтверждено CI |
|
||
| AC2 (числовые потолки и запасы) | **Переисполнено лично**: `npm run bundle:budget` на `b921ba71` — редактор 228621 ≤ 229600 (запас к полосе 979/1021 Б, >500), онбординг 27468 ≤ 28500 (запас 34526−27468=27058 ≥ 6500, 244433−228621=15812 ≥ 15000), initial View 289418 (было 289457 до задачи — фактически **снижение**, не рост; в полосе потолка) — причина перецентровки редакторского потолка (#642) записана в комментарии константы дословно с числами | Доказан заново на текущем SHA |
|
||
| AC3 (9 ленивых чанков, владение графами) | Не тронут дельтой (`test/i18n-lazy-namespaces.test.mjs`, `test/bundle-assets.test.mjs` не изменились с r1); CI `Unit tests` зелёные на `b921ba71` | Унаследовано из r1 |
|
||
| AC4 (холодное открытие on ru/de/fr, первый кадр на языке) | Лично: `smoke_lazy_admin_locale.mjs` — OK на пересобранном бандле | Переисполнено |
|
||
| AC5 (live-переключение языка, составной гейт) | Лично: тот же смок + `smoke_danger_confirmation.mjs` (M1) + `smoke_optimize_geometry_preflight.mjs` + `smoke_dialog_segments_i18n.mjs` + 6 доп. смоков с тем же патчем — все OK | Переисполнено, шире, чем требовала дельта |
|
||
| AC6 (отказ обеих попыток → английский только в пространстве) | Не тронут дельтой; `smoke_lazy_admin_locale.mjs` (поля `failure*`) — OK в прогоне выше | Унаследовано + переподтверждено прогоном |
|
||
| AC7 (холодный View/en-редактор/Zigbee не тянут лишних чанков) | Не тронут дельтой; те же поля смока — OK | Унаследовано |
|
||
| Трейлеры | `git show <sha> -s --format='%B'` на `82a48ee0`/`70fe860b`/`b921ba71` — везде `Issue: #627`, `User-Visible: no` | Корректно |
|
||
| Changelog | `git diff 70fe860b b921ba71 --stat -- docs/CHANGELOG.md docs/CHANGELOG.ru.md` — пусто; верно при `User-Visible: no` и отсутствии видимых изменений | Корректно |
|
||
| Одно число — один источник | `grep -rn "229_600\|229600\|2508211" scripts test src` — по одному вхождению каждое, только в объявлении константы/базы | Корректно |
|
||
|
||
## Закрытие раунда r2
|
||
|
||
r2 был зелёным, «Находки: Нет» — закрывать нечего. Таблица приведена для формы, соответствия сокращённому шаблону:
|
||
|
||
| Находка r2 | Чем закрыта | Где видно |
|
||
|---|---|---|
|
||
| — | — | — |
|
||
|
||
## Унаследовано из r2
|
||
|
||
Без повторной проверки в r3 принято из `docs/reviews/CODE-REVIEW-627-r2.md` (материал `47d07281b6ce…` / дерево `e19b817f43f3…`, вердикт зелёный · заход r2 · High 0 · Medium 0), поскольку `src/**`, `test/**`, `demo/**` в дельте `70fe860b..b921ba71` не тронуты:
|
||
|
||
- AC3, AC6, AC7 — доказаны в r1, не пересчитывались повторно ни в r2, ни здесь.
|
||
- Полный реестр из 7 мутантов #627 (5 новых + 2 с обновлёнными якорями), лично прогнанных r1-ревьюером по `--id`, «поймано 1 из 1» каждый.
|
||
- `check-docs.mjs --screenshots=warn`, `check-inputs.mjs --coverage` (0), `CONTRIBUTING.md`/`tsconfig.test.json` — содержательно не менялись.
|
||
|
||
Не унаследовано, а переисполнено заново лично в r3 (см. «Как проверялось»): M1-фикс (`smoke_danger_confirmation.mjs`) и AC4/AC5 — потому что артефакт (собранный бандл) впервые стал совместным продуктом #627+#642, и это первый раз, когда кто-либо гонял браузерные смоки против именно такого дерева.
|
||
|
||
## Вердикт
|
||
|
||
Зелёный. Дельта раунда (`scripts/bundle-budget.mjs`, `scripts/monolith-baseline.json` + механическая пересборка) арифметически честна и подтверждена и CI, и лично. Ни одной находки. Дополнительно: два смока, явно относящихся к контракту задачи (один — по прямому тексту ТЗ, другой — по собственному упоминанию в теле коммита без прогона) и шесть смоков с тем же защитным патчем, ни разу не запускавшихся в r1/r2, лично прогнаны на этом SHA и зелёные — пробел в доказательствах предыдущих раундов закрыт, а не унаследован молча.
|
||
|
||
---
|
||
|
||
---
|
||
|
||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `issue/627-lazy-admin-locales`, коммит `b921ba71847d` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||
- Дерево материала: `c76d64409884dfb646eb723f3e868003e923cce9`
|
||
```
|
||
git log --all --format='%H %T' | grep c76d64409884
|
||
```
|
||
- Тело issue: `11ffae080ad26691a4b8dbd32f7736895c0c25a3f0cabe1b09da0e21666e6562`
|
||
- Вердикт конвейера: `green` · High 0
|