mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,128 @@
|
||||
# CODE-REVIEW-602-r2
|
||||
|
||||
Issue: #602 · Этап: code · Заход: r2 · блокирующих циклов израсходовано 1 из 4
|
||||
Материал: `e1fa2591a4cc7cb5a86ee43183353eb3b9783984` (issue/602-dialog-polish), рабочая копия ревью — на этом SHA, `git status` чист на всём протяжении разбора.
|
||||
|
||||
## Скоуп раунда
|
||||
|
||||
Предыдущий заход (r1, материал `c69d73f1`, документ `docs/reviews/CODE-REVIEW-602-r1.md`)
|
||||
дал единственную находку — Medium в скоупе: `npm run golden:verify` был красным (8 из 173
|
||||
сцен `different`), а AC15/план тестирования ТЗ требуют его зелёным. Всё остальное (AC1–AC14,
|
||||
AC16, трейлеры, i18n, отдельно проверенный риск с авто-раскрытием radar-формы) r1 закрыл без
|
||||
замечаний.
|
||||
|
||||
Дельта этого раунда — **строго** `git diff c69d73f1..e1fa2591`:
|
||||
|
||||
- `demo/golden/baselines/baselines-index.json` — обновлены хэши и метаданные приёмки;
|
||||
- 8 PNG-файлов эталонов (ровно те 8 сцен, что r1 назвал `different`);
|
||||
- `docs/reviews/CODE-REVIEW-602-r1.md` — публикация документа r1 (добавлен конвейером,
|
||||
не автором; не несёт функциональных изменений).
|
||||
|
||||
`src/**`, `test/**`, `demo/smoke_*`, локали, `docs/USER-GUIDE*`, `docs/CHANGELOG*` в дельте
|
||||
не тронуты. Это ровно то действие, которое r1 назвал единственным недостающим шагом (принятие
|
||||
эталонов на канонической Linux-сборке с трейлерами `Release:`/`Baseline-Reviewed:`) — не
|
||||
рефакторинг, не смена контракта, не задета новая подсистема. По PROCESS.md §2.9 разбор
|
||||
сужен до дельты; полный повторный прогон всех AC1–AC16 не требуется, так как ни один из них
|
||||
не зависит от кода, тронутого дельтой.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
| Гейт | Статус | Как проверено |
|
||||
|---|---|---|
|
||||
| `typecheck`/`npm test`/`npm run build` + сверка 3 копий бандла | зелёный, не перегонял | Validate на точном материале `e1fa2591` — [прогон 35539075873](https://github.com/Matysh/houseplan-card/actions/runs/35539075873), `conclusion: success`, `headSha` совпадает (проверено `gh run list --commit e1fa2591…`). Дельта раунда не трогает `src/**`, пересчитывать нечего. |
|
||||
| `node scripts/check-docs.mjs --strict` | не перегонял, не применимо | Дельта не трогает `src/**`/`docs/images/**`; отпечаток документации не мог измениться этим коммитом (уже был зелёным на `c69d73f1`, см. r1). |
|
||||
| `npm run golden:verify` (закрытие Medium r1) | **зелёный**, проверено на канонических CI-прогонах, не перегонял локально | Два независимых прогона на точных SHA дают причинно-следственную пару: (1) [прогон 35538133817](https://github.com/Matysh/houseplan-card/actions/runs/35538133817) на материале `8ca877c9` (код идентичен `c69d73f1`, только + документ r1) — `conclusion: failure`, это тот самый диагностический Linux-снимок, из которого взяты 8 кадров; (2) [прогон 35539075873](https://github.com/Matysh/houseplan-card/actions/runs/35539075873) на материале ревью `e1fa2591` — job «Golden-кадры против принятых эталонов» `conclusion: success` (не skip — проверено `gh api .../check-runs`, это полный, а не dedup-прогон). Разница между (1) и (2) — ровно принятие 8 эталонов, ничего больше. |
|
||||
| Целостность принятых эталонов | зелёный, проверил сам | Пересчитал SHA-256 всех 8 принятых PNG в рабочей копии и сверил с записями `baselines-index.json` — совпадают побайтово для всех 8 (`device-dialog-desktop-en/de`, `device-dialog-mobile-ru`, `device-help-popover-light-ru`, `settings-help-zoom-200-en-light/ru-dark`, `device-ripple-color-popover-mobile-ru`, `space-room-color-popover-desktop-ru`). Ни один файл вне этого списка не изменился (`git diff c69d73f1..e1fa2591 --stat` — 10 файлов, из них 8 названы явно). |
|
||||
| Провенанс и allowlist приёмки | зелёный, проверил чтением `demo/golden/accept.mjs` | Скрипт (не тронут этой дельтой, инфраструктура доверенная и ранее не была предметом замечаний) отказывается писать эталоны без `--reviewed`, проверяет `buildFingerprint === sourceFingerprint(ROOT)` (гарантия, что кадры сняты именно с этого исходника), считает «свидетелей» — необъявленные сцены, совпавшие байт-в-байт (#355) — и отказывает при их нехватке (`floor`). В принятом индексе `witnesses.count: 104` при `floor: 10` — с большим запасом, то есть посторонний дрейф вне 8 объявленных сцен инструментом исключён. `foreignCapture.reason` в индексе прямым текстом фиксирует «съёмка на Linux CI, приёмка на Windows автора после визуальной проверки» — это осознанный, задокументированный путь, а не сокрытие. |
|
||||
| Трейлеры коммита `e1fa2591` | зелёный, проверил сам | `git show -s --format=%B`: `Issue: #602`, `User-Visible: no`, `Release: v1.77.0-beta.3` (совпадает с `package.json` `version`), `Baseline-Reviewed: …/runs/35538133817` — ровно то, что требует `scripts/validate-commit-provenance.mjs:64-77` для коммитов, трогающих `demo/golden/baselines/*.{png,json}`, и ровно то, что r1 указал как «что нужно». |
|
||||
| Мутанты по диффу (6/6 шардов) | зелёный, не перегонял | Тот же прогон 35539075873 — все 6 шардов `success`; дельта раунда не содержит логики, которую могли бы поймать мутанты (только бинарные эталоны и JSON-метаданные). |
|
||||
| Смоки (`demo/smoke_*.mjs`) | не гонял, не применимо | Дельта не трогает ни один smoke-файл и ни один файл, который smoke-и импортируют (`src/**`, `dist/**`) — `scripts/smoke-select.mjs` не даёт новых кандидатов относительно уже проверенного в r1 диапазона. Полный набор смоков r1 уже прогнал сам на функциональном коде (746147d0/c69d73f1), эта дельта его не меняет — наследуется. |
|
||||
| `npm run invariants`, `python -m pytest tests_backend`, performance-профили | не гонял | Дельта не трогает геометрию/`custom_components/**/*.py`/перф-пути — то же основание, что и в r1, не изменилось. |
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. Единственная находка r1 закрыта именно тем действием, которое r1 предписал; новых
|
||||
находок дельта не создаёт (дельта не содержит логики — только данные эталонов, их индекс и
|
||||
публикацию документа предыдущего раунда).
|
||||
|
||||
## Закрытие раунда r1
|
||||
|
||||
| Находка r1 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| Medium: `npm run golden:verify` красный на материале ревью (8/173 `different`: `device-dialog-desktop-en/de`, `device-dialog-mobile-ru`, `device-help-popover-light-ru`, `settings-help-zoom-200-en-light/ru-dark`, `device-ripple-color-popover-mobile-ru`, `space-room-color-popover-desktop-ru`), обещанный тестовый артефакт (принятые baseline-кадры) отсутствовал | Коммит `e1fa2591`: принятие ровно этих 8 эталонов через `accept.mjs --reviewed` на артефакте канонического Linux-прогона 35538133817, с трейлерами `Release:`/`Baseline-Reviewed:`, как и требовало r1 дословно («Что нужно») | `git diff c69d73f1..e1fa2591 -- demo/golden/baselines` — те же 8 id, ни одного лишнего; `gh api .../35539075873/check-runs` → job golden `success` (не skip); хэши PNG совпадают с индексом (см. таблицу выше) |
|
||||
|
||||
Побочное наблюдение без действия: документ r1 в прозе назвал общее число сцен «150»
|
||||
(«8 из 150 сцен different»), тогда как в самом индексе на материале r1 (`c69d73f1`) их уже
|
||||
было 173, и это же число совпадает с явным `GOLDEN_SCENARIOS.length` и с «165 сохранены без
|
||||
изменений» из комментария автора (165+8=173). Похоже на опечатку в тексте документа r1, а не
|
||||
на ошибку разбора — состав 8 названных сцен и итоговое решение («нужен `golden:accept`») от
|
||||
этого не меняются, поэтому не поднимаю как находку.
|
||||
|
||||
## Унаследовано из r1
|
||||
|
||||
Без повторной проверки в этом раунде — дельта их не задевает, основание см. в
|
||||
`docs/reviews/CODE-REVIEW-602-r1.md` на SHA `c69d73f1f26b3277fde938a4eb08195c561e46ba`:
|
||||
|
||||
- AC1/AC8 — лишние подписи/заголовок убраны, синхронно по 4 локалям;
|
||||
- AC2 — центрирование тумблера (`top: 50%`/`translateY(-50%)`), защитный AC подтверждён
|
||||
мутацией руками;
|
||||
- AC3/AC5 — числовые поля не обрезаются/не перекрывают слайдер (grid-раскладка `.hpf-range`);
|
||||
- AC4 — подписи шкалы совпадают с концами трека (`84px` единый резерв);
|
||||
- AC6/AC7/AC14 — однострочные футеры, mobile icon-only, confirm в одну строку на
|
||||
320/360/560;
|
||||
- AC9 — climate-toggle перенесён после «Additional actions»;
|
||||
- AC10 — нейтральный `dialog.unsaved` убран из всех 4 диалогов и локалей;
|
||||
- AC11–AC13 — единая toggle-секция радара, восстановление черновика Off→On, защитный AC
|
||||
подтверждён мутацией руками; `savedUnsupported`/`virtual`-ветки структурно не тронуты;
|
||||
- AC16 — оба changelog и `docs/USER-GUIDE*` правлены в коммите `746147d0` с `User-Visible: yes`;
|
||||
- трейлеры `746147d0`/`c69d73f1` — корректны;
|
||||
- отдельно проверенный и закрытый риск: авто-раскрытие radar-формы для распознанного, но
|
||||
ещё не сохранённого устройства — унаследованное (не из диффа #602) и задокументированное
|
||||
в `docs/USER-GUIDE.md` поведение, не регрессия;
|
||||
- соответствие `docs/SCOPE.md` (J4/J6) и `docs/TOUCH-SUPPORT.md` — оценено в ревью ТЗ (зелёный
|
||||
вердикт spec r2) и не пересматривается на этапе кода без изменения контракта.
|
||||
|
||||
Ни один из этих пунктов дельта `c69d73f1..e1fa2591` не задевает (она не содержит `src/**`).
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- **`npm test`/`npm run typecheck`/`npm run build` — не перегонял.** Дешёвые гейты зелёные на
|
||||
точном SHA `e1fa2591` (Validate 35539075873), дельта раунда их не меняет.
|
||||
- **`node scripts/check-docs.mjs --strict`** — не перегонял, дельта не трогает `src/**`/
|
||||
`docs/images/**`.
|
||||
- **Полная матрица `demo/smoke_*.mjs`** — не гонял; дельта не содержит кода, который смоки
|
||||
исполняют, `smoke-select` не даёт новых кандидатов сверх уже проверенных в r1.
|
||||
- **`npm run invariants`, `python -m pytest tests_backend`, performance-профили** — не гонял,
|
||||
как и в r1: дельта не касается геометрии, `custom_components/**/*.py` или перф-путей.
|
||||
- **Локальный повторный прогон `npm run golden:verify`** — не гонял руками (нет причины: два
|
||||
канонических Linux-прогона на нужных SHA уже дают прямую причинно-следственную пару
|
||||
«до фикса красный → после фикса зелёный», это сильнее локального дубля на этой же машине).
|
||||
- **Ручная проверка в браузере HA** — не проводилась (среды HA нет), как и в r1.
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- SHA: `e1fa2591a4cc7cb5a86ee43183353eb3b9783984` (`issue/602-dialog-polish`)
|
||||
- Дерево материала: идентично рабочей копии на момент вывода вердикта (`git status --short`
|
||||
пуст непосредственно перед выводом)
|
||||
- ТЗ: тело issue #602, зелёный вердикт спецификации r2
|
||||
- Предыдущий код-ревью: `docs/reviews/CODE-REVIEW-602-r1.md`, материал `c69d73f1`, вердикт
|
||||
жёлтый · High 0 · Medium 1
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. Единственная Medium-находка r1 закрыта именно предписанным действием, дельта раунда
|
||||
не содержит функционального кода и не создаёт новых находок.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/602-dialog-polish`, коммит `e1fa2591a4cc` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `eed53eb273f319a3cf3c49bf42d1625feca21672`
|
||||
```
|
||||
git log --all --format='%H %T' | grep eed53eb273f3
|
||||
```
|
||||
- Тело issue: `8f8081ec29db1c104189682530643bde421d91127170b2c635107c595950a5a9`
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user