15 KiB
CODE-REVIEW-461-r2
- Issue: https://github.com/Matysh/houseplan-card/issues/461
- ТЗ:
docs/specs/461-wall-draw-click-performance.md(SPEC-REVIEW-461-r1, зелёный) - Материал: SHA
41e6eef941c29675095365b472e063ff1caa8482, веткаissue/461-wall-draw-click-performance, диапазонorigin/dev..HEAD= 6 коммитов (добавились13ab4b12— публикация документа r1,41e6eef9— исправление M1). - Заход: r2 · блокирующих циклов израсходовано 1 из 4
- Вердикт: зелёный
Скоуп ревью (дельта, не с нуля)
Предыдущий раунд (r1) получил жёлтый вердикт на SHA 34d53bf2 — единственная
находка M1 (Medium, в скоупе): AC4 требовал parity-свидетеля fast/full на
матрице §8 (10 пунктов ТЗ), а тестами была покрыта только часть матрицы.
Документ: docs/reviews/CODE-REVIEW-461-r1.md.
Дельта между 34d53bf2 и текущим HEAD (git diff 34d53bf2..HEAD --name-only):
docs/reviews/CODE-REVIEW-461-r1.md (публикация документа r1 конвейером, не автор)
test/draft-live-preflight.test.mjs (+89 строк, новый test-case, коммит 41e6eef9)
Это ровно фикс M1 и ничего сверх него — src/**, demo/**, scripts/**,
.github/**, changelog не тронуты. Коммит 41e6eef9 несёт Issue: #461,
User-Visible: no (корректно: чисто тестовое изменение, видимого поведения
нет). Ребейза на ушедший вперёд dev не было, контракт поведения не менялся,
новая подсистема не задета — дельта локальна, разбор веду по ней, а не заново.
Остальные 10 AC (AC1–AC3, AC5–AC12) не имеют отношения к этой дельте и
наследуются из r1 без повторной проверки (раздел ниже).
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
M1 — AC4: матрица §8 не проверена ни одним тестом через новый путь; фикс — repräsentативное подмножество (границы 14°/15°, 19/20 см, 4/5 см, valence 6/7) через реальные junctionLimitViolations/increasedViolations на local vs full candidate |
Новый тест test/draft-live-preflight.test.mjs:184 '#461 local and full junction verdicts agree at every limit boundary' (коммит 41e6eef9) |
8 сценариев (по одному на каждую сторону границы), для каждого: строит полный previous/candidate (с активным draft и валидной удалённой геометрией через partitions: [..., remote]), проецирует обе стороны через draftLiveCandidateSpace, сравнивает introducedRules(local) с introducedRules(full) (assert.deepEqual), проверяет нормативный ожидаемый verdict (['angle']/['length']/['distance']/['valence']/[]) и что remote-партиция не попала в bounded projection |
Проверил, что это не бумажный тест, а свидетель, который умеет падать: временно
понизил MIN_JUNCTION_ANGLE_DEG с 15 на 10 в src/junction-limits.ts,
пересобрал test-build (npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs) и прогнал файл целиком —
'14 degree junction is rejected: boundary verdict' покраснел
(+ [] / - ['angle']), остальные 7 сценариев остались зелёными. Откатил
правку (git checkout -- src/junction-limits.ts), пересобрал test-build,
дерево снова чистое (git status --porcelain пусто).
Проверил, что тест использует настоящий production-путь, а не параллельную
реализацию: _junctionLimitsIntroduced (src/houseplan-editor-runtime.ts:2070)
вызывает _junctionLimitViolations (2049), который оборачивает тот же самый
junctionLimitViolations из src/junction-limits.ts, а затем
increasedViolations (2126) — ровно те две функции, что тест импортирует
напрямую из test-build/junction-limits.js и вызывает с той же сигнатурой
(config, spaceId, segments, sharedGeometry, roomIds). Локальный helper
limitSegments() в тесте воспроизводит _limitSegmentsOf
(houseplan-editor-runtime.ts:2020) построчно (wall_segments + partitions +
room_drafts.flatMap на пары точек) — форма и порядок совпадают на
корректных фикстурах.
Требование r1 было явно сформулировано как «хотя бы репрезентативное
подмножество матрицы §8, в первую очередь четыре границы» — потому что
остальные 6 пунктов матрицы (intersection room/partition/foreign draft/column, wall-degraded-extra, hosted opening, zero wall,
malformed carrier) это по сути «объект есть/объекта нет», а не «поведение
проектора у существующей числовой границы», и они уже были свидетельствованы
существующими тестами 'retains interacting geometry and drops remote work'
(test/draft-live-preflight.test.mjs:101) и
'malformed local geometry fails closed into the proof' (255) —
неизменными в этой дельте. Фикс закрывает именно то, что было названо
условием закрытия, не больше и не меньше — сверка со спекой (docs/specs/461-*.md:223-238,
раздел §8) подтверждает список из 10 пунктов совпадает буквально с текстом
находки M1.
M1 закрыта. Других находок r1 не было (High: 0, Medium: 1 — закрыт, Low: 1 — L1, снят автором в r1 без правки, дельта его не касается).
Унаследовано из r1
Без повторной проверки принимаю из docs/reviews/CODE-REVIEW-461-r1.md
(материал 34d53bf2d1b9252e37b356c1a295b1bcab7865f9), поскольку дельта r2 их
не задевает:
- AC1, AC2 — единственная точка изменения (
_persistActiveDraftSegment,houseplan-editor-runtime.ts:2795), route guardisSingleDraftAppend, доказаноdemo/benchmark_wall_draw_click.mjsиtest/draft-live-preflight.test.mjs. - AC3 — pure local projector: не мутирует
space, сохраняет неизвестные поля, реальная толщина при отборе, итеративное закрытие collinear run и junction rays, fail-closed на malformed. - AC5 — переиспользование wall-артефакта между local proof и junction
proof, мутант
wall-draw-wall-artifact-discarded. - AC6 — rollback до
beforeпри отказе, смок + мутантwall-draw-rejection-rollback-skipped. - AC7 — независимый full-space preflight на terminal finish, мутант
wall-draw-terminal-full-check-skipped. - AC8 — регрессия одиннадцати существующих
_markupClick-смоков через единственный call site; Validate на34d53bf2зелёный по всем трём шардам. - AC9 — perf-профиль
wall-draw-click-v1: structural + timing (median 10.9 мс / max 13.8 мс / remote 16.7 мс против бюджетов 150/250/~36.3 мс); числа не перепроверялись повторно и в r1 (нет Chromium под рукой), доверие к структуре ассертов, прочитанных построчно. - AC10 — tsc/test/build/no-new-any: были зелёными на
34d53bf2(Validate https://github.com/Matysh/houseplan-card/actions/runs/33962804004); для r2 я перегнал их заново на текущемHEAD(см. «Как проверялось» ниже) — дельта их косвенно затрагивает (новый тестовый файл компилируется черезtsc -p tsconfig.test.json), поэтому это не чистое наследование, а подтверждение. - AC11 — golden/screenshots:
docs/images/screenshots.json, все 10imageSha256идентичныdev, изменился толькоsourceFingerprintна34d53bf2; дельта r2 не трогаетsrc/**, снимок не может устареть повторно. - AC12 — оба changelog, ARCHITECTURE, CONFIG-COMPATIBILITY обновлены в
04a1de09(User-Visible: yes); дельта r2 не меняет пользовательское поведение (User-Visible: noна41e6eef9), новых записей не требуется. - L1 (§6.4 vs
!safehandling вdraft-live-commit.ts) — снят автором в r1 без правки, обоснование (совпадает с конвенциейhouseplan-editor-runtime.ts:1846-1854) дельтой не затронуто.
Как проверялось (r2)
Зелёного Validate на 41e6eef9 не найдено на момент ревью — прогнал дешёвые
гейты сам, они минуты:
| Гейт | Прогнал сам | Результат |
|---|---|---|
npx tsc --noEmit |
да | exit 0, без вывода |
npm test |
да | tsc -p tsconfig.test.json + node --test test/*.test.mjs: 1996 pass, 0 fail, 1 skip (1997 всего) — совпадает с заявленным автором числом в комментарии-фиксе; новый тест '#461 local and full junction verdicts agree at every limit boundary' — в списке, зелёный |
npm run build + сверка 3 копий бандла |
да | tsc --noEmit && rollup -c — success; diff -rq dist/ custom_components/houseplan/frontend/ — пусто (байт-в-байт); git status --porcelain после build — пусто (дельта не меняет бандл) |
node scripts/no-new-any.mjs |
да | «Новых any нет» (560 добавленных строк в 3 файлах — число из полного диапазона origin/dev..HEAD, не только дельты r2) |
node scripts/check-docs.mjs |
да | «Documentation checks passed» — дельта r2 не трогает src/**, отпечаток скриншотов устареть повторно не мог |
node scripts/smoke-select.mjs --base 34d53bf2 --head HEAD |
да | «Исполняемого frontend-диффа нет (src/**/*.ts не тронут). Browser-smoke этим диффом не выбираются — выбирать нечего»; тронуто файлов: 2 |
| Мутационная проверка «тест умеет падать» | да | вручную занизил MIN_JUNCTION_ANGLE_DEG 15→10 в src/junction-limits.ts, пересобрал test-build, новый тест покраснел ровно на ожидаемом сценарии (14 degree junction is rejected), остальные 7 сценариев не задеты; откатил правку и test-build |
node scripts/model-invariants.mjs |
нет | дельта r2 не трогает ни один файл геометрии/записи модели (только тест и review-doc); риск рассинхронизации ключей толщины/решётки не создаётся ни этой дельтой, ни задачей в целом (см. наследование, r1 уже это установил для полного diff) |
python -m pytest tests_backend -q |
нет | дельта и весь diff не трогают custom_components/**/*.py |
| Targeted/full browser smoke | нет | smoke-select.mjs на дельте прямо говорит «выбирать нечего» — дельта r2 не пересобирает бандл и не меняет исполняемый путь; полный набор — предрелизный гейт, не гейт ревью |
npm run golden:verify |
нет | дельта r2 не может изменить пиксель — не трогает src/**, demo/**, стили |
Мутанты scripts/mutation-gate.mjs |
нет | дельта их не трогает (не менялись после r1) |
Находки
Нет находок в этом раунде. High: 0, Medium: 0.
Чего не проверял
- Не воспроизводил числа
npm run benchmark:wall-draw-clickв браузере ни в r1, ни в r2 — дельта r2 их не касается (не трогает perf-профиль). - Не гонял
python -m pytest tests_backend— ни разу за обе итерации, diff никогда не касалсяcustom_components/**/*.py. - Не гонял
node scripts/model-invariants.mjsповторно — обоснование (диф не меняет функции записи геометрии) установлено в r1 для полного diff и остаётся верным: дельта r2 добавляет только чтение production функций в тесте, не меняет их. - Не прогонял browser smoke (targeted или полный) — инструмент
smoke-select.mjsна дельте34d53bf2..HEADпрямо сообщает, что исполняемого frontend-диффа нет и выбирать нечего; полный набор — гейт предрелиза, а не код-ревью соразмерного объёма для тестового патча на 89 строк.
Материал раунда
- Ветка:
issue/461-wall-draw-click-performance, коммит41e6eef941c2— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
3185737736d19e808ba8b85dcfc99b6265c177d5git log --all --format='%H %T' | grep 3185737736d1 - ТЗ
docs/specs/461-wall-draw-click-performance.md, блобccf374b1c0797ace0156b7cfb366007f1271fd35git log --all --find-object=ccf374b1c0797ace0156b7cfb366007f1271fd35 -- docs/specs/461-wall-draw-click-performance.md