From b1f1f6b7543861a2235f6c3cf9a4344e8d128730 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Wed, 23 Sep 2026 09:21:53 +0000 Subject: [PATCH] docs: review document for #639 Issue: #639 User-Visible: no --- docs/reviews/CODE-REVIEW-639-r2.md | 179 +++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 docs/reviews/CODE-REVIEW-639-r2.md diff --git a/docs/reviews/CODE-REVIEW-639-r2.md b/docs/reviews/CODE-REVIEW-639-r2.md new file mode 100644 index 00000000..3e94f3a9 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-639-r2.md @@ -0,0 +1,179 @@ +# CODE-REVIEW · issue #639 · заход r2 + +Материал: `a3397329d53487d0c8b78df02fadd161475c9cb9` (рабочая копия на нём). +Заход r2, блокирующих циклов ревью израсходовано 1 из 4 (жёлтый вердикт r1 +цикл не тратит — бюджет §4 списывается с жёлтых/красных, а r1 сам был +жёлтым; счётчик 1/4 в шапке задачи относится к другому событию конвейера, +не к этому ревью). + +Предыдущий раунд: r1, вердикт **жёлтый**, материал `0ac08434b5cd12848ce8b18aa17a6343b83b6653` +(SHA назван в служебном блоке «§2.10 материал раунда» под комментарием r1 — +сам вердикт его в тексте не повторяет). Документ: `docs/reviews/CODE-REVIEW-639-r1.md` +(закоммитирован в этой же ветке как `368ea35f`). + +## Дельта r2 + +`git diff origin/dev...HEAD --stat` относительно r1 показывает три файла в +ветке; из них к дельте раунда относится только один — `368ea35f` (сам +документ r1, публикуемый конвейером) и `9cf848c1` (`scripts/smoke-links.mjs`) +уже были материалом r1. Новый по отношению к r1 — единственный коммит: + +``` +a3397329 test(smoke): коммитить размер шрифта пространства через DOM (#639) + demo/smoke_space_settings_form.mjs | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) +``` + +Это ровно правка по единственной находке r1 (M1). Объекты старого материала +`0ac08434`/`71e8dc29` в текущем дереве недоступны (веб ветки после ребейза +переписал историю — автор описал это в возврате r2: «исходные исправления +room/device уже оказались в актуальном `dev`»), поэтому дельта сверялась не +`git diff ..HEAD`, а прямым `git show a3397329` — единственный коммит +после материала r1, содержимое совпадает с тем, что описывает возврат +автора. + +Диапазон дельты локален: один файл, тестовая инфраструктура, тот же смок, +что и в r1. Полный повторный разбор не требуется — расширяю его только до +границ, которые эта дельта задевает (сам смок и подтверждающий его код +`form-kit.ts`/`space-form.ts`), остальное наследую из r1. + +## Закрытие раунда r1 + +| находка | чем закрыта | где это видно | +|---|---|---| +| **M1** (Medium, в скоупе): запись `smoke-links.mjs` для `rangeLine`/`unitInput` заявляла, что `smoke_space_settings_form.mjs` «drives … space card font … through the DOM», хотя код присваивал `c._spaceDialog.cardFontScale` напрямую, минуя `#space-card-font` | `demo/smoke_space_settings_form.mjs:139-145` (коммит `a3397329`): вместо прямого присваивания драфта — `cardFontInput.value='150'` → `dispatchEvent('input')` → assert `fontDraftWaitsForChange` (черновик НЕ коммитится на `input`) → `dispatchEvent('change')` → assert `fontNumberCommitsThroughDom` (`cardFontScale===1.5`, Reset разблокирован) | Diff коммита `a3397329`; воспроизвёл падение, откатив ровно эти строки к варианту r1 (прямое присваивание) — `fontDraftWaitsForChange: expected true, got false`, `FAILED (1)`. Восстановил файл, дерево чистое | + +Текст записи `smoke-links.mjs:47-49` не менялся этим коммитом (и не должен +был) — теперь он просто перестал быть ложью: `smoke_space_settings_form.mjs` +действительно ведёт число через DOM ровно как заявлено. + +## Как проверялось (только то, что задевает дельта) + +1. Прочитал diff `a3397329` целиком (8 строк) — единственное изменение в + `demo/smoke_space_settings_form.mjs`. +2. Прочитал по коду путь коммита, который смок теперь проверяет: + `src/editors/space-form.ts:428-431` — `#space-card-font` собран через + `rangeLine({ min:50, max:300, step:5, slider: port.rangeInput(...), onInput: (n) => set(port, {...d, cardFontScale: n/100}) })`; + `src/editors/form-kit.ts:470-489` — `rangeLine()` монтирует числовое поле + с `onInput: () => undefined` (черновик не коммитится) и `onChange` → + `committedRangeLineValue` → коммит. `150/100 = 1.5` — совпадает с + ассертом `cardFontScale === 1.5`. Это тот же контракт, что ломался в + #608, и теперь смок идёт через него, а не мимо. +3. Собрал бандл (`npm run bundle:sync`) — Validate этот прогон уже + подтвердил на `a3397329`, но локальной копии `demo/srv/assets` не было, + а без неё браузерные смоки не запускаются; пересборка нужна была для + пункта 4, не для повторной проверки `tsc`/`build`. +4. `node demo/smoke_space_settings_form.mjs` на HEAD — `OK`, включая новые + ассерты `fontDraftWaitsForChange`/`fontNumberCommitsThroughDom`, + зарегистрированные в `checkAll(out)` (проверил `demo/serve.mjs:75-77` — + `checkAll` требует `true` от каждого ключа объекта `out`, значит новые + поля действительно участвуют в вердикте смока, а не просто вычисляются). +5. **Тест умеет падать**: временно вернул ровно правленые строки к + варианту r1 (`c._spaceDialog = { ...c._spaceDialog, cardFontScale: 1.5 }` + без DOM-событий) — смок упал: `fontDraftWaitsForChange: expected true, got false`, + `FAILED (1)`. Восстановил файл из бэкапа, `git status --short` пуст. +6. `node scripts/smoke-select.mjs --base origin/dev --head HEAD` — «браузерные + смоки этим диффом не выбираются», диф не трогает `src/**` (как и в r1; + инструмент подтверждает то же самое на новом материале). +7. `node --test test/smoke-select.test.mjs` — 7/7, реестр `smoke-links.mjs` + структурно цел (символы/файлы существуют). +8. Сопутствующая регрессия дельты: прогнал `smoke_room_settings_form.mjs` и + `smoke_device_settings_form.mjs` на HEAD — оба `OK`. Дельта их не + касалась, но они входят в ту же запись реестра, что и правленый файл; + дешёвый прогон снял вопрос о побочном эффекте. + +## Унаследовано из r1 + +Без повторной проверки в этом раунде — документ `docs/reviews/CODE-REVIEW-639-r1.md`, +SHA `0ac08434b5cd12848ce8b18aa17a6343b83b6653`: + +- Причинно-следственная цепочка задачи (регресс #608 → красные ночные + гарды `smoke_room_settings_form`/`smoke_device_settings_form`) и её + устранение (`input`+`change` вместо только `input` на четырёх полях + `room-*-scale`, `marker-glow-brightness`, `marker-size`, `marker-angle`). + Дельта r2 эти файлы не трогает. +- Проверка, что соседние `unitInput`-поля без `rangeLine` (`#room-temp-min/max`, + `#marker-glow-radius`) не были задеты и не должны были быть. +- Структурная целостность `scripts/smoke-links.mjs` (символы/смоки + существуют) — механическая часть теста `smoke-select.test.mjs`, не + менялась. +- Классификация изменения (класс B, `User-Visible: no`, changelog не + требуется) — новый коммит несёт те же трейлеры (`Issue: #639`, + `User-Visible: no`), проверил их наличие в `a3397329`, но не пересматривал + саму классификацию. +- Полный перечень «чего не проверял и почему» (`tsc`/`npm test`/`npm build` + без пересборки — только на основании Validate; `check-docs`, `invariants`, + `golden:verify`, `pytest tests_backend`, перф-профили — диф вне их + условий). Дельта r2 не меняет ни одного из этих условий: всё ещё один + тестовый файл, не `src/**`, не геометрия, не Python, не рендер. + +## Находки + +Новых нет. Единственная находка r1 (M1) закрыта по существу — см. таблицу +выше. Дельта не вносит собственных дефектов: изменение состоит из тех же +DOM-событий (`input`+`change`), что уже использует эталонный код в этом же +файле для `#space-temp-max`, `#space-north-deg`, `.hpf-opacity input`, и тот +же коммит-контракт `rangeLine`, что уже подтверждён в r1 для room/device. + +## Что проверено и корректно + +- Новый DOM-путь `#space-card-font` соответствует продуктовому коммит- + контракту `rangeLine()`/`committedRangeLineValue` — подтверждено чтением + `form-kit.ts` и `space-form.ts`. +- Ассерты `fontDraftWaitsForChange`/`fontNumberCommitsThroughDom` включены + в `checkAll(out)` и реально влияют на код возврата смока (не отрисовка + без проверки). +- Тест умеет падать: воспроизвёл ровно на откате правленых строк. +- Соседние проверки того же смока (`resetDisabledAt100`, `resetRestores100`, + весь блок AC1/AC2/AC9/К1/К10, полосы экранов) не тронуты диффом и + остались зелёными при полном прогоне файла. +- Трейлеры коммита `a3397329`: `Issue: #639`, `User-Visible: no` — верно, + тестовая инфраструктура, изменений в user-facing changelog не требуется. + +## Чего не проверял и почему + +- `npx tsc --noEmit`, `npm test`, `npm run build` (сверка 3 копий бандла как + отдельный гейт) — не перегонял как отдельную проверку: Validate на `a3397329` + зелёный (https://github.com/Matysh/houseplan-card/actions/runs/35841321979, + указан в постановке задачи). `npm run bundle:sync` пересобрал тот же + бандл ради локальной копии для смока, но это не замена «сверки трёх + копий» как отдельного гейта, а побочный эффект пункта 3 выше. +- `node scripts/check-docs.mjs` — не запускал: дифф не трогает `src/**` + (файл в `demo/`), отпечаток скриншотов не устаревает. +- `npm run invariants` — не запускал: дифф не трогает геометрию/`layout`/ + толщины/`marker.space`/`open_spans`. +- `npm run golden:verify` — не запускал: дифф — событийная семантика теста, + не код рендера; видимый результат карточки не меняется. +- `python -m pytest tests_backend` — не запускал: `custom_components/**/*.py` + не тронут. +- Остальные смоки `demo/smoke_*.mjs` вне записи `rangeLine`/`unitInput` — + не гонял: `smoke-select` их не выбирает, дифф темы не пересекает. +- Perf-профили — не запускал: не названы в задаче, дифф не задевает + чувствительные к перфу пути. + +## Вывод + +Дельта r2 — точечная правка ровно по единственной находке r1: смок +`smoke_space_settings_form.mjs` теперь действительно ведёт `#space-card-font` +через `input`+`change`, как заявляет запись `smoke-links.mjs`, и падает при +откате к прежнему прямому присваиванию. Причинно-следственная цепочка задачи +и фиксы room/device наследуются из r1 без повторной проверки — дельта их не +касается. Новых находок нет. + +**Вердикт: зелёный.** + +--- + +--- + + + +## Материал раунда + +- Ветка: `issue/639-range-line-smokes`, коммит `a3397329d534` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `226a65401a6b48c9a19b8f450288905e5e7ec8e4` + ``` + git log --all --format='%H %T' | grep 226a65401a6b + ``` +- Тело issue: `7ad41f5686d99bfd44e274349b50adaec808bc8169c0e0ea2f31df52671bf0b3` +- Вердикт конвейера: `green` · High 0