Files
houseplan-card/docs/reviews/CODE-REVIEW-217-r1.md
T
claude[bot] 9e8393f874
Validate / docs (push) Successful in 26s
Validate / provenance (push) Successful in 52s
Validate / process-gate (push) Failing after 1m1s
Validate / changes (push) Successful in 53s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / reuse (push) Successful in 58s
Validate / backend (push) Skipped
Validate / frontend (push) Successful in 6m44s
Validate / golden (push) Failing after 11m20s
Validate / performance_smoke (push) Failing after 12m44s
Validate / smoke (push) Failing after 31m10s
docs: review document for #217
Issue: #217
User-Visible: no
2026-08-20 10:30:27 +00:00

14 KiB
Raw Blame History

CODE-REVIEW-217-r1

  • Issue: #217 — внешняя рамка Text-маркера должна быть капсулой
  • ТЗ: docs/specs/217-text-shell-outline.md (SPEC-REVIEW-217-r1, зелёный)
  • Ветка/SHA: issue/217-text-shell-outline @ 39456dc (implementation), предыдущий коммит fe33dea (spec), c547586 (spec-review doc)
  • Диапазон: origin/dev...HEAD
  • Трек: обычный (не small)
  • Цикл: r1/4
  • Вердикт: зелёный · High: 0 · Medium: 0

Скоуп ревью

Первый цикл — разбор полный. git log --oneline origin/dev..HEAD даёт три коммита (spec, spec-review doc, implementation); git diff origin/dev...HEAD — 17 файлов. Проверены: сам фикс в src/styles.ts, source-regression тест, изменения в demo/smoke_device_icon_design.mjs, golden-матрица (demo/golden/matrix.mjs, harness.mjs, test/golden-matrix.test.mjs), reference-капчер (capture_device_icon_reference.mjs), оба changelog, docs/TESTING.md, docs/images/screenshots.json, три копии бандла, трейлеры коммитов. Соответствие AC1–AC9 из §13 ТЗ проверено по каждому пункту.

Как проверялось

Прочитаны целиком: docs/SCOPE.md, AGENTS.md, PROCESS.md §2.7/§7.2/§8/§12, docs/specs/217-text-shell-outline.md, тело issue #217 и оба комментария, docs/reviews/SPEC-REVIEW-217-r1.md (контекст спек-ревью), src/styles.ts (строки 2013–2090 — весь блок .device-shell/.device-shell-frame), src/device-face.ts (весь renderDeviceFace, классы text-shell/with-values).

Прогнаны гейты:

Команда Результат
npx tsc --noEmit 0 ошибок
npm test 957 pass / 0 fail
npm run build + md5sum dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js demo/srv/assets/houseplan-card.js одинаковый хеш 6b01daba677f602728d128dc80e25cfc во всех трёх копиях
node scripts/check-docs.mjs --external "Documentation checks passed (7 files, 10 external links)"
node demo/smoke_device_icon_design.mjs (изменён в этом диффе, покрывает AC1–AC5) все флаги true, OK
node demo/smoke_device_preview_parity.mjs (AC7, названа в §14.2 ТЗ) все флаги true, OK
node demo/smoke_static_icon.mjs (AC7, названа в §14.2 ТЗ) все флаги true, OK
npm run golden:verify (диагностически, диф — CSS-геометрия, видимый результат меняется) см. ниже

Дисциплина «тест должен уметь падать» — применена к обоим тестам, которые покрывают сам фикс:

  • временно вернул старый селектор .device-shell:not(.with-values) .device-shell-frame (без :not(.text-shell)) в src/styles.ts, пересобрал, скопировал бандл в demo/srv/assets/, прогнал smoke_device_icon_design.mjs — красным стали ровно textShellIsStadiumAtRepresentativeSizes: false и textShellMutationGuardRejects50Percent: false, остальные 39 флагов не затронуты;
  • на том же мутанте прогнал node --test test/device-marker-polish-contract.test.mjs — 6 pass / 1 fail (упал именно новый тест issue 217 keeps the Text shell stadium...);
  • восстановил src/styles.ts из git, пересобрал, скопировал все три копии бандла — хеши снова совпали с закоммиченными (6b01daba677f602728d128dc80e25cfc), git status чист.

