diff --git a/docs/specs/249-multiwall-junction-bevel.md b/docs/specs/249-multiwall-junction-bevel.md index 0e2d5c9a..db23cf47 100644 --- a/docs/specs/249-multiwall-junction-bevel.md +++ b/docs/specs/249-multiwall-junction-bevel.md @@ -6,7 +6,7 @@ - Сложность/риск: 5/10 и 6/10 - Issue: [#249](https://github.com/Matysh/houseplan-card/issues/249) - Ветка: `issue/249-multiwall-junction-bevel` -- Статус ТЗ: первая редакция, ожидает ревью +- Статус ТЗ: редакция r2 после SPEC-REVIEW-249-r1, ожидает повторное ревью Канонические документы: `docs/SCOPE.md`, `docs/WALL-THICKNESS.md`, `docs/ARCHITECTURE.md`, `docs/TOUCH-SUPPORT.md`, `docs/TESTING.md`. @@ -136,13 +136,17 @@ junction patch, созданная именно для соединения ин Когда вершина room profile совпадает с multi-wall node: 1. существующее пересечение смещённых граней остаётся митрой, если его - расстояние от node `<= R + epsilon`; -2. если пересечения нет, оно не конечное либо дальше `R`, join содержит две + конечное расстояние от node `d <= R`; +2. если пересечения нет, оно не конечное либо `d > R`, join содержит две штатные offset-точки соседних граней — прямую фаску; -3. каждая созданная для этого node join-вершина остаётся не дальше `R + epsilon`; -4. локальное соединение имеет ненулевую площадь, node не попадает в hole wall +3. epsilon не расширяет область выбора митры: branch decision всегда разделён + единственной границей `R`. Допуск `epsilon` используется только при проверке + и сравнении уже вычисленных floating-point координат; +4. каждая созданная для этого node join-вершина остаётся не дальше + `R + epsilon` при численной проверке результата; +5. локальное соединение имеет ненулевую площадь, node не попадает в hole wall body, а тела всех инцидентных rays входят в один связный кладочный компонент; -5. boolean union не вправе вернуть в body отброшенную дальнюю вершину из другого +6. boolean union не вправе вернуть в body отброшенную дальнюю вершину из другого независимого room ring. Все ring/piece producers получают одну карту и лимит до объединения. @@ -290,13 +294,68 @@ Validate остаётся обязательным. - `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md`: пользовательский bugfix в том же коммите, что продуктовая правка. -## 11. Откат +## 11. Риски и меры снижения + +### R1. Широкий blast radius для существующих T-стыков + +Новый контракт действует не только на экспорт #249, а на каждый валидный узел +степени `3+`. Сегодня визуально приемлемая митра в диапазоне `(1.25 × H, 4 × H]` +станет фаской. Такие T-стыки встречаются в обычных сохранённых планах, поэтому +изменение может затронуть golden-сценарии, не связанные с #249. + +**Митигация:** targeted unit/golden не заменяют полный `golden:verify`. Перед +бетой обязателен полный Linux golden artifact; просматриваются все изменённые +кадры и diff, а не только новый crop #249. Необъяснимое изменение другого узла +останавливает baseline acceptance. Существующие двухлучевые expected values +дополнительно остаются неизменными по AC3. + +### R2. Фаска может создать щель или ложную кладку + +Независимое ограничение двух room rings способно оставить pinhole, разорвать +один ray от узла либо, наоборот, заполнить сектор пола лишним материалом. +Расхождение особенно опасно для Glow/sun: визуально малый дефект становится +ложным световым проходом или барьером. + +**Митигация:** единая node map применяется до boolean union всеми producers; +AC1/AC2 требуют ненулевой положительной связности с каждым ray, отсутствия hole +и единой canonical geometry для рендера и occlusion. Отдельный SVG overlay +запрещён. + +### R3. Порядок, winding и масштаб могут менять классификацию + +Shared interval присутствует в профилях двух комнат, а атомарные отрезки могут +иметь обратное направление. Ошибка дедупликации превратит двухлучевой угол в +multi-wall node либо даст разные фаски при перестановке данных. Абсолютный +epsilon может разойтись между normalized и production scale. + +**Митигация:** канонический interval/ray key, scale-relative tolerance и +обязательная permutation/winding/`coordScale = 1000` матрица AC2. + +### R4. Локальная boolean-ошибка может погасить весь structural pass + +Новая ограничивающая геометрия проходит через `polyclip-ts`; вырожденный patch +может бросить исключение или дать zero-area polygon. + +**Митигация:** локальный candidate проверяется до union и отбрасывается +изолированно по §7.5. Существующий fail-dark контракт обязательных стадий не +маскируется; regression #197 остаётся зелёной. + +### R5. Дополнительный topology pass может ухудшить live rendering + +Повторный поиск всех совпадающих endpoints на каждом HA tick сделал бы стоимость +видимого bugfix непропорциональной. + +**Митигация:** карта строится только в cached structural pass с ограничением +`O(E)`/`O(E log E)` из §8. Targeted smoke проверяет cache parity, а обязательный +предрелизный performance smoke контролирует тяжёлый дом. + +## 12. Откат Откатывается pure multi-wall node classification/limit и связанные tests/docs. Данные не мигрируются, поэтому отдельный data rollback не нужен. Golden baseline откатывается только вместе с соответствующей product geometry. -## 12. Принятые технические предположения +## 13. Принятые технические предположения 1. Коэффициент `1.25` — именованная константа канонической wall geometry, а не настройка и не литерал в рендерерах.