Files
houseplan-card/docs/reviews/CODE-REVIEW-639-r2.md
T
claude[bot] b1f1f6b754
Проверка (CI) / Классификация изменённых файлов (push) Successful in 43s
Проверка (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) Failing after 1m2s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m9s
Проверка (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 31s
docs: review document for #639
Issue: #639
User-Visible: no
2026-09-23 09:21:53 +00:00

14 KiB
Raw Blame History

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 <SHA>..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