# SPEC-REVIEW-288-r2 - **Issue:** https://github.com/Matysh/houseplan-card/issues/288 - **Этап:** spec (PROCESS.md §2.4) - **Заход:** r2 · блокирующих циклов израсходовано 1 из 4 (r1 был жёлтым и потратил 1 цикл; зелёный вердикт цикла не образует, #227) - **Документ ТЗ:** `docs/specs/288-bounded-multiwall-corridor.md` - **SHA r1 (найден в документе r1, не в комментарии-вердикте):** `cb0f9e7351e919701666dfd05b53f0e218e672a5` - **SHA r2 (текущий HEAD, дельта этого раунда):** `fba615e9f6ec8841c6e6e0f9a7cc5fe0d1fc7c25` - **Разбор — по дельте** (PROCESS.md §2.10): единственный коммит между SHA r1 и HEAD — `fba615e9 docs: add risks and rollback to junction spec` (`docs/specs/288-bounded-multiwall-corridor.md`, +21/-4 строк). Дельта локальна: только текст, только два новых раздела плюс одна строка в шапке; не задета ни одна формулировка сценария, контракта, scope или AC. Условия «разбор остаётся полным» (ребейз на ушедший вперёд `dev`, смена контракта поведения, новая подсистема, объём дельты сопоставим с исходной задачей) не выполнено ни одно — исходное ТЗ 208 строк, дельта 25 строк правки двух разделов. Полный повторный разбор не требуется. ## Дельта (что менялось) ``` git diff cb0f9e73..fba615e9 -- docs/specs/288-bounded-multiwall-corridor.md ``` - добавлен раздел «7. Риски и меры» (3 пункта: регрессия семи прежних junction-контрактов → мера AC4/оба плана/golden; над-/недосечение соседней стены → мера AC3/AC5/AC7; расхождение polygon между Plan/View/Static/Iso → мера AC5 + запрет consumer-specific post-fix); - добавлен раздел «8. Откат» (один абзац: чистый revert, флаг/миграция не нужны, т.к. persisted model не меняется); - последующие разделы («Ожидаемые файлы», «Release…», «Принятые технические предположения») перенумерованы 7→9, 8→10, 9→11 без потери и без дублей (проверено `grep -n "^## "` по всему файлу — последовательность 1…11 без пропусков); - в шапку «Связано» добавлен `#279`. Коммит несёт корректные трейлеры: `Issue: #288`, `User-Visible: no` (класс C, поведение не меняется). ## Закрытие раунда r1 | Находка r1 | Чем закрыта | Где это видно | |---|---|---| | **M1** (Medium, в скоупе) — отсутствуют обязательные разделы «Риски» и «Откат» (§7.1, DoR §2.5) | Добавлены разделы «7. Риски и меры» (3 пункта с мерами, привязанными к AC3/AC4/AC5/AC7) и «8. Откат» (чистый revert, без флага/миграции) | `docs/specs/288-bounded-multiwall-corridor.md:170-185`, коммит `fba615e9` | | **L1** (Low) — «Связано» не включает #279, хотя AC4 на него ссылается | `#279` добавлен в строку «Связано» | `docs/specs/288-bounded-multiwall-corridor.md:11`, коммит `fba615e9` | Оба пункта закрыты содержательно, а не формальным упоминанием слова: риск 1 прямо называет затронутый общий код (`bevelMultiWallBody`) и все семь прежних контрактов по номерам, риск 2 и 3 — конкретные меры отказа (перекрытие, недосечение, рассинхронизация consumers) с привязкой к конкретным AC, а не общими словами. Формулировки рисков корректно хеджированы («может вернуть», «может разойтись») — это анализ риска, а не факт о поведении, выданный без основания. Откат сформулирован как утверждение и совпадает с уже зафиксированным в шапке фактом «persisted model не меняется» — не новое недоказанное утверждение, а следствие уже принятого в r1 факта. ## Унаследовано из r1 Всё, что не затронуто дельтой, принимается без повторной проверки по документу `docs/reviews/SPEC-REVIEW-288-r1.md` (SHA `cb0f9e7351e919701666dfd05b53f0e218e672a5`): - диагноз причины (узел `577,299`, лучи `349/120/5` шагов, толщины `30/30/30` см, соседняя стена `20` см, радиус `4×15=60`, вырез `60−15=45`) — сверен ревьюером r1 с телом issue буквально; - существование и корректность использования идентификаторов контракта (`MITRE_LIMIT`, `MultiWallNodeRay.supports`/`halfDepth`) в `src/wall-thickness.ts` — проверено чтением кода в r1, дельта этого файла не касается; - привязка AC1/AC2 к существующему `demo/smoke_real_plan_masonry.mjs` и корректность его логики подсчёта разрывов — не менялась; - table-driven конструкция AC3 как независимая от AC1 unit-гарантия — текст AC3 не тронут дельтой; - список регрессионных контрактов AC4 (#249/#261/#271/#272/#275/#278/#279), сверенный с `docs/WALL-THICKNESS.md`, — текст AC4 не тронут; #279 добавлен только в шапку «Связано», в самом AC4 он уже присутствовал в r1; сверено `git diff cb0f9e73..HEAD -- docs/specs/288-bounded-multiwall-corridor.md` — раздел AC (строки 98–156 текущего файла) в дельте не участвует; мутационное требование AC7 — не менялось; - корректность Scope/«Не входит» (исключение #289/#290 и глобальных констант) — не менялось; «Принятые технические предположения» — не менялись по содержанию, только перенумерованы (9→11); - отсутствие продуктовых вопросов, требующих участия владельца, — не менялось; новый текст рисков и отката тоже не содержит продуктовой развилки, ниже проверено отдельно. - совместимость/touch/performance (раздел 6) — не менялась. ## Что проверено заново в этом раунде - Полный просмотр итогового файла (`docs/specs/288-bounded-multiwall-corridor.md`, 226 строк) для проверки целостности нумерации разделов и отсутствия висячих перекрёстных ссылок на старые номера — ссылок по номеру раздела в тексте документа нет вообще (`grep -n "раздел\|§[0-9]"` — 0 совпадений), поэтому перенумерация 7→9/8→10/9→11 безопасна. - Содержательность нового раздела «Риски и меры»: каждый из трёх пунктов называет конкретный failure mode и конкретную меру, привязанную к проверяемому AC, а не общую фразу «будем осторожны». Прецедентная сверка формы с `docs/specs/275-multiwall-strip-containment.md` и `docs/specs/278-wall-union-isolation.md` (использовались как эталон в r1) показывает сопоставимую структуру: конкретный риск → конкретная мера. - Раздел «Откат»: соответствует требованию DoR §2.5 «откат: как выключить или вернуть назад» — здесь ответ «чистый revert» обоснован отсутствием изменений модели данных, что само по себе уже было зафиксировано в шапке ТЗ («Модель данных: schema, config, layout и Optimize не меняются») и в r1 это не оспаривалось. - Продуктовая рамка не пересматривалась целиком (не требуется по §2.10, дельта не продуктовая), но точечно проверено: новые два раздела не вводят решения, которое следовало бы адресовать владельцу (нет пограничного случая, нет конфликта персон, нет вопроса об объёме видимых изменений) — оба раздела чисто технические, что соответствует их месту в документе (после AC, до release-раздела). - Трейлеры коммита `fba615e9`: `Issue: #288`, `User-Visible: no` — корректно для документации класса C без изменения поведения. ## Гейты Этап — spec, продуктовый код не менялся (diff ограничен `docs/specs/288-*.md`, класс C). Как и в r1, гейты §8 (`typecheck`/`test`/`build`/`check-docs`/ smoke/invariants/golden) к этапу spec-review не относятся и не запускались — это гейты этапа code-review (§2.7), где эта задача окажется позже. Дельта этого раунда тем более не продуктовая (только текст ТЗ), так что необходимость их прогона не возникла и по факту дельты. ## Находки Нет. High: 0, Medium: 0, Low: 0. Обе находки r1 закрыты содержательно (см. таблицу выше), новых находок дельта не порождает. ## Чего не проверял - Повторно не проверял идентичность кода `src/wall-thickness.ts` контракту §3.1 — код не менялся с r1, наследуется. - Не запускал `demo/smoke_real_plan_masonry.mjs` и `npm run invariants` — реализации ещё нет, как и в r1; вопрос сохраняется до code-review. - Не проверял golden baseline — как и в r1, AC6 описывает будущую работу. ## Вердикт ``` Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0 Документ: docs/reviews/SPEC-REVIEW-288-r2.md ```