Files
houseplan-card/docs/reviews/CODE-REVIEW-278-r2.md
T
claude[bot] bb81ede47c
Validate / docs (push) Failing after 31s
Validate / process-workflow-sync (push) Successful in 31s
Validate / provenance (push) Successful in 37s
Validate / process-gate (push) Failing after 38s
Validate / changes (push) Successful in 35s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / reuse (push) Successful in 48s
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 #278
Issue: #278
User-Visible: no
2026-08-24 06:35:58 +00:00

159 lines
13 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-278-r2
- **Issue:** https://github.com/Matysh/houseplan-card/issues/278
- **Этап:** код-ревью, заход r2, блокирующих циклов израсходовано 1/4 (потрачен r1 — жёлтый вердикт; зелёный вердикт бюджет не тратит, #227)
- **Проверяемый диапазон:** дельта `49504379..79285ab1` (r1 SHA `495043791e0fa916708f832248f13dfacf23dbdc` → HEAD `79285ab1d2f3b413a7fa54fb77ff47dd9dbfb2cd`), ветка `issue/278-wall-union-isolation`
- **Спецификация:** `docs/specs/278-wall-union-isolation.md` (зелёное ревью ТЗ, r2)
- **Вердикт:** зелёный · High: 0 · Medium: 0
## Скоуп раунда
r1 (`docs/reviews/CODE-REVIEW-278-r1.md`) вернул жёлтый вердикт с единственной
Medium-находкой M1: `docs/TESTING.md` называл 4 из 5 mutation-id для чек-листа
#278 неточно (несовпадение с реестром `scripts/mutation-gate.mjs`), что делало
канонический тест-чеклист нечитаемым машиной и вводящим в заблуждение
человеком — нарушение AC15.
Дельта r1→r2 — ровно два коммита:
- `c123757f` — публикация документа `CODE-REVIEW-278-r1.md` (инфраструктурный
шаг конвейера, класс C, не авторский код);
- `79285ab1` — правка автора: 4 неточных id в `docs/TESTING.md` заменены на
точные имена реестра.
Продуктовый код (`src/**`), тесты, фикстуры, golden-эталоны, backend — не
затронуты. Дельта строго локальна: `git diff --stat 49504379..79285ab1`
показывает изменения только в `docs/TESTING.md` (6 строк) и в самом
опубликованном документе ревью. `dev` не ушёл вперёд между раундами
(`origin/dev` — предок HEAD, ребейза не было), новая подсистема не задета,
контракт поведения не менялся. Основание для полного разбора (§2.10) —
ребейз, смена контракта, новая подсистема, сопоставимый с задачей объём —
отсутствует. Объём разбора этого раунда сокращён до дельты и AC15, которую
она задевает.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| **M1** — `docs/TESTING.md` называет 4 из 5 mutation-id неточно (`isolated-wall-extra-discarded`, `strict-accepts-degraded`, `wall-thickness-writer-bypasses-barrier`, `invariants-bypasses-production-geometry` — не совпадают с реестром) | Коммит `79285ab1` заменяет все 4 id на точные имена: `wall-isolated-extra-discarded`, `strict-wall-barrier-accepts-degraded`, `wall-thickness-writer-bypasses-common-barrier`, `model-invariants-bypasses-production-geometry` | `git show 79285ab1 -- docs/TESTING.md`; лично сверено построчно с выводом `node scripts/mutation-gate.mjs --list` — все 5 id чек-листа (включая ранее верный `wall-component-failure-kills-primary`) присутствуют в реестре дословно, без допусков |
## Унаследовано из r1
Без повторной проверки — техническая часть контракта и все AC, доказательство
которых дельта не задевает — принято по выводу `docs/reviews/CODE-REVIEW-278-r1.md`
на SHA `495043791e0fa916708f832248f13dfacf23dbdc`:
- типизированный structural result (`ok`/`degraded-extra`/`failed-core`/
`not-applicable`), per-extra transactional изоляция, `components[]` —
AC1–AC3;
- render-safe проекция и parity потребителей (Plan/View, Static, hidden Iso,
Glow/light barrier, sun) — AC4–AC5;
- единый strict commit barrier для всех geometry writers, откат, 0 WS/Undo
при отказе, toast — AC6–AC9;
- production model-invariants на реальной команде (плохая/валидная фикстура)
— AC10;
- регрессии #197/junction/fail-dark — AC11;
- реестр 5 mutation-id целостен и один живьём воспроизведён (`--check`,
ручной мутант `degraded-extra`→`failed-core` ломает
`smoke_wall_union_isolation.mjs`) — AC12 (частично, как и в r1: 4 из 5
подтверждены чтением, не прогоном `--id=`, см. «Чего не проверял» ниже);
- performance-бюджеты §13 — AC13;
- зелёные tsc/test/build/bundle-сверка/смоки на SHA r1, полный `golden:verify`
(108/108) — AC14;
- CHANGELOG RU/EN, USER-GUIDE RU/EN, WALL-THICKNESS.md, ARCHITECTURE.md,
CANVAS.md, STATUS.md — точны, терминология соответствует
`docs/USER-GUIDE.ru.md` — часть AC15, не связанная с `TESTING.md`.
Эти выводы не переоценивались заново в r2: дельта их доказательства не
задевает (ни один изменённый байт не лежит в `src/**`, тестах или фикстурах).
## Как проверялось в r2
Дешёвые гейты прогнаны заново (§2.10: они гоняются в каждом раунде, код
изменился и стоят минуты):
| Гейт | Команда | Результат |
|---|---|---|
| Typecheck | `npx tsc --noEmit` | зелёный, без вывода |
| Unit | `npm test` | 1204/1204 pass, 0 fail, 0 skip |
| Build + 3 копии бандла | `npm run build && npm run bundle:sync` + `cmp` `dist/`, `custom_components/houseplan/frontend/`, `demo/srv/assets/` | все три побайтово идентичны; `git status --porcelain` чист после сборки |
| Docs fingerprint | `node scripts/check-docs.mjs` | «Documentation checks passed (7 files, 10 external links)» (диф не трогает `src/**`, гейт не обязателен, но дешёвый — прогнан) |
| Точечная проверка M1 | `node scripts/mutation-gate.mjs --list` + построчная сверка с `docs/TESTING.md` | все 5 id AC15-чек-листа совпадают дословно |
| `smoke-select.mjs` по дельте | `node scripts/smoke-select.mjs --base 49504379 --head HEAD` | «Исполняемого frontend-диффа нет… Browser-smoke этим диффом не выбираются» — выбирать нечего, диф не трогает `src/**`, тесты и фикстуры |
| Commit-трейлеры | `git show -s --format="%B" 79285ab1` | `Issue: #278`, `User-Visible: no` — корректно: чистая правка документации для разработчиков, не меняющая пользовательское поведение, changelog не требуется |
| Ребейз/дрейф `dev` | `git merge-base --is-ancestor origin/dev 79285ab1` | true — `dev` не ушёл вперёд между раундами, полный разбор по этому основанию не требуется |
Не запускались повторно (не требуется дельтой и уже пройдены на r1 без
изменений с тех пор): `npm run invariants`, `smoke_wall_union_isolation.mjs`
и соседние geometry-смоки, `benchmark_wall_union_isolation.mjs`,
`npm run golden:verify`, `python -m pytest tests_backend` (backend не
затронут ни разу за весь диапазон #278), `mutation-gate.mjs --id=` живой
прогон — дельта не касается `src/**`, тестов, фикстур или golden-эталонов, а
значит не может изменить их результат.
## Находки
Нет. M1 закрыта точно (см. таблицу выше), новых находок делта не порождает —
изменение состоит из четырёх строковых замен id, каждая сверена дословно с
реестром.
## Проверка AC
AC1–AC14 и часть AC15 (changelog/user/architecture/wall-thickness/canvas/status
docs) — унаследованы из r1 без повторной проверки, дельта их не задевает (см.
«Унаследовано из r1»).
AC15 в части `docs/TESTING.md` — перепроверена заново в этом раунде: ✅.
`docs/TESTING.md` теперь называет для чек-листа #278 ровно те 5 mutation-id,
что существуют в `scripts/mutation-gate.mjs` (сверено `--list`, дословное
совпадение строк, без опечаток и без допуска на разницу в написании).
## «Одно число — один источник»
Дельта не вводит и не меняет ни одной пользовательской величины: правка —
только в id-строках внутреннего тест-чеклиста для разработчиков
(`docs/TESTING.md`), не в пользовательском UI и не в changelog. Правило не
применимо к этой дельте.
## Что проверено и корректно
- Все 4 замены в `docs/TESTING.md` — точные, посимвольно совпадают с именами
в живом реестре `scripts/mutation-gate.mjs --list`, включая ранее верный
5-й id `wall-component-failure-kills-primary` (не тронут, и не должен был).
- Коммит `79285ab1` несёт корректные трейлеры (`Issue: #278`,
`User-Visible: no`) и не расширяет скоуп: единственный тронутый файл —
`docs/TESTING.md`, ровно тот, что назвала находка M1.
- Дешёвые гейты (tsc/test/build/bundle-сверка) зелёные на итоговом HEAD
`79285ab1`, что подтверждает: правка документации не сломала ничего в
продуктовом коде (ожидаемо, поскольку `src/**` не тронут, но проверено, а
не предположено).
- `dev` не сдвинулся между r1 и r2 — снований для полного разбора вместо
разбора по дельте (§2.10) нет.
## Чего не проверял
- Не прогонялся живой `mutation-gate.mjs --id=<mutant>` ни для одного из 5
id — не требуется этим раундом: сами мутанты в `scripts/mutation-gate.mjs`
не менялись (дельта их не касается), их поведение проверено в r1
(`wall-component-failure-kills-primary` — вручную и живьём, реестр —
`--check`); данный раунд правит только текст `docs/TESTING.md`, ссылающийся
на уже проверенные id.
- Не переигрывались `npm run invariants`, browser-смоки, `benchmark_*`,
`golden:verify` — дельта не содержит изменений в `src/**`, тестах,
фикстурах или golden-эталонах, поэтому их результат не может отличаться от
r1; `smoke-select.mjs` по дельте `49504379..HEAD` подтверждает это
формально («Исполняемого frontend-диффа нет»).
- `python -m pytest tests_backend` не запускался — весь диапазон #278 (не
только эта дельта) не трогает `custom_components/houseplan/**/*.py`.
- PNG golden-эталонов не пересматривались повторно — не создавались и не
менялись в этой дельте; визуальная приёмка была выполнена и задокументирована
в r1.
## Итог
Единственная находка r1 (M1) закрыта точно и полно: все 4 неточных
mutation-id заменены на дословно совпадающие с реестром имена, дешёвые гейты
зелёные, трейлеры корректны, скоуп не расширен. Дельта строго локальна,
`dev` не ушёл вперёд, оснований для полного разбора нет. Blocking (High)
находок нет, Medium-находок нет. Задача готова к слиянию.