mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 20:29:00 +00:00
docs: review document for #282
Validate / docs (push) Failing after 21s
Validate / process-workflow-sync (push) Successful in 47s
Validate / provenance (push) Successful in 49s
Validate / process-gate (push) Failing after 54s
Validate / changes (push) Successful in 54s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / reuse (push) Successful in 52s
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
Validate / docs (push) Failing after 21s
Validate / process-workflow-sync (push) Successful in 47s
Validate / provenance (push) Successful in 49s
Validate / process-gate (push) Failing after 54s
Validate / changes (push) Successful in 54s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / reuse (push) Successful in 52s
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
Issue: #282 User-Visible: no
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
# CODE-REVIEW-282-r4
|
||||
|
||||
- **Issue:** #282 — стабильная идентичность сегментов стен (ADR Stage 1)
|
||||
- **Ветка:** `issue/282-wall-geometry-model`, HEAD `f37efdad8a8f677f0af94ce0297641add5617c4e`
|
||||
- **ТЗ:** `docs/specs/282-stable-wall-segment-identity.md` (spec-review зелёный на r2, `2f30c481`)
|
||||
- **Этап:** код-ревью (PROCESS.md §2.7)
|
||||
- **Заход:** r4 · блокирующих циклов израсходовано 3 из 4 до этого вердикта
|
||||
- **Предыдущий раунд:** `docs/reviews/CODE-REVIEW-282-r3.md`, красный, HEAD на тот момент `95fa23ca79db830b201e82d9a34a05dcc3cecb29`
|
||||
- **Вердикт:** **зелёный**
|
||||
|
||||
## 1. Скоуп проверки
|
||||
|
||||
Разбор по дельте (PROCESS.md §2.10): финальный ребейз на `dev` уже был сделан
|
||||
до r3 (без конфликта), между r3 и этим раундом ветка на `dev` не перебазировалась
|
||||
повторно — `git merge-base --is-ancestor origin/dev HEAD` истинно, дополнительных
|
||||
коммитов слияния нет.
|
||||
|
||||
Дельта `95fa23ca..HEAD` — 2 коммита:
|
||||
|
||||
```
|
||||
fb6cc3ca docs: review document for #282 (публикация CODE-REVIEW-282-r3.md, docs-only, не код)
|
||||
f37efdad fix: keep wall-hosted passages open in static view
|
||||
```
|
||||
|
||||
Файлы правки (без учёта review-документа, класс C):
|
||||
|
||||
```
|
||||
src/space-render.ts (1 строка)
|
||||
demo/smoke_open_passage.mjs (усилена одна ассерция)
|
||||
custom_components/houseplan/frontend/houseplan-card.js (сгенерировано)
|
||||
dist/houseplan-card.js (сгенерировано)
|
||||
docs/CHANGELOG.md, docs/CHANGELOG.ru.md (бюллетень)
|
||||
docs/images/screenshots.json (sourceFingerprint)
|
||||
```
|
||||
|
||||
Дельта предметно локальна и совпадает по границам с единственной находкой r3
|
||||
(H1): изменена ровно та строка, которую r3 указал как источник дефекта, тем же
|
||||
паттерном, что уже применён двумя строками выше в том же файле. Новых
|
||||
продуктовых путей, новой подсистемы или смены контракта дельта не вносит —
|
||||
полный повторный разбор подсистемы не требуется, разбор ограничен этой строкой
|
||||
и её прямыми следствиями, как и предполагал r3 в своём резюме (§9 r3).
|
||||
|
||||
Отдельно проверено предостережение самого r3 («grep не ловит эквивалентную
|
||||
логику, выраженную иначе»): `grep -n "\.host\b" src/*.ts` по всему `src/`
|
||||
показывает, что все прочие потребители `opening.host`/`o.host` уже различают
|
||||
`kind === 'wall'` от `kind === 'partition'` (`plan-geometry-preflight.ts:207,259`,
|
||||
`houseplan-card.ts:9204,15471`, `room-deletion.ts:88`, `wall-segment-model.ts`,
|
||||
`space-render.ts:221,279` и т. д.) — `space-render.ts:437` был единственным
|
||||
местом с устаревшим одноусловным `!opening.host`, и дельта его закрывает.
|
||||
Других эквивалентных, но иначе выраженных фильтров не найдено.
|
||||
|
||||
## 2. Как проверялось — таблица гейтов
|
||||
|
||||
| Гейт | Команда | Результат |
|
||||
|---|---|---|
|
||||
| Typecheck | `npx tsc --noEmit` | зелёный |
|
||||
| Unit/frontend | `npm test` | 1335 тестов, 1334 passed, 0 failed, 1 skipped |
|
||||
| Build + sync бандла | `npm run build && npm run bundle:sync` | зелёный; `cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js` и `cmp … demo/srv/assets/houseplan-card.js` — побайтово идентичны; `git status` после сборки пуст |
|
||||
| Docs fingerprint | `node scripts/check-docs.mjs` | зелёный (7 файлов, 10 внешних ссылок) — обязателен, дельта трогает `src/**`; `sourceFingerprint` в коммите пересчитан верно (совпал с `visualFingerprint(ROOT)` на HEAD) |
|
||||
| Смок-подбор по дельте | `node scripts/smoke-select.mjs --base 95fa23ca --head HEAD` | **НЕОПРЕДЕЛЁННОСТЬ** — изменённая строка не даёт инструменту символа для сопоставления (0 символов на изменённых строках); решение по существу ниже |
|
||||
| Целевой AC7-смок (прямое совпадение по существу находки r3, не по инструменту) | `node demo/smoke_open_passage.mjs` | **OK**, все 13 проверок, включая усиленную геометрическую `staticCutsAndFillsPassage` |
|
||||
| Дисциплина «тест умеет падать» | сборка изолированного `git worktree` на пред-фикс кандидате `fb6cc3ca` (HEAD r3, до строки-фикса) с той же усиленной версией смока | `staticCutsAndFillsPassage: false` — тест детерминированно падает на дефектном коде и проходит на HEAD |
|
||||
| Model invariants | не перепрогонял отдельно | дельта не трогает рёбра/`layout`/`marker.space`/`open_spans` — только фильтр-предикат рендера Static-карточки, геометрия модели не меняется; не требуется в этом раунде |
|
||||
| `golden:verify` | не прогонял локально | поверхность правки — `houseplan-space-card` (`renderSpaceStatic`), который **не входит** в `demo/golden/matrix.mjs` вовсе (там только режимы `plan`/`view`/`devices`/`decor` основной карточки; проверено `grep -n "mode:" demo/golden/matrix.mjs`) — гейт неприменим к этой поверхности. CI `golden` job на точном SHA тем не менее зелёный (см. ниже) |
|
||||
| `pytest tests_backend` | не прогонялся | backend не в дельте (все файлы — frontend/demo/docs) |
|
||||
| Mutation gate | не перепрогонялся | дельта не трогает ни один из именованных `wall-identity-*`-мутантов (файлы вне дельты) |
|
||||
| CI на точном SHA | `gh api .../commits/f37efdad.../check-runs`, run `32912755206` | `Validate`: **completed/success**; все активные джобы (`frontend`, `smoke`×3, `golden`, `performance_smoke`, `docs`, `process-gate`, `provenance`) — success; `backend/hacs/hassfest` — `skipped` (путь-фильтр `changes`, backend/manifest не в дельте — ожидаемо) |
|
||||
|
||||
Дешёвые гейты и целевой AC7-смок — зелёные; тест по существу находки r3
|
||||
проверен на фальсифицируемость лично мной (не только принят на слово автора).
|
||||
|
||||
## 3. High / Medium — новые находки
|
||||
|
||||
Нет. Единственная блокирующая находка r3 (H1) закрыта по строке кода и
|
||||
подтверждена исполнением (см. §5).
|
||||
|
||||
## 4. Low
|
||||
|
||||
Нет новых.
|
||||
|
||||
## 5. Закрытие раунда r3
|
||||
|
||||
| Находка r3 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| **H1** — `src/space-render.ts:437`: Static-карточка не вырезает физический разрыв кладки под wall-hosted `passage` после миграции в v8 (`wallBodiesUnionPath` фильтровал по устаревшему `!opening.host`, который перестал быть верным предикатом с самого Stage 1) | Строка 437 приведена к тому же паттерну, что уже применён на строках 221/279 того же файла: `staticPassages.filter((opening) => opening.host?.kind !== 'partition')` — теперь и «нет host», и `host.kind==='wall'` попадают в список вырезов кладки, исключён только `host.kind==='partition'` (материализуется отдельно через `hostedCompositeOpenings`) | `src/space-render.ts:437` (коммит `f37efdad`); `demo/smoke_open_passage.mjs` усилен геометрической проверкой (`path.isPointInFill` по точке в центре прохода и по точке в сплошном участке стены) вместо проверки одного лишь присутствия DOM-узла — именно та проверка, отсутствие которой r3 назвал причиной, по которой дефект прежде проходил незамеченным. Проверено лично: на pre-fix HEAD (`fb6cc3ca`) с той же усиленной ассерцией смок падает (`staticCutsAndFillsPassage: false`), на `f37efdad` — проходит |
|
||||
|
||||
## 6. Унаследовано из r3
|
||||
|
||||
Дельта `95fa23ca..HEAD` не касается — принято на основании выводов
|
||||
`docs/reviews/CODE-REVIEW-282-r3.md` (HEAD на котором получен вывод —
|
||||
`95fa23ca79db830b201e82d9a34a05dcc3cecb29`), которая сама наследовала
|
||||
большую часть от r2/r1 (см. §6 документа r3):
|
||||
|
||||
- **Migration determinism/idempotence**, **backend-зеркало валидации**
|
||||
(unique-id, owner-count, dangling refs, edge-geometry parity,
|
||||
`_wall_catalog_projection`), **import/export remap**, **i18n-ключи**,
|
||||
**документация подсистемы** (`WALL-THICKNESS.md`, `CANVAS.md`,
|
||||
`USER-GUIDE.{ru,}.md`, `TESTING.md`), **`config-field-registry.mjs`**,
|
||||
**три `wall-identity-*` мутанта mutation-gate**, **lineage hints**,
|
||||
**off-grid guard** — вне дельты r3→r4, наследуется без переразбора.
|
||||
- **Guard-порядок #278**, **9 именованных structural-smoke**, **sun-rays после
|
||||
структурного редактирования**, **`additionalAuthoredPoints`**, **явный ноль
|
||||
толщины не воскресает**, **`wall_model_client_outdated` на реалистичном
|
||||
stale-client сценарии**, **AC7 для символа/материализации** проходов
|
||||
(`resolvedHosted`/`resolvedRawOpenings`) — файлы вне дельты r3→r4,
|
||||
наследуются из r3 §6/§7, которая сама перепроверила их исполнением на
|
||||
своём HEAD.
|
||||
- **Model invariants на реальной нагрузке** (`large-house`, 0% шума у узла до
|
||||
и после `commitWallSegmentModel`) — вне дельты, наследуется из r3 §7.
|
||||
- **CI-покрытие golden/performance/backend/hacs/hassfest на предыдущем HEAD**
|
||||
— наследуется из r3 §2/§7 и дополнительно переподтверждено собственным
|
||||
прогоном CI на новом точном SHA (см. §2 этого документа) — не голое
|
||||
наследование, а повторная проверка.
|
||||
|
||||
## 7. Что проверено и корректно (в этом раунде)
|
||||
|
||||
- Фикс не вводит двойного учёта: `hostedCompositeOpenings` (составные
|
||||
partition-стены) по-прежнему строится из `resolvedHosted`, отфильтрованного
|
||||
по `kind === 'partition'` (строка 221, не тронута) — пересечения множеств
|
||||
«wall-hosted passages» и «partition-hosted composite openings» нет.
|
||||
- Тип `OpeningHost = PartitionOpeningHost | WallOpeningHost` (`src/types.ts:198`)
|
||||
— ровно два варианта `kind`, поэтому `!== 'partition'` исчерпывающе и
|
||||
типобезопасно покрывает `'wall'` и `undefined` (нет host).
|
||||
- Трейлеры: оба коммита дельты несут `Issue: #282`; `f37efdad` — `User-Visible: yes`
|
||||
с правками в `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` в том же коммите
|
||||
(проверено `git show --stat f37efdad`).
|
||||
- «Одно число — один источник» — не применимо к этой дельте: правка не
|
||||
добавляет и не меняет видимую пользователю величину (число/подпись/площадь),
|
||||
только предикат включения объекта в список геометрических вырезов.
|
||||
- `docs/images/screenshots.json`: обновлён только `sourceFingerprint`/`sourceSha256`
|
||||
(пересчитан правильно, `check-docs` зелёный); `imageSha256` не менялся — реальные
|
||||
PNG не изменены (сценарии doc-скриншотов не задевают Static-карточку с
|
||||
wall-hosted проходом), лишних правок нет.
|
||||
- CI на точном SHA кандидата подтверждает то же самое независимо от локального
|
||||
прогона: `golden` и `performance_smoke` зелёные, несмотря на то что локальный
|
||||
`golden:verify` не запускался (см. §2) — не молчаливый пропуск, а гейт,
|
||||
пройденный другим путём.
|
||||
|
||||
## 8. Чего не проверял и почему
|
||||
|
||||
- **`golden:verify` локально** — поверхность правки (`houseplan-space-card`
|
||||
static-режим) не входит в `demo/golden/matrix.mjs`; CI `golden` job на
|
||||
точном SHA зелёный, это покрывает то немногое, что матрица вообще
|
||||
проверяет по соседству.
|
||||
- **`pytest tests_backend`, mutation-gate, model invariants** — вне дельты
|
||||
r3→r4 (см. §1), не требуются по методологии §2.10.
|
||||
- **Полный `performance_smoke` локально** — предрелизный гейт; CI на точном
|
||||
SHA зелёный.
|
||||
- **Полная матрица `demo/smoke_*.mjs` (190 файлов)** — инструмент подбора не
|
||||
нашёл ни прямых, ни слабых связей (изменённая строка без узнаваемого имени
|
||||
символа); решение по существу — прогнан только AC7-смок, прямо
|
||||
соответствующий содержанию находки r3, плюс он же на pre-fix коде для
|
||||
проверки фальсифицируемости. Остальные 189 смоков дельты не касаются: фикс
|
||||
меняет один булев предикат в одной функции одного файла (`renderSpaceStatic`),
|
||||
не тронутой ни одним другим смоком по имени или маршруту.
|
||||
|
||||
## 9. Резюме
|
||||
|
||||
Единственная блокирующая находка r3 закрыта ровно тем фиксом, который сам
|
||||
документ r3 предсказал («фикс структурно локален... не должен требовать
|
||||
полного повторного разбора подсистемы в r4»), и дополнительно проверено его
|
||||
собственное предостережение о скрытых эквивалентных фильтрах — таких не
|
||||
найдено. Тест, доказывающий AC7 для этого код-пути, усилен с DOM-присутствия
|
||||
до геометрической проверки формы пути и лично проверен на фальсифицируемость.
|
||||
Дешёвые гейты, целевой AC7-смок и CI на точном SHA — зелёные. Новых находок
|
||||
нет.
|
||||
|
||||
**Вердикт: зелёный.**
|
||||
Reference in New Issue
Block a user