mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 06:38:57 +00:00
docs: review document for #290
Validate / docs (push) Successful in 28s
Validate / process-workflow-sync (push) Successful in 36s
Validate / provenance (push) Successful in 40s
Validate / process-gate (push) Failing after 40s
Validate / changes (push) Successful in 37s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / reuse (push) Successful in 47s
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) Successful in 28s
Validate / process-workflow-sync (push) Successful in 36s
Validate / provenance (push) Successful in 40s
Validate / process-gate (push) Failing after 40s
Validate / changes (push) Successful in 37s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / reuse (push) Successful in 47s
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: #290 User-Visible: no
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# CODE-REVIEW-290-r4
|
||||
|
||||
- **Issue:** #290 — «Уступ в один шаг на общей стене создаётся молча и невидим при обычном зуме»
|
||||
- **Этап:** код-ревью (PROCESS.md §2.7)
|
||||
- **Заход:** r4 · блокирующих циклов израсходовано на входе 2 из 4
|
||||
- **Ветка:** `issue/290-near-axis-authoring-repair`
|
||||
- **HEAD на момент ревью:** `01512081db0d41cb86c921a61961275c8c18aedb`
|
||||
- **Предыдущий раунд:** r3, жёлтый, `docs/reviews/CODE-REVIEW-290-r3.md`,
|
||||
SHA на котором получен вердикт — `d33ae88da4049bdbdfd02c57f935199007157cf3`
|
||||
(назван в самом документе r3, раздел «HEAD на момент ревью» — в этот раз
|
||||
находки в процессе нет).
|
||||
|
||||
## Разбор по дельте (PROCESS.md §2.10) — почему сокращённый объём законен
|
||||
|
||||
Дельта: `git diff d33ae88d..HEAD` — **2 коммита, 2 файла, только классы C и B**:
|
||||
|
||||
```
|
||||
docs/reviews/CODE-REVIEW-290-r3.md | 218 ++++++++++++++++ (класс C, документ ревью r3)
|
||||
test/near-axis.test.mjs | 15 ++ (класс B, только новый тест)
|
||||
```
|
||||
|
||||
Ни одного файла класса A. `src/**` этим раундом не тронут вовсе — проверено
|
||||
`git diff --stat d33ae88d..HEAD -- src/`: пусто. Ветка полностью содержит
|
||||
`origin/dev` (`git merge-base --is-ancestor origin/dev HEAD` — true, `dev` не
|
||||
уходил вперёд после r3), контракт поведения не менялся, новая подсистема не
|
||||
задета, объём дельты (15 строк теста) многократно меньше исходной задачи.
|
||||
Ни одно из исключений §2.10 («ребейз на ушедший вперёд dev», «смена контракта»,
|
||||
«новая подсистема», «объём сопоставим с задачей») не применяется →
|
||||
разбор ограничен закрытием единственной находки r3 (M1) и дешёвыми гейтами,
|
||||
которые гоняются в любом раунде.
|
||||
|
||||
## Скоуп раунда
|
||||
|
||||
Единственная находка r3 (Medium M1, в скоупе задачи, жёлтый вердикт) требовала
|
||||
механического source guard на AC1: «Authoring, Optimize и renderer #279
|
||||
импортируют один threshold source; source guard запрещает отдельные литералы
|
||||
`0.25` в этих classifiers» (`docs/specs/290-near-axis-authoring-and-repair.md:173-174`).
|
||||
Автор выбрал вариант (а) из двух, предложенных r3: статический guard-тест,
|
||||
читающий исходники трёх потребителей как текст и требующий literal import +
|
||||
literal вызов/присваивание общего near-axis API, а не инлайн-константу.
|
||||
|
||||
## Закрытие раунда r3
|
||||
|
||||
| Находка | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| **M1** (Medium, в скоупе): AC1 обещает source guard против инлайн-литерала `0.25` в renderer/authoring/Optimize; такого guard'а не было — числовое равенство в `test/near-axis.test.mjs:23` не ловит дублирование значения, только его совпадение | Новый тест `#290 authoring, Optimize and renderer use one near-axis threshold source` (`test/near-axis.test.mjs:22-34`, коммит `01512081`) читает `src/wall-thickness.ts`, `src/houseplan-card.ts`, `src/plan-optimizer.ts` как текст и требует буквального `import … from './near-axis'` плюс использования соответствующего экспорта в каждом из трёх файлов | Воспроизвёл ровно ту же мутацию, что и r3: заменил в `src/wall-thickness.ts:85` импортированную ссылку на инлайн-литерал `= 0.25` (удалив зависимость от `NEAR_AXIS_MAX_DEGREES`) — новый guard-тест **краснеет** (`The input did not match the regular expression /import \{ NEAR_AXIS_MAX_DEGREES \} .../`). Дополнительно проверил ту же схему для двух других потребителей: убрал `import { snapNearAxisEndpoint } from './near-axis';` из `src/houseplan-card.ts` — тест краснеет; убрал `import { repairNearAxisRoomWalls } from './near-axis';` из `src/plan-optimizer.ts` — тест краснеет. После каждой мутации файл восстановлен, `git status --short` пуст, `npm test` снова зелёный (см. таблицу гейтов) |
|
||||
|
||||
Других находок в r3 не было (High:0, остальные Medium:0) — закрывать больше
|
||||
нечего.
|
||||
|
||||
## Как проверялось — гейты
|
||||
|
||||
| Гейт | Команда | Результат |
|
||||
|---|---|---|
|
||||
| Typecheck | `npx tsc --noEmit` | чисто, без ошибок |
|
||||
| Unit (полный, дешёвый гейт гоняется в любом раунде) | `npm test` | 1235 тестов: 1234 passed, 1 skipped, 0 failed (на 1 больше, чем в r3 — новый guard-тест); подтверждено `npm run inventory` (Node unit: 1235) |
|
||||
| Build + сверка копий бандла | `npm run build`; `diff dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js`; `git status --short` | пересобранный `dist` побайтово идентичен закоммиченному и копии в `custom_components`; `git status` после пересборки чист — рабочая копия не разошлась с закоммиченными артефактами |
|
||||
| Дисциплина «тест умеет падать» — M1 (renderer) | откат `src/wall-thickness.ts:85` к инлайн-литералу `0.25` без импорта, `npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs && node --test --test-name-pattern="#290 authoring, Optimize and renderer..." test/near-axis.test.mjs` | тест краснеет (regex import не совпал); после отката файла — снова зелёный, `git status` чист |
|
||||
| Дисциплина «тест умеет падать» — M1 (authoring) | тот же приём для `import { snapNearAxisEndpoint } from './near-axis';` в `src/houseplan-card.ts` | тест краснеет; откат — зелёный |
|
||||
| Дисциплина «тест умеет падать» — M1 (Optimize) | тот же приём для `import { repairNearAxisRoomWalls } from './near-axis';` в `src/plan-optimizer.ts` | тест краснеет; откат — зелёный |
|
||||
| Smoke-select по дельте раунда | `node scripts/smoke-select.mjs --base d33ae88d --head HEAD` | «Исполняемого frontend-диффа нет (src/**/*.ts не тронут). Browser-smoke этим диффом не выбираются — выбирать нечего» — согласуется с тем, что дельта не трогает `src/**` |
|
||||
| Docs fingerprint | не перезапускал | не требуется этим раундом: `src/**` дельтой не тронут (см. «Разбор по дельте»); последний прогон — r3, «Documentation checks passed (7 files, 10 external links)», наследуется |
|
||||
| Инварианты геометрии | не перезапускал | не требуется: дельта не трогает геометрию/`layout`/`marker.space`/`open_spans`; последний прогон — r3, код 0 на обоих real-plan фикстурах, наследуется |
|
||||
| Golden | не перезапускал | не требуется: дельта не меняет рендер/UI; последний прогон — r3, 161/161 passed, наследуется |
|
||||
| Backend pytest | не запускал | `git diff --stat d33ae88d..HEAD -- 'custom_components/**/*.py'` пуст |
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. High: 0, Medium: 0.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- **M1 закрыт по существу, не только по факту существования теста** — три
|
||||
прямые мутации (см. таблицу гейтов) доказывают, что guard действительно
|
||||
ловит инлайн-литерал в каждом из трёх названных AC1 потребителей
|
||||
(`wall-thickness.ts`, `houseplan-card.ts`, `plan-optimizer.ts`), а не только
|
||||
в одном из них.
|
||||
- **Guard читает исходник, а не собранный бандл** — `sourceOf()`
|
||||
(`test/near-axis.test.mjs:20`) делает `readFileSync` из `src/*.ts` напрямую,
|
||||
минуя `test-build/`; расхождение между исходником и типизированной сборкой
|
||||
тест не маскирует.
|
||||
- **Регекс на вызов, а не только на импорт** — `assert.match(authoring,
|
||||
/snapNearAxisEndpoint\(/)` и `assert.match(optimizer,
|
||||
/repairNearAxisRoomWalls\(space\)/)` отдельно требуют реального использования
|
||||
импортированного символа, а не только присутствия строки импорта (мёртвый
|
||||
импорт не прошёл бы эту часть проверки).
|
||||
- **Трейлеры и класс изменения** — `01512081` (`test: enforce shared near-axis
|
||||
threshold source`) несёт `Issue: #290`, `User-Visible: no`; правильно, это
|
||||
чисто тестовый файл (`test/**`, класс B), продуктовое поведение не менялось,
|
||||
changelog не требуется.
|
||||
- **Дерево не расходится с гейтами** — до, во время и после всех мутационных
|
||||
проверок `git status --short` оставался чист; финальная пересборка `dist`
|
||||
побайтово совпадает с обеими закоммиченными копиями.
|
||||
- **AC2–AC10, H1-регрессия r1, mutation-gate ×6, golden, инварианты, single
|
||||
source of numbers, совместимость, performance** — не пересматривались в этом
|
||||
раунде: дельта их не задевает (см. «Разбор по дельте»), полностью
|
||||
унаследованы из r3 (раздел ниже), который сам разобрал их читая весь
|
||||
`origin/dev...HEAD` (а не по дельте) из-за промежуточного ребейза.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- **`node scripts/check-docs.mjs`, `npm run invariants`, `npm run
|
||||
golden:verify`, полный `mutation-gate`, touch-смоки, `pytest tests_backend`**
|
||||
— не перезапускал в этом раунде; все они не выбираются ни диффом (`src/**`
|
||||
не тронут), ни AC, задетым этой дельтой (только AC1/source guard). Их
|
||||
последние зелёные прогоны — в r3, см. таблицу гейтов там и «Унаследовано»
|
||||
ниже.
|
||||
- **Внешний Linux CI Validate на точном HEAD `01512081`** — не проверял
|
||||
напрямую; последняя подтверждённая владельцем ссылка (Validate 32733382537)
|
||||
относится к SHA `d33ae88d`, до этого раунда. Пересборка/тесты локально
|
||||
воспроизводят зелёное состояние, но отдельного прогона CI на новом HEAD в
|
||||
комментариях issue не найдено на момент ревью.
|
||||
- **Комментарий-хендофф автора после r3** (issue #290, id `5396316118`,
|
||||
2026-08-24T14:03:02Z) обрывается на полуслове: «Исправление Medium M1 из
|
||||
code review r3 запушено в \» — SHA коммита-фикса в нём не назван. Это не
|
||||
влияет на вердикт: коммит независимо идентифицирован через `git log
|
||||
d33ae88d..HEAD` (`01512081`, единственный коммит с продуктовым/тестовым
|
||||
содержимым в дельте) и проверен напрямую, а не со слов автора. Отмечаю как
|
||||
находку процесса, не как находку кода — вердикт не снижается, править
|
||||
нечего в этой ветке.
|
||||
|
||||
## Унаследовано из r3
|
||||
|
||||
Документ: `docs/reviews/CODE-REVIEW-290-r3.md`, SHA `d33ae88da4049bdbdfd02c57f935199007157cf3`
|
||||
(назван в самом документе r3). Принято без повторной проверки в этом раунде,
|
||||
так как дельта `d33ae88d..HEAD` их не задевает:
|
||||
|
||||
- **AC1 (кроме source guard), AC2–AC10** — весь предметный разбор по коду
|
||||
(`src/near-axis.ts`, `src/houseplan-card.ts`, `src/resize.ts`,
|
||||
`src/plan-optimizer.ts`, `src/wall-thickness.ts`,
|
||||
`scripts/model-invariants.mjs`) — r3 прочитал и перепроверил их **полностью**
|
||||
(не по дельте относительно r2, а заново, из-за промежуточного ребейза на
|
||||
ушедший вперёд `dev`), включая прямой откат H1-регрессии r1 и все 6
|
||||
обязательных mutation-gate ID индивидуально.
|
||||
- **Golden (161/161 сценариев)**, **docs fingerprint** (7 файлов, 10 внешних
|
||||
ссылок), **near-axis профиль на обоих real-plan фикстурах** (`--near-axis`
|
||||
CLI), **bundle parity на момент r3** — гоняны и зафиксированы в r3, дельта
|
||||
этого раунда не меняет ни один из задействованных там файлов.
|
||||
- **Продуктовые решения владельца** (авто-выравнивание без modifier bypass,
|
||||
подтверждаемый lossy-пас Optimize с отчётом/Undo, единый допуск `0.25°`) —
|
||||
зафиксированы на этапе ТЗ (`SPEC-REVIEW-290-r2`, зелёный, `dc9f9a6c`) и не
|
||||
относятся к коду; ребейз и текущая дельта их не касаются.
|
||||
- **Backend** — `custom_components/**/*.py` не менялся ни в r3, ни в этой
|
||||
дельте; `pytest tests_backend` по-прежнему не требуется.
|
||||
|
||||
## Вывод
|
||||
|
||||
Единственная находка предыдущего раунда (M1) закрыта и подтверждена прямой
|
||||
мутацией на всех трёх названных в AC1 потребителях, а не только заявлением
|
||||
автора. Новых находок дельта не создаёт. Дешёвые гейты (`tsc`, `npm test`,
|
||||
`build` + сверка бандла) зелёные на текущем HEAD. High: 0, Medium: 0 →
|
||||
**зелёный вердикт**.
|
||||
Reference in New Issue
Block a user