docs(spec): address #249 review findings

Issue: #249
User-Visible: no
This commit is contained in:
Sergey Matyunin
2026-08-23 03:47:19 +00:00
committed by claude[bot]
parent d44d2e8830
commit cb745c2035
+67 -8
View File
@@ -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, а не
настройка и не литерал в рендерерах.