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

177 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`](https://github.com/Matysh/houseplan-card/blob/dev/docs/reviews/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`.