Files
houseplan-card/docs/reviews/CODE-REVIEW-195-r2.md
T
2026-08-19 13:46:04 +00:00

16 KiB
Raw Blame History

CODE-REVIEW-195-r2

  • Issue: https://github.com/Matysh/houseplan-card/issues/195
  • Трек: trivial (короткий, §5.1 PROCESS.md) — ТЗ живёт в теле issue, спек-файла нет и не требуется.
  • Диапазон: git log --oneline origin/dev..HEAD / git diff origin/dev...HEAD на ветке issue/195-editor-close-hit-target после ребейза на актуальный origin/dev:
    • 016c75f fix: enlarge editor close hit target (Issue: #195, User-Visible: yes)
    • 2ef3241 test: sample editor close glyph before removal (Issue: #195, User-Visible: no)
    • 07b0b3d docs: review document for #195 (Issue: #195, User-Visible: no) — сохранённый документ предыдущего зелёного ревью
  • Роль: ревьюер кода (не автор), этап S7-code-review
  • Цикл: r2/2 (лимит короткого трека). r1 закончился зелёным вердиктом (High: 0, Medium: 0, CODE-REVIEW-195-r1.md); слияние в dev не удалось из-за конфликта, ветка перебазирована и переведена обратно в S7-code-review — по AGENTS.md после ребейза это другой код и требует полноценного повторного прогона, а не формальности.

Почему нужен новый цикл, а не переиспользование r1

dev ушёл вперёд (в частности #186, #176) с момента r1; ребейз переписал историю и мог затронуть файлы, которые r1 не рассматривал в их новой форме (docs/STATUS.md, docs/images/screenshots.json, три копии бандла). Цель r2 — не переделать анализ К1/К2/К3 заново, а убедиться, что: (а) продуктовая и тестовая правки, уже одобренные в r1, дошли до постребейзного дерева байт-в-байт; (б) конфликты разрешены корректно, без потери чужих изменений или порчи новой правки; (в) все обязательные гейты зелены именно на текущем HEAD, а не на снятой с проверки версии.

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

  1. git fetch origin и сверка git log --oneline origin/dev..HEAD — диапазон соответствует ожидаемому (три коммита выше), рабочее дерево чистое (git status).
  2. Побайтовое сравнение продуктового и тестового коммитов с версиями, которые видел r1:
    • git show 016c75f -- src/styles.ts — диф идентичен диффу 140a56f из r1 (то же правило .modetab .closex: width/height: 24px, margin: -5.5px -5.5px -5.5px -3.5px, тот же комментарий). Продуктовая логика не менялась при ребейзе.
    • git show 2ef3241 -- demo/smoke_editor_tabs.mjs — диф идентичен диффу a169cc6 из r1 (тот же фикс порядка измерения glyphStays13 до клика).
    • git diff origin/dev...HEAD -- src/houseplan-card.ts — 0 строк: _setMode/_finishWallChain по-прежнему не тронуты, К2/К3 не переписаны, короткий трек остаётся корректным выбором.
    • git diff origin/dev...HEAD --stat -- 'src/**' 'custom_components/houseplan/**/*.py' manifest.json hacs.json — единственный класс-A файл: src/styles.ts, 10 изменённых строк.
  3. Проверены файлы, затронутые слиянием с новым dev (не входили в diff r1 в этом виде):
    • docs/CHANGELOG.md/docs/CHANGELOG.ru.md — запись #195 присутствует в обеих версиях и запись #186, добавленная на dev после r1, не потеряна (обе видны последовательно в git show 016c75f -- docs/CHANGELOG.md).
    • docs/STATUS.md — строка Current local cycle перечисляет и #180/#192/ #193/#196/#197/#176 (историю dev), и добавленное предложение про #195; ни одна запись не выпала при разрешении конфликта.
    • docs/images/screenshots.json — sourceFingerprint/sourceSha256 обновлены (edb4278c… → b0a03dc3…), imageSha256 не менялись — согласуется с тем, что это чисто невидимая CSS-правка: скриншоты не перевыпускались, обновился только хеш исходников, который включает весь src/** (в него входят и посторонние изменения dev, попавшие в диапазон ребейза, — не только #195).
  4. Перепрогнаны обязательные гейты лично на текущем HEAD (не переиспользована декларация из хендоффа/r1) — см. таблицу.
  5. Falsifiability прогнанного browser smoke повторно подтверждена на постребейзном дереве: временно восстановлен дореформенный src/styles.ts (git show 016c75f^:src/styles.ts), пересобран бандл, скопирован в demo/srv/assets/; node demo/smoke_editor_tabs.mjs упал ровно на tabCrossTargetsAtLeast24: expected true, got false, остальные проверки остались зелёными. Дерево восстановлено (cp исходного src/styles.ts из бэкапа), бандл пересобран и скопирован в обе generated-копии; cmp подтвердил побайтовое совпадение всех трёх копий с dist/houseplan-card.js, git status --short пуст.
  6. node scripts/check-docs.mjs --external — проверяет обновлённый sourceFingerprint из п.3 против фактического текущего src/**; зелёный, значит хеш в screenshots.json не рассинхронизирован с постребейзным деревом (это тот самый гейт docs, который в CI ловит именно такое расхождение после #113).
  7. Прочитан docs/USER-GUIDE.ru.md:166 — формулировка «крестик активного редактора» совпадает с изменённым текстом docs/CHANGELOG.ru.md и docs/UX-MODES.md; новых терминов интерфейса не изобретено.
  8. Содержательный анализ AC (диагностика К1/К2/К3, корректность фикса, отсутствие расширения скоупа) не повторялся заново — он не зависит от ребейза, полностью выполнен и задокументирован в r1, и продуктовый код, как показано в п.2, не изменился ни на байт.

Обязательные гейты (всегда)

Гейт Команда Результат
Typecheck npx tsc --noEmit чисто, без вывода
Unit-тесты npm test 908/908, 0 fail (было 900/900 в r1 — рост за счёт тестов, вошедших в dev после r1)
Build + сверка бандлов npm run build, затем cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js и cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js оба cmp без вывода — три копии идентичны; git status --short после сборки пуст
Docs-гейт node scripts/check-docs.mjs --external Documentation checks passed (7 files, 10 external links).

Гейты по необходимости

Гейт Почему запускался / не запускался Результат
node demo/smoke_editor_tabs.mjs назван в AC1–AC3 issue, единственный смок по затронутой поверхности (.modetab, header editor tabs); повторно прогнан на постребейзном бандле, а не переиспользован из хендоффа зелёный, все 48 проверок true; falsifiability подтверждена в п.5 выше на текущем дереве
Остальные 126 demo/smoke_*.mjs diff после ребейза по-прежнему один CSS-селектор на header editor tabs (п.2); других продуктовых поверхностей ребейз не добавил не прогонялись — сознательное сужение, как в r1
npm run golden:verify видимая геометрия не менялась (тот же вывод, что в r1, п.6 того документа: расчёт CSS box-модели + эмпирическое измерение rect); ребейз не тронул demo/golden/baselines/** (нет в diff-статистике) и не добавил новых визуальных изменений сверх CSS-правила из r1 не запускался — обоснованное сужение
python -m pytest tests_backend -q diff не касается custom_components/**/*.py не запускался — неприменимо
performance-профили правка — статический CSS без hot-path кода не запускались — неприменимо

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

  • Продуктовая и тестовая правки дошли до постребейзного HEAD без изменений. 016c75f/2ef3241 побайтово повторяют содержимое 140a56f/a169cc6, одобренное в r1 (п.2). Анализ К1 (единственная подтверждённая причина), корректность фикса (расширение реального border-box кликабельного узла, а не хак с перехватом координат) и легитимность правки теста (computed style фиксируется до удаления узла из DOM) остаются в силе без повторного вывода — код не изменился.
  • Конфликт ребейза разрешён без потерь. docs/CHANGELOG.md/.ru.md и docs/STATUS.md содержат записи и #195, и всех соседей из dev (#186, #176 и далее); docs/images/screenshots.json обновил только фингерпринт исходников (без изменения imageSha256), что подтверждено зелёным check-docs.mjs — сам гейт CI, который ловит именно такое расхождение (#113), проходит на текущем дереве.
  • Все три AC по-прежнему доказаны исполняемым тестом на текущем HEAD. tabCrossTargetsAtLeast24/tabCrossGlyphStays13/tabCrossKeepsLayoutFootprint (AC1), reclickNoop/tabCrossCloseStartsDuringEnter/ tabCrossCloseDuringEnterWorks (AC2), tabCrossFinishesWallChain/ tabCrossLimitKeepsDraftWithFeedback (AC3) — все true; падение до фикса и восстановление дерева воспроизведены заново на постребейзном бандле (п.5), а не приняты на слово из хендоффа.
  • Класс A по-прежнему ограничен одним CSS-селектором. src/houseplan-card.ts не тронут (0 строк), _setMode/_finishWallChain — тот же код, что в dev; трек trivial остаётся верным выбором и после ребейза.
  • Трейлеры и changelog. Все три коммита несут Issue: #195; User-Visible: yes только на 016c75f, оба changelog редактируются в нём же; 2ef3241 и 07b0b3d — User-Visible: no, корректно (тест и документ ревью не меняют продукт).
  • Терминология не изобретена. docs/UX-MODES.md, docs/CHANGELOG.ru.md используют формулировку, совпадающую с docs/USER-GUIDE.ru.md:166.

Находки

Находок нет. High: 0, Medium: 0, Low: 0.

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

  • Полный набор demo/smoke_*.mjs (127 файлов). Ребейз не расширил затронутую поверхность за пределы header editor tabs; прогон одного целевого смока соразмерен диффу (PROCESS.md §8).
  • npm run golden:verify. Не запускался повторно. Обоснование не меняется относительно r1: изменение невидимо на пиксель (только hit-zone, не рендер), а demo/golden/baselines/** вне диапазона diff. Полный golden-прогон всё равно случится перед бетой.
  • python -m pytest tests_backend -q и performance-профили. Неприменимы — diff не касается Python-кода и не имеет измеримого влияния на производительность.
  • Multi-touch/реальное тач-устройство. Контракт docs/TOUCH-SUPPORT.md не меняется этой правкой (как и в r1); 24×24 — заявленный в issue WCAG-минимум, не HA-тач-рекомендация 40 px.
  • Повторный содержательный анализ К1/К2/К3 и продуктового обоснования фикса. Не повторялся с нуля — обоснован в п.2 и п.8 выше: продуктовый и тестовый код после ребейза побайтово идентичен тому, что уже прошло r1; предметом r2 был ребейз и его последствия, а не переоткрытие уже закрытого содержательного вопроса.

Вердикт

Зелёный. High: 0, Medium: 0. Ребейз на актуальный dev не изменил ни продуктовый, ни тестовый коммит ни на байт (сверено побайтово); конфликт в документации и генерируемых артефактах разрешён без потери соседних изменений и подтверждён зелёным check-docs.mjs. Все обязательные гейты перепрогнаны лично на текущем HEAD (908/908 тестов, чистый typecheck, идентичные три копии бандла) и целевой demo/smoke_editor_tabs.mjs перепроверен на постребейзном бандле, включая повторное подтверждение, что он умеет падать. Задача готова к слиянию в dev.