npm run golden:verify (диагностический Linux-раннер, не гейт код-ревью): 90 сценариев, passed — 84, different — 2, missing-baseline — 2, error — 0.

  • missing-baseline: device-text-shell-long-{light,dark} — новые сценарии из этого диффа, у них по определению ещё нет принятого baseline. Просмотрел artifacts/golden/actual/device-text-shell-long-{light,dark}.png: маркер 498 ppm показывает корректную stadium-форму (полукруглые торцы, прямой средний участок сверху/снизу) в обеих темах — визуально решает ровно тот сценарий, который описан в §2 ТЗ.
  • different: device-icon-state-table-{light,dark} — существующий, ранее принятый baseline. Просмотрел artifacts/golden/diff/*.png: расхождение строго локализовано на одном маркере — golden-left-temperature (Text-only, display: value, длинное значение "Complete long localized state..."), его внешняя рамка стала капсулой вместо эллипса; стены, комнаты, остальные маркеры (Double/badge, Icon-only, presence, climate, LQI) пиксель в пиксель не изменились. Это ожидаемый побочный эффект того же самого фикса на уже существующем сценарии — доказательство, что фикс работает единообразно, а не находка. Принятие обновлённого baseline — пре-релизный шаг (npm run golden:accept -- --reviewed на Linux CI-артефакте, AGENTS.md «Gates»), не действие код-ревью; тот же паттерн зафиксирован в docs/reviews/CODE-REVIEW-213-r1.md.

Не прогонялись и почему:

  • полный набор demo/smoke_*.mjs (127 файлов) — диф не задевает стены, tray, sun/glow, openings, isometric и т.п.; golden:verify выше подтвердил, что все сценарии этих поверхностей passed без изменений, значит расширять смок-набор не нужно;
  • python -m pytest tests_backend -q — диф не касается custom_components/**/*.py;
  • перф-профили — AC8 не требует их явно, изменение CSS-only (одно правило, без нового JS/ResizeObserver/слоя), проверено чтением src/styles.ts и диффа demo/smoke_device_icon_design.mjs целиком — новых наблюдателей, таймеров или compositor-слоёв не добавлено;
  • npm run golden:accept — не роль код-ревью (см. выше).

