Files
houseplan-card/docs/reviews/CODE-REVIEW-258-r2.md
T
claude[bot] 9f63163339
Validate / docs (push) Failing after 21s
Validate / process-workflow-sync (push) Successful in 26s
Validate / changes (push) Successful in 32s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / provenance (push) Successful in 1m4s
Validate / process-gate (push) Successful in 51s
Validate / reuse (push) Successful in 44s
Validate / smoke (1) (push) Skipped
Validate / smoke (2) (push) Skipped
Validate / smoke (3) (push) Skipped
Validate / smoke_done (push) Skipped
Validate / golden (push) Skipped
Validate / performance_smoke (push) Skipped
Validate / backend (push) Skipped
docs: review document for #258
Issue: #258
User-Visible: no
2026-08-23 11:46:19 +00:00

198 lines
17 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-258-r2
Issue: #258 «На 1.67.0-beta.4 после «Оптимизировать» появились белые клинья в местах схода стен»
Этап: code
Заход: r2 · блокирующих циклов израсходовано 1 из 4
Ветка: `issue/258-wall-key-storage-roundtrip`
HEAD ревью: `61bf537b58a2e2c0b78e6e2a55a1075f90618dbd`
SHA предыдущего раунда (r1, код-ревью): `28eaf86662819651b2c75e7423280f10820a757d`
Документ r1: `docs/reviews/CODE-REVIEW-258-r1.md` (закоммичен отдельным коммитом `aa85a95` поверх r1-кода — не часть проверяемого кода)
## Скоуп раунда
Раунд r1 (код) дал жёлтый вердикт с единственной находкой Medium в скоупе:
формулировки `docs/CHANGELOG.md`/`.ru.md` безусловно заявляли, что зарепорченные
белые клинья устранены, хотя собственное измерение владельца в этом же issue
(комментарий от 2026-08-23T11:15:02Z) показало: переписанные Optimize-ключи не
меняют `wallEdgeBodies`/карту узлов на реальных экспортах владельца ни на бит.
Реализация исправляет доказанный дефект другого класса — рассогласование
структурных потребителей (`lookupWall`/`thicknessCmAt`/`cmsForPoly`) на
устаревшем compatibility-key, — но changelog должен был описывать именно его,
а не визуальный симптом со скриншотов.
Дельта r2 — правка по этой находке:
```
git diff 28eaf86..HEAD --stat
docs/CHANGELOG.md | 11 +-
docs/CHANGELOG.ru.md | 12 +--
docs/reviews/CODE-REVIEW-258-r1.md | 204 ++++++++++++++++++++++++++++++
```
`docs/reviews/CODE-REVIEW-258-r1.md` — публикация документа r1 предыдущим
циклом, не код автора; предмет этого раунда — только два changelog-файла,
изменённые коммитом `61bf537` («docs: correct wall-key changelog claim»,
`Issue: #258`, `User-Visible: no`).
Дельта локальна: не рёбейз (родитель `28eaf86` — прямой предок `HEAD`, `dev`
не менялся под веткой), не смена контракта поведения, не задета новая
подсистема — правка чисто текстовая, в двух файлах документации одного
формата. Продуктовый код (`src/**`, `test/**`, `scripts/**`,
`custom_components/**`) между `28eaf86` и `HEAD` не менялся вовсе — проверено
`git diff 28eaf86..HEAD --stat` (полный список выше, других файлов нет).
Поэтому разбор сокращён до дельты: обзор AC не переоткрывается, потому что
дельта не касается кода, от которого зависит их доказательство.
## Как проверялось
1. Восстановлен вердикт и SHA r1 из истории issue (`gh issue view 258`,
комментарий `claude` от `2026-08-23T11:38:29Z`) и из `git log` — SHA в самом
тексте вердикта не назван прямо, но однозначно восстанавливается по
`git show --stat aa85a95` (документ r1 закоммичен поверх `28eaf86`) и по
тексту комментария реализации («Коммит: `28eaf866...`»).
2. `git diff 28eaf86..HEAD` — построчно, целиком (полный текст ниже).
3. Проверено, что новая формулировка changelog не переносит старую
ошибку в другую форму: сверена с AC2/AC5 спецификации
(`docs/specs/258-wall-key-storage-roundtrip.md`, `git show 28eaf86:...`) и с
текстом r1-вердикта — заявление ограничено «толщина стены согласована у
структурных потребителей при перезаписи compatibility-key», без упоминания
устранения белых клиньев с реальных скриншотов.
4. Прогнаны дешёвые гейты (см. таблицу) — не потому что дельта могла их
сломать (текст в `.md` не компилируется и не тестируется), а чтобы
подтвердить прямым исполнением, что дерево `src/**`/`test/**` осталось
тем же деревом, на котором r1 уже получил зелёный результат, а не
заявлением автора.
### Полный diff дельты r2
```diff
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -2,11 +2,12 @@
## Unreleased
-- Thick-wall T-junctions no longer develop white wedges after “Optimize
- plans”. Wall identity now stays stable when an exact `1/240` grid endpoint is
- persisted with nine decimal places, and already affected records are read by
- their exact endpoint pair without broadening legacy midpoint matching.
- Optimize canonically repairs the stored key and remains a no-op after reload
+- Wall thickness now stays consistent across structural consumers when
+ “Optimize plans” rewrites a compatibility key. Wall identity remains stable
+ when an exact `1/240` grid endpoint is persisted with nine decimal places,
+ and already affected records are read by their exact endpoint pair without
+ broadening legacy midpoint matching. Optimize canonically repairs the stored
+ key and remains a no-op after reload
([#258](https://github.com/Matysh/houseplan-card/issues/258)).
--- a/docs/CHANGELOG.ru.md
+++ b/docs/CHANGELOG.ru.md
@@ -8,12 +8,12 @@
## Не выпущено
-- После «Оптимизировать планы» в T-образных стыках толстых стен больше не
- появляются белые клинья. Идентификатор стены теперь остаётся стабильным,
- когда точный узел сетки `1/240` сохраняется с девятью знаками, а уже
- затронутые записи читаются по точной паре концов без расширения старого
- поиска по середине. Optimize канонически исправляет сохранённый ключ и после
- перезагрузки остаётся no-op
+- После перезаписи compatibility-key командой «Оптимизировать планы» толщина
+ стены теперь остаётся согласованной у всех структурных потребителей.
+ Идентификатор стены стабилен, когда точный узел сетки `1/240` сохраняется с
+ девятью знаками, а уже затронутые записи читаются по точной паре концов без
+ расширения старого поиска по середине. Optimize канонически исправляет
+ сохранённый ключ и после перезагрузки остаётся no-op
([#258](https://github.com/Matysh/houseplan-card/issues/258)).
```
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| Medium (в скоупе): `docs/CHANGELOG.md`/`.ru.md` безусловно заявляют устранение белых клиньев со скриншотов владельца, хотя собственное измерение владельца в issue показывает, что переписанные Optimize-ключи не меняют `wallEdgeBodies`/карту узлов на его реальных данных. | Оба changelog переформулированы на факт, доказанный AC2/AC5/мутационными тестами: согласованность толщины между структурными потребителями (`lookupWall`/`thicknessCmAt`/`cmsForPoly`) при перезаписи compatibility-key. Упоминание устранения белых клиньев убрано из обоих файлов; причина визуального симптома явно оставлена за рамками (`#261`, уже заведён автором в r1). | `docs/CHANGELOG.md:5-9`, `docs/CHANGELOG.ru.md:11-15`, коммит `61bf537` (diff — выше целиком, других изменений в коммите нет). |
Находка закрыта полностью: новая формулировка не содержит утверждений вне
доказанного (сверено с AC2 и подтверждённым в r1 фактом, что `thicknessCmAt`
и `cmsForPoly` идут через один и тот же исправленный `lookupWall`), а строки
про белые клинья/скриншоты удалены из обеих версий файла синхронно, в одном
коммите с трейлером `Issue: #258`.
## Унаследовано из r1
Всё, что не относится к changelog, унаследовано без повторной проверки —
делать это безопасно, потому что `git diff 28eaf86..HEAD --stat` подтверждает
байт-в-байт отсутствие изменений в `src/**`, `test/**`, `scripts/**`,
`custom_components/**`, `demo/**` (кроме уже упомянутых двух `.md`-файлов) —
дельта в принципе не может задеть эти доказательства:
- **AC1–AC3, AC5–AC8** — доказаны исполнением в r1 (unit/mutation-таблицы,
targeted production-bundle smoke, golden-сценарий с semantic probes,
`typecheck`/`test`/`build`/`check-docs`). Документ: `docs/reviews/CODE-REVIEW-258-r1.md`, SHA `28eaf86662819651b2c75e7423280f10820a757d`.
- **AC4 (осознанное отступление)** — `checkWallKeys` диагностирует несовпадение
key↔wallKey(a,b) как observation, а не violation, согласовано с `#259`
(`5e95a28`); r1 признал отступление обоснованным и не смог обнаружить
регрессии в этом сужении. Документ: `docs/reviews/CODE-REVIEW-258-r1.md`, SHA `28eaf86662819651b2c75e7423280f10820a757d`.
- **Три копии бандла и мутационные анкеры** — синхронность
`dist/houseplan-card.js` ↔ `custom_components/houseplan/frontend/houseplan-card.js`
↔ `demo/srv/assets/houseplan-card.js` и убойность мутационных анкеров
подтверждены в r1 исполнением; независимо переподтверждено в этом раунде
(см. таблицу гейтов) командой `cmp` после `npm run build` + `npm run bundle:sync`.
- **Инварианты модели (#254) и smoke-выборка** — `smoke_wall_key_roundtrip.mjs`
(24/24 assertion) и `smoke_resize_wall_thickness.mjs` прогнаны и зелёные в
r1; дельта r2 не касается геометрии, `layout`, `marker.space`, `open_spans`
или записей толщины — прогон не повторялся намеренно (раздел «Чего не
проверял» ниже).
## Что проверено и корректно (дельта r2)
- Формулировки обоих changelog теперь ограничены доказанным фактом и не
заявляют устранения визуального симптома владельца — устраняет находку r1
дословно так, как она была сформулирована.
- EN и RU версии согласованы по смыслу (проверено построчным сопоставлением
diff выше) — не разошлись в переводе, как могло бы случиться при точечной
правке одного файла.
- Трейлеры коммита `61bf537`: `Issue: #258` есть; `User-Visible: no`
корректен — сам код продукта не менялся, меняется только текст описания
уже отгруженного (в предыдущем коммите) изменения; предыдущий коммит
`28eaf86` (`User-Visible: yes`) уже включал правку обоих changelog в одном
коммите с кодом — обязательное правило «правки в оба changelog в том же
коммите» соблюдено на уровне исходного изменения, а не только на уровне
правки формулировки.
- `git diff --check 28eaf86..HEAD` — чисто, конфликтов пробелов нет.
- Рабочее дерево чистое после `npm run build && npm run bundle:sync`
(`git status --porcelain` — пусто), три копии бандла побайтово совпадают.
## Гейты: что прогнал и почему
| Гейт | Прогнан | Результат | Почему (не) прогонял |
|---|---|---|---|
| `npx tsc --noEmit` | да | чисто, 4.8s | дешёвый, обязателен каждый раунд |
| `npm test` | да | 1159 passed, 0 failed, 7.3s | дешёвый, обязателен каждый раунд; заодно подтверждает, что кодовое дерево не разошлось с тем, что видел r1 |
| `npm run build` + сверка 3 копий бандла | да | сборка ок; `cmp dist ↔ custom_components/houseplan/frontend` и `dist ↔ demo/srv/assets` (после `npm run bundle:sync`) — побайтовое совпадение | дешёвый, обязателен каждый раунд |
| `node scripts/check-docs.mjs` | нет | — | условие запуска — diff трогает `src/**`; дельта r2 — только `docs/CHANGELOG*.md`, `src/**` не тронут. Уже прогнан в r1 на коде, который не изменился (см. комментарий владельца от 2026-08-23T11:23:49Z) |
| Инварианты модели (`npm run invariants`/`model-invariants.mjs`) | нет | — | дельта не трогает геометрию, `layout`, `marker.space`, `open_spans` или записи толщины — только текст changelog |
| Browser smoke (`smoke_wall_key_roundtrip.mjs`, `smoke_resize_wall_thickness.mjs`) | нет | — | относились к продуктовому коду `28eaf86`, уже зелёные в r1; дельта r2 их не касается — код `src/wall-thickness.ts` не менялся между раундами |
| `npm run golden:verify` | нет | — | дельта не меняет рендер/геометрию/стили/слои, только markdown |
| `python -m pytest tests_backend -q` | нет | — | `custom_components/**/*.py` не тронут ни в r1, ни в дельте r2 |
| performance-профили | нет | — | не названы в AC, чувствительные к перфу пути не тронуты |
## Чего не проверял
- Не переисполнял golden-сценарий и mutation-анкеры r1 — дельта не может их
задеть (текстовые файлы `.md` не участвуют ни в сборке, ни в рендере).
- Не перепроверял продуктовый диагноз причины белых клиньев на реальных
экспортах владельца — это прямо вне скоупа #258 (см. non-scope спецификации
и последующий #261, уже заведённый автором в r1 для этого следа).
- Не проверял #259/#261 — отдельные issue, не предмет этого ревью.
## Вывод
Единственная Medium-находка r1 закрыта точно и полностью: changelog больше не
заявляет ничего, что не доказано, а формулировка соответствует тому, что
реально исправлено и подтверждено исполнением (согласованность толщины между
структурными потребителями при перезаписи compatibility-key). Дельта нового
раунда не вносит собственных находок. Новых High/Medium нет.
**Вердикт: зелёный.**