From 4241bb56f8c0902994afb1d8dd8b210cc708626e Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 22 Aug 2026 17:15:50 +0000 Subject: [PATCH] docs: review document for #242 Issue: #242 User-Visible: no --- docs/reviews/SPEC-REVIEW-242-r1.md | 185 +++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-242-r1.md diff --git a/docs/reviews/SPEC-REVIEW-242-r1.md b/docs/reviews/SPEC-REVIEW-242-r1.md new file mode 100644 index 00000000..37039336 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-242-r1.md @@ -0,0 +1,185 @@ +# SPEC-REVIEW-242-r1 + +- Issue: [#242](https://github.com/Matysh/houseplan-card/issues/242) — «Проём в толстой стене рисуется у произвольной грани, а не по центру толщины» +- Этап: ТЗ на ревью (PROCESS.md §2.4) +- Артефакт ТЗ: `docs/specs/242-opening-symbol-center.md`, ревизия `0033138` +- Ветка: `issue/242-opening-symbol-center` +- Заход: **r1**, блокирующих циклов израсходовано **0 из 4** (лимит обычного трека — 4, §4) +- Вердикт: **зелёный** + +## Скоуп ревью + +Первый заход — полный разбор ТЗ, без ограничения по дельте (§2.10 применяется +только со второго захода). + +Проверялось: + +1. Соответствие обязательным разделам §7.1 PROCESS.md. +2. Продуктовая рамка — принадлежность задачи job'ам из `docs/SCOPE.md`. +3. Верность диагноза — сверка цитируемого кода с текущим `HEAD` (та же + ревизия, на которой ТЗ написано). +4. Проверяемость и однозначность AC1…AC8. +5. Отсутствие догадок, выданных за факт (решения без пометки, что это + предположение автора, а не решение владельца). +6. Совпадение зафиксированных в ТЗ product-решений (§4) с ответами владельца в + комментариях issue (Q1–Q4). +7. Техническая осуществимость геометрического контракта (§7 ТЗ) — не + декларация ли это того, что текущая модель данных не может обеспечить. +8. Термины интерфейса — сверка с `docs/USER-GUIDE.ru.md`, а не изобретённые. +9. Полнота списка канонических документов, которые придётся обновить. + +## Как проверялось + +- Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md`, тело issue #242 и все + 5 комментариев (аналитика → занятие → вопросы владельцу → решения владельца + → готовое ТЗ). +- Прочитан `docs/specs/242-opening-symbol-center.md` целиком. +- Прочитаны канонические `docs/WALL-THICKNESS.md` и `docs/ISOMETRIC.md`. +- В `docs/USER-GUIDE.ru.md` найден и прочитан раздел «Толстые стены» + (строки 606–616) и таблица «Настройки проёма» (568–575) — источник + интерфейсной терминологии, которую ТЗ обязано использовать без изменений. +- Прочитан код, на который ссылается диагноз ТЗ, чтобы отделить проверенный + факт от догадки: + - `src/wall-thickness.ts` — `OpeningWallSide`, `resolveOpeningWallAssociation`, + `openingInnerFaceOffsetFromIndex` (строки ~2340–2530); + - `src/partition-openings.ts` — `partitionOpeningFace` (153–165); + - `src/render/opening-symbol.ts` — `openingVisibleMetrics`, + `renderOpeningVisibleGeometry` (1–147); + - `src/houseplan-card.ts` — рендер `op-hit`/`op-outline` (18530–18588) и + позиционирование lock-бейджа (18590–18618). +- Продуктовый код и ТЗ не редактировались — ревьюер только читает. + +Гейты для этапа ТЗ не запускались: PROCESS.md §8 требует их на код-ревью, а +здесь нет ни строчки кода. Автор уже отчитался о `node scripts/check-docs.mjs` +для diff'а этого захода (только `docs/specs/**`), что достаточно для этой +стадии. + +## Находки + +Нет. Ни одной High, Medium или Low. + +## Что проверено и признано корректным + +**Структура ТЗ (§7.1).** Все обязательные разделы на месте: сценарий и +персона (§1), что человек увидит до/после (§2), диагноз/проблема (§3), +скоуп и не-скоуп (§6), контракт поведения (§7–8), данные/миграция/i18n/a11y/ +touch (§9), перф и безопасность (§10), AC1…AC8 с доказательством (§11), план +автотестов (§12), mutation guards (§13), гейты (§14), release-артефакты +(§15), откат (§16), риски (§17), явный блок принятых технических +предположений (§18). Ничего не подменяет продуктовый вопрос техническим и +наоборот. + +**Продуктовая рамка.** Задача закрывает J4 («от нуля до плана без внешнего +редактора» — точность геометрии) и J6 («план остаётся достоверным при +эволюции комнат» — независимость от порядка `space.rooms`); во View +дополнительно поддерживает J1 (одинаковое чтение геометрии независимо от +внутреннего порядка данных), как и написано в аналитике issue. Ни одна +строка `docs/SCOPE.md` не нарушается, новых поверхностей продукта не +добавляется. + +**Диагноз подтверждён чтением, а не поверил автору на слово.** Прочитанный +код на актуальном `HEAD` (`0033138`, тот же коммит, на котором писалось ТЗ) +подтверждает каждое утверждение §3 ТЗ: +- `openingInnerFaceOffsetFromIndex` действительно сортирует кандидатов по + `order` — полю, комментарий к которому в коде прямо называет его + «first matching room edge in config order» (wall-thickness.ts:2355) — и + берёт `available[0]` как «natural» грань (2513–2520); +- `partitionOpeningFace` действительно фиксирует знак `side` от `flipV` и + умножает его на `resolved.axis` — направление, которое зависит от того, как + сохранены `partition.a`/`partition.b` (partition-openings.ts:157–164); +- `renderOpeningVisibleGeometry` переносит только группу `body` (дуга/створки/ + стекло) через `translate(swingTx swingTy)` (opening-symbol.ts:74–137); + косяки (`op-jamb`-линии на `±half` — здесь и далее «half» это `jambHalf`, + то есть половина физической толщины) рисуются вне этой группы (140–146) — + то есть **уже сейчас** структурно независимы от face-сдвига. Это прямо + подтверждает пункт контракта ТЗ §7 «Косяки всегда остаются на `±cm/2` … и + не входят в translated группу» — не предположение, а описание уже + существующей структуры кода, которую нужно не разрушить, а сохранить. + +**Геометрический контракт (§7 ТЗ) реализуем на текущей модели данных**, а не +декларация невозможного: +- Для стены комнаты `side` (`-1`/`1`) уже вычисляется из `opening.angle` через + `nx = -sin(rad), ny = cos(rad)` и знака `inward`-нормали ребра + (wall-thickness.ts:2419–2441) — это уже канонический локальный базис самого + проёма, **не зависящий от `order`**. Order используется только для выбора, + какая из двух сторон общей стены становится «natural» (unflipped) — + единственное, что требует замены на фиксированное правило по локальной оси. + Никакой новой геометрической информации придумывать не нужно. +- Для partition та же независимая от направления рисования величина уже + доступна — тот же `opening.angle`, что и для room-wall (сейчас не + используется в `partitionOpeningFace`, но используется параллельно для + room-wall face). Перевести partition-резолвер на тот же базис, вместо + `resolved.axis`, зависящего от `a`/`b`, технически прямолинейно. +- **Lock-бейдж переживёт правку без отдельного контракта**, хотя ТЗ (§18.3) + формулирует это как «принятое предположение»: `_renderOpeningLocks` + (houseplan-card.ts:18605–18616) вычисляет офсет бейджа как + `lockOffset * sign`, где `lockOffset` — фиксированная величина в grid units, + **не связанная с `face.ox/oy`/`cm`** вообще; она использует только знак + (`gateFace.side` либо `flip_v ? -1 : 1`). Смена перевода видимой группы с + «сдвиг на грань» на «центр» этот знак не меняет ни для одного из + зафиксированных в контракте случаев (§7 ТЗ) — прочитано и проверено + чтением, вывод сильнее, чем у самого автора: это не предположение, + которое ревьюер не оспорил, а проверенный факт. + +**Верность отражения решений владельца.** Раздел §4 ТЗ построчно совпадает с +ответами владельца из комментария `2026-08-22T17:07:08Z` на все четыре вопроса +(Q1 flip_v-совместимость, Q2 направление ворот, Q3 parity поверхностей, Q4 +окно целиком) — без искажений и без добавления нового необсуждённого +поведения. Технические детали (§18: формула локальной оси, имя типа +visual-offset) явно помечены как «принято предположительно, менять свободно» +и не выданы за продуктовое решение. + +**Проверяемость AC.** Все восемь AC (§11) сформулированы через числа и +конкретные наблюдаемые свойства (нулевое смещение, идентичность метрик при +перестановке, сохранение full-depth jambs, отсутствие diff в schema), а не +через «выглядит по центру» — ровно то, что требует сама постановка issue +(«AC стоит формулировать через числа»). У каждого указан способ доказательства +в допустимом словаре (`unit`/`smoke`/`golden`/`review`). + +**Терминология.** «Открывается в другую сторону» и «flip_v» использованы как +в `docs/USER-GUIDE.ru.md` (568–575), без изобретения нового языка. ТЗ явно +называет тот самый абзац «Толстые стены» (606–616) устаревшим фактическим +описанием («Створка/дуга двери и окна смещается к внутренней грани комнаты, а +створки ворот — к наружной») и относит его обновление к release-артефактам +своего user-visible коммита (§15) — список канонических документов на +обновление (`USER-GUIDE.ru.md`, `WALL-THICKNESS.md`, `ARCHITECTURE.md`, +`ISOMETRIC.md`, changelog RU+EN) полон, ничего из задетых поверхностей не +забыто. + +**Не-скоуп обоснован.** Passage (нет видимого символа), wall cut/jamb depth/ +opening length, lock badge, hitbox, Glow/sun/decor/vacuum, новый Iso UX или +config-migration — всё это корректно исключено и не пересекается с +задекларированным контрактом §7–8. + +## Чего не проверял + +- **Не запускал автотесты/гейты** — на этапе ТЗ кода нет, гейты §8 + относятся к код-ревью. +- **Не проверял `docs/ARCHITECTURE.md` целиком** — только убедился, что файл + фигурирует как канонический для этого изменения и включён в release- + артефакты §15; содержимое самого файла не читал, это не требуется для + вывода о полноте ТЗ. +- **Не оценивал `docs/specs/README.md` рассинхрон колонки «Статус ТЗ»** + (известный открытый пункт PROCESS.md §7.3.1, не относится к #242) — запись + строки #242 в таблице P2 корректна и не мой предмет. +- **Не проверял `iso-openings.ts`/`buildIsoOpeningBasis()` построчно** — + прочитал только его роль по `docs/ISOMETRIC.md` («door has one jamb-hinged + leaf… mirrors the existing opening-symbol transform algebra»); ТЗ верно + определяет его как одну из четырёх поверхностей parity (AC5), детальную + реализуемость там не проверял глубже необходимого для вывода «этот + контракт возможен» — она подтверждена уже на room-wall/partition пути, а + Iso по документации использует ту же алгебру. +- **Не проверял mutation-gate script и наличие тестовых фикстур** — на этапе + ТЗ они не существуют, это работа код-ревью. +- Никаких browser-smoke/golden не запускал — на этапе ТЗ нет рендера для + сравнения. + +## Заключение + +ТЗ полно по составу разделов, продуктово обосновано, верно отражает решения +владельца без домыслов, а диагноз и предложенный контракт подтверждены +чтением актуального кода (в том числе в пунктах, которые сам автор пометил +как непроверенное предположение — lock-бейдж, независимость косяков). High/ +Medium-находок нет. Задача может двигаться в `S5-ready`. + +**Вердикт: зелёный · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 0 → в задаче**