Проверка AC (§13 ТЗ)

  1. AC1 (stadium shell). Подтверждено визуально по обоим новым golden-кадрам и смоком textShellIsStadiumAtRepresentativeSizes. ✅
  2. AC2 (защита от 50%). Source-тест test/device-marker-polish-contract.test.mjs и browser-мутант в смоке оба красны на documented mutant — проверено ручным реверсом селектора (см. выше). ✅
  3. AC3 (матрица размеров). textShellSizeMatrix в смоке проходит все пять размеров (24/32/56/96/112) с допуском <=0.5px для радиуса/инсета. ✅
  4. AC4 (геометрическая совместимость). Изменение — только border-radius одного CSS-правила; width/height/inset этим свойством не затрагиваются ни в спецификации CSS, ни фактически (golden-диф показывает identical footprint, меняется только форма угла). Проверено чтением + golden-диф. ✅
  5. AC5 (соседние варианты). iconShellIsCircle и doubleShellKeepsCapsule в смоке — true; golden-диф подтверждает, что Icon-only/Double/badge маркеры в device-icon-state-table-* не изменились ни на пиксель. ✅
  6. AC6 (interaction parity). valueCapsuleOwnsHoverAndActionAtEveryPosition, hitAreaAtLeast44 — true; правка не касается pointer-events, hover- или action-кода — только border-radius в CSS, подтверждено чтением диффа. ✅
  7. AC7 (surface/theme parity). smoke_device_preview_parity.mjs (planPreviewEqual, planStaticEqual — true) и smoke_static_icon.mjs (planStaticCardParity — true) плюс golden в обеих темах. ✅
  8. AC8 (data/i18n/security/perf). Диф не содержит правок схемы, storage, i18n-ключей, resolveToggleIntent/isControllable/action-путей, ResizeObserver, media listener или анимации — проверено чтением всего диффа (git diff origin/dev...HEAD). ✅ — «проверено чтением, не исполнением».
  9. AC9 (release artifacts). docs/CHANGELOG.md и docs/CHANGELOG.ru.md правлены в том же коммите 39456dc (User-Visible: yes), docs/TESTING.md получил новый раздел «Text marker shell shape (#217)», docs/images/screenshots.json fingerprint обновлён и подтверждён check-docs.mjs, golden/smoke fixtures обновлены. ✅

Трейлеры и класс изменений

  • fe33dea (спек, класс C) — Issue: #217 / User-Visible: no — корректно.
  • c547586 (документ спек-ревью, класс C) — те же трейлеры — корректно.
  • 39456dc (реализация) — Issue: #217 / User-Visible: yes; правки src/** (класс A, только CSS), test/**/demo/** (класс B), dist/**/custom_components/houseplan/frontend/**/demo/srv/assets/** (класс D, три копии синхронны), docs/** (класс C, оба changelog в том же коммите — соответствует требованию AGENTS.md). Всё в одном коммите, ветка не содержит признаков ребейза на ушедший вперёд dev (три коммита линейно продолжают origin/dev).

Находки

Нет находок High или Medium. Low не обнаружено (терминология changelog "капсульную форму" соответствует docs/USER-GUIDE.ru.md; спек-ревью уже снял единственный Low прошлого этапа — слово "stadium" в тексте ТЗ, не в user-visible строке).

Что проверено и корректно

  • Сам фикс — src/styles.ts:2061: сужение селектора .device-shell:not(.with-values) .device-shell-frame до .device-shell:not(.with-values):not(.text-shell) .device-shell-frame. Единственная строка продуктового кода, ровно то, что предсказано §11 ТЗ ("сузить circular override так, чтобы он не захватывал Text").
  • Комбинация классов text-shell + with-values (Text с badge) не затронута: такой маркер и раньше не попадал под circular override (уже был исключён :not(.with-values)), новое условие :not(.text-shell) для него избыточно, но не вредит — подтверждено чтением src/device-face.ts:96-101.
  • Regression-тест и browser-мутант доказанно умеют падать (ручной реверс, см. «Как проверялось»).
  • Побочный эффект на уже принятом golden (device-icon-state-table-*) локализован ровно на затронутом маркере, остальная сцена не сдвинулась — подтверждает, что фикс не расширяет blast radius за пределы Text-shell.
  • Три копии бандла синхронны после чистой пересборки; фингерпринт скриншотов обновлён и проходит check-docs.mjs.

Чего не проверял

  • Полный demo/smoke_*.mjs (127 файлов) — не запускал; необходимость отсутствует, см. «Как проверялось». Косвенно покрыто через golden:verify (все нетронутые поверхности — passed).
  • python -m pytest tests_backend — не запускал, диф не касается backend.
  • Performance-профили (performance_smoke и аналоги) — не запускал; AC8 не требует их явно, изменение CSS-only проверено чтением.
  • Принятие/пересчёт golden baseline (npm run golden:accept -- --reviewed) — сознательно не выполнял: это пре-релизный шаг на полном Linux CI-артефакте, не входит в роль код-ревью (прецедент — CODE-REVIEW-213-r1). Два missing-baseline и два different сценария должны быть приняты перед публикацией беты — фиксирую это как ожидаемый следующий шаг, не как блокирующую находку.
  • Ручное браузерное тестирование за пределами smoke_*.mjs/golden:verify — не проводилось; по процессу ручного тестирования в цикле код-ревью нет.