docs: update partition openings spec after unified walls

Issue: #132
User-Visible: no
This commit is contained in:
Sergey Matyunin
2026-08-19 00:21:38 +03:00
parent b9bf210804
commit 2aaabc48d6
2 changed files with 194 additions and 83 deletions
+193 -82
View File
@@ -1,23 +1,27 @@
# Issue #132 — проёмы в независимых перегородках
# Issue #132 — проёмы в независимых стенах
- **Issue:** https://github.com/Matysh/houseplan-card/issues/132
- **Статус документа:** готово к будущей реализации; issue остаётся на `S3-spec`
- **Связанный bug в том же scope:** https://github.com/Matysh/houseplan-card/issues/185
- **Статус документа:** актуализировано после #173 и #157; готово к ревью ТЗ
- **Приоритет:** P2
- **Тип:** feature, обычный трек
- **Пользовательское изменение:** да
## 1. Сценарий
Администратор рисует независимую перегородку в Plan editor и размещает в ней
реальную дверь, окно или ворота тем же инструментом «Проём», которым работает со
стенами комнат. Домочадцы затем видят корректный разрыв, live state и действия в
View/kiosk.
Администратор рисует незамкнутую цепочку инструментом «Стены», завершает её
сменой инструмента, редактора или этажа и размещает в одном сохранённом сегменте
дверь, окно, ворота либо открытый проём тем же инструментом «Проём», которым
работает со стенами комнат. Домочадцы затем видят корректный разрыв, а для
stateful-типов — тот же live state и действия в View/kiosk.
## 2. Что человек увидит до и после
До изменения перегородка остаётся сплошной и не принимает проём; после изменения
выбранный door/window/gate вырезает её тело, следует за перегородкой и ведёт себя
как тот же тип проёма в обычной стене.
До изменения завершённая независимая стена остаётся сплошной и не принимает
проём; после изменения выбранный door/window/gate/passage вырезает её тело,
следует за конкретным host-сегментом и ведёт себя как тот же тип проёма в обычной
стене. При этом стена с проёмом по #185 остаётся полноценным ребром для
распознавания замкнутой комнаты.
## 3. Проблема и связь со scope
@@ -25,14 +29,27 @@ View/kiosk.
placement/index принимает только derived room walls. Physical union специально
добавляет partitions после opening cuts, поэтому проём не может вырезать их.
#173 заменил отдельный публичный инструмент «Перегородка» одной непрерывной
цепочкой «Стены». Активные сегменты crash-safe живут в `room_drafts`; явное
завершение превращает каждый сегмент в отдельный `partition` со stable `id`.
Face graph использует сохранённые partitions и может создать room wall на той же
оси, не удаляя исходный объект. Это делает composite room-wall/partition overlap
штатным, а не ошибочным случаем.
#185 фиксирует более новый продуктовый контракт: проём является свойством стены,
а не разрывом её структурного ребра. Поэтому opening cuts влияют на физическую и
световую геометрию, но room-face detection должен уметь замыкать область через
room wall или partition с любым поддержанным проёмом. `open_spans` остаются
реальным отсутствием стены и в topology не возвращаются.
Функция закрывает J4: администратор может без внешнего SVG точно воспроизвести
план. Правильный итоговый View также поддерживает J1/J2/J3: физическая геометрия,
contact/lock status и безопасные actions не расходятся с домом.
## 4. Решения владельца
1. На перегородке разрешены существующие `door`, `window`, `gate`; новый тип
«открытый проход» не добавляется.
1. На независимой стене разрешены все существующие типы: `door`, `window`,
`gate`, `passage`. #132 не добавляет новый opening type.
2. Проём следует за host при движении перегородки.
3. Удаление перегородки с проёмами требует confirmation со списком и удаляет их
только после явного согласия.
@@ -40,13 +57,25 @@ contact/lock status и безопасные actions не расходятся с
меняется только host geometry.
5. Физический passage в перегородке участвует в световой геометрии по тем же
type-specific правилам, что passage в стене.
6. При точном совпадении saved partition со стеной комнаты они считаются одним
составным физическим барьером без дополнительного host chooser. Explicit host
остаётся partition; hosted interval прорезает оба совпадающих тела. После
движения partition вычисляемый room-wall cut исчезает, room config не
переписывается.
7. По #185 проём любого поддержанного типа не разрывает структурное ребро для
room-face detection. Контур через стену с проёмом замыкается, а проём и его
host сохраняются.
## 5. Scope
- явная persisted host identity для partition opening;
- placement/hover/drag/edit/delete door, window и gate на partition;
- placement/hover/drag/edit/delete door, window, gate и passage на partition;
- full-depth cut, jamb/tunnel/symbol geometry с толщиной partition;
- composite cut совпадающих partition + derived room wall без persisted room
provenance;
- движение/удаление host и единая Undo/Redo команда;
- structural wall axes для #185 отдельно от physical opening gaps; regression
контракта #173 для endpoint/T/X/collinear faces и реальных `open_spans`;
- Flat Plan/View/kiosk/static и hidden Isometric renderers;
- clean floor, Glow barrier/source guard и действующие sun semantics;
- existing opening HA state/actions/security;
@@ -55,11 +84,11 @@ contact/lock status и безопасные actions не расходятся с
## 6. Не входит в задачу
- новый тип «открытый проход» без door/window/gate symbol;
- новый opening type или новая семантика существующего `passage`;
- проёмы в unfinished room drafts или columns;
- несколько host segments на один opening;
- автоматическая конверсия старого room-wall opening в partition opening;
- создание room/Area из partition;
- новый способ завершения Walls chain либо auto-resume finished partition;
- новая light model либо изменение window/door/gate semantics;
- sun rays, источником которых становится внутреннее partition window;
- полная touch parity Plan editor;
@@ -80,6 +109,9 @@ host?: {
- `host` отсутствует — current legacy/current room-wall association по `x/y/
angle/length`; старые конфиги не мигрируют.
- `kind='partition'` — `id` обязан ссылаться на partition того же space.
- Один finished Walls segment создаёт один partition id. Бывшая multi-segment
chain не становится составным host: соседние segments двигаются и удаляются
независимо.
- `t` — нормализованное положение центра вдоль направленного `a→b`, `[0,1]`.
- `x`, `y`, `angle` остаются materialized compatibility projection и обновляются
атомарно из host; новый frontend считает valid host+t authority.
@@ -104,12 +136,15 @@ opening.
- center from `a + t(b-a)`;
- angle modulo current opening convention;
- full length and host depth from partition `cm`;
- derived room-wall intervals, collinear with and covering the hosted opening
interval within the canonical wall epsilon;
- validity/orphan reason;
- adjacent floor samples/type-specific passage policy.
Placement preview, symbol, body cut, tunnel, hit test, light barriers, Iso panel,
move/delete и tests используют этот resolver. Запрещён render-only nearest-wall
fallback для explicit partition host.
Placement preview, symbol, body/composite cut, tunnel, hit test, light barriers,
Iso panel, move/delete и tests используют этот resolver. Запрещён render-only
nearest-wall fallback для explicit partition host. Coincident room-wall coverage
— вычисляемая projection valid partition host, а не второй persisted host.
Если endpoints хоста представлены в обратном порядке при canonical rewrite,
rewrite одновременно заменяет `t → 1-t`, сохраняя physical center и hinge/flip
@@ -123,14 +158,17 @@ orientation. Простое rigid translation сохраняет `t`, length и
- saved independent partition segments.
Hover preview показывает тот же translucent door/window/gate и привязывается к
partition axis. Center квантуется по действующему wall-bound grid step, length
целиком помещается между endpoints. Click повторно разрешает candidate и открывает
существующий opening dialog.
partition axis; `passage` использует свою действующую symbol-less preview. Center
квантуется по действующему wall-bound grid step, length целиком помещается между
endpoints. Click повторно разрешает candidate и открывает существующий opening
dialog.
При близких candidates выбирается минимальная perpendicular distance, затем
полное покрытие opening length; точная неразрешимая tie room-wall/partition
отклоняется с локализованной причиной вместо скрытого выбора другого host.
Existing opening hit имеет приоритет над placement.
полное покрытие opening length. Точное collinear overlap room-wall/partition,
покрывающее reserved interval, считается одним composite barrier и выбирает
explicit partition host без дополнительного dialog. Не совпадающая геометрически
tie остаётся неразрешимой и отклоняется с локализованной причиной. Existing
opening hit имеет приоритет над placement.
Toast `opening_no_wall` обновляется до «стены или перегородки». Virtual room span,
room draft и column остаются невалидными host. Touch placement — best effort;
@@ -146,15 +184,40 @@ Hosted opening:
- door swing начинается с выбранной face по `flip_v`;
- window glass располагается в середине partition depth;
- gate leaves используют current compact gate geometry;
- passage остаётся symbol-less full-depth cut по контракту #157;
- overlapping hosted openings не могут резервировать один interval дважды;
- junction patches после cut не должны заново закрыть passage.
Для zero/invalid thickness new partition невозможна по current validation
(1–100 cm). Malformed legacy host fail-dark: cut не применяется. Room-wall and
partition cuts выполняются по host identity до единого physical union; случайное
совпадение осей не позволяет opening прорезать второй независимый body.
(1–100 cm). Malformed legacy host fail-dark: cut не применяется. Partition cut
выполняется по explicit host identity до единого physical union. Он дополнительно
вырезает только derived room-wall bodies, которые collinear и покрывают тот же
hosted interval в пределах canonical epsilon. Случайное пересечение, nearby
parallel wall или второй independent body не прорезаются.
## 11. Floor fill и tunnel
## 11. Room topology и bug #185
Room-face graph получает два разных представления одной архитектуры:
- **physical/presentation:** opening interval вырезан из кладки и остаётся
проходом для изображения, hit geometry и type-specific света;
- **structural room topology:** axis валидной стены непрерывен через
door/window/gate/passage, потому что проём не отменяет принадлежность стены
контуру комнаты.
`buildPlanSnapGeometry()` либо следующий pure collector обязан сохранить
structural room/partition segment через opening interval для face traversal, не
возвращая этот interval в physical body. Действующий opening cut может оставаться
snap boundary/measure input, но не удаляет connectivity для room detection.
Контракт применяется одинаково к legacy room-wall opening и новому
partition-hosted opening. Контур, который последним segment опирается на такую
стену endpoint/T/X/collinear-примыканием, предлагает room по обычному #173 flow;
opening config, host, entities и materialized geometry не мутируют. `open_spans`
и отсутствующий/invalid host остаются настоящими gaps. Пассивные HA state ticks,
редактирование opening state и render не запускают room dialog.
## 12. Floor fill и tunnel
Partition не является границей room ownership. После вычитания hosted opening
видна уже существующая clean-floor/fill geometry под body. Дополнительный
@@ -165,24 +228,25 @@ fill ownership; cut не смешивает alpha и не создаёт нов
остаются выше base fill. Opening symbol скрывается по `hide_openings`, но physical
cut, HA state и barrier semantics остаются активны, как у room-wall opening.
## 12. Glow и light barriers
## 13. Glow и light barriers
Решение владельца «проём пропускает свет» реализуется через type-specific
существующий контракт:
- door/gate — transparent passage только там, где по обе стороны host есть floor;
- door/gate/passage — transparent passage только там, где по обе стороны host
есть floor; `passage` не получает state или створку;
- exterior/no-floor с одной стороны остаётся opaque, чтобы Glow не уходил наружу;
- window сохраняет текущую политику: glass виден, но indoor Glow через него не
проходит;
- virtual boundary к partition не относится;
- source внутри valid interior door/gate passage допустим; source внутри window
- source внутри valid interior door/gate/passage допустим; source внутри window
tunnel или invalid/orphan cut fail-dark.
Barrier geometry получает joined partition body **после вычитания только его
hosted passages**. Cache fingerprint включает host id/t, partition endpoints/cm,
opening length/type и geometry validity. HA-only state tick не rebuild-ит barriers.
## 13. Sun semantics
## 14. Sun semantics
Partition window не является exterior room-boundary window и не создаёт новый
sun wedge. Existing exterior windows и their wedges сохраняются. Если canonical
@@ -190,7 +254,7 @@ sun/physical clipping использует independent body set, hosted cut не
восстанавливать opaque partition поверх уже разрешённого passage; никаких новых
direction/source rules #132 не вводит.
## 14. HA state, actions и security
## 15. HA state, actions и security
Contact/invert, lock, badges, open amount, info card, lock/unlock confirmation и
`resolveHaBindingStatus()` не зависят от host kind.
@@ -199,17 +263,21 @@ Contact/invert, lock, badges, open amount, info card, lock/unlock confirmation
- Marker tombstone не отключает exact opening entity reference.
- Disabled/orphaned/unverified entity не выполняет service call.
- Window не получает lock control, если current type contract его не допускает.
- Passage остаётся inert: без contact/lock/invert/flip, badge, info card и service
call, по тому же контракту #157 на room wall.
- Перемещение host не меняет entity ids и runtime state.
Новый action resolver или отдельный partition status model запрещён.
## 15. Move, edit, delete и Undo
## 16. Move, edit, delete и Undo
### Move/edit
Rigid partition drag обновляет endpoints и materialized `x/y/angle` всех hosted
openings в одном preview/commit. `t`, length, entities and flips сохраняются.
Одна Undo/Redo command восстанавливает partition и все hosted projections.
Rigid drag одного partition segment обновляет endpoints и materialized
`x/y/angle` всех его hosted openings в одном preview/commit. `t`, length,
entities and flips сохраняются. Соседние segments бывшей Walls chain не
двигаются. Одна Undo/Redo command восстанавливает partition и все hosted
projections, включая computed composite cut.
Editor operation, которая сократила бы host меньше opening+jamb margin, блокирует
commit с причиной. Import/legacy invalid geometry не clamped молча.
@@ -226,7 +294,7 @@ commit с причиной. Import/legacy invalid geometry не clamped молч
Удалять hosted openings без confirmation через generic cleanup запрещено.
## 16. Orphan и failure policy
## 17. Orphan и failure policy
Explicit partition opening с отсутствующим/invalid host:
@@ -240,10 +308,12 @@ Explicit partition opening с отсутствующим/invalid host:
Boolean failure по одному cut возвращает непрорезанный opaque partition
(fail-dark), не удаляет config и не делает все independent bodies прозрачными.
## 17. Migration и compatibility
## 18. Migration и compatibility
- Старые openings без `host` читаются и пишутся по current room-wall contract.
- Existing room-wall opening около partition не начинает прорезать partition.
- Room-wall opening, существовавший до #132, сохраняет implicit host и участвует
в structural room topology по #185 без migration/write-on-read.
- New optional fields добавляются в frontend/backend schema и
`docs/CONFIG-COMPATIBILITY.md`/field registry.
- Export/import/backup сохраняют host object и referential order; counts остаются
@@ -257,60 +327,82 @@ Boolean failure по одному cut возвращает непрорезан
Schema migration существующих данных не нужна: capability появляется только у
новых/явно перепривязанных openings.
## 18. i18n и accessibility
## 19. i18n и accessibility
Новые en/ru strings:
- «Стена или перегородка» в placement guidance/error;
- host kind «Перегородка» в properties/diagnostic;
- confirmation title/body и строки списка hosted openings;
- orphan reason/rebind action, если affordance нужен по §16.
- orphan reason/rebind action, если affordance нужен по §17.
Opening dialog, list и confirmation используют существующий `hp-dialog`, focus
trap, Escape и restore focus. List доступен screen reader; confirmation сообщает
точное количество. Canvas preview не является единственным объяснением host:
properties/diagnostic имеет текстовое accessible name.
## 19. Acceptance criteria
## 20. Acceptance criteria
1. **AC1 — placement.** Door/window/gate размещаются на partition canonical
wall-bound workflow; draft/column/virtual span не принимаются.
**Доказательство:** resolver unit + desktop browser smoke.
2. **AC2 — geometry.** Opening cut full-depth с корректными jamb/symbol для
1/15/100 cm и diagonal partition, без прорезания coincident other body.
1. **AC1 — Walls workflow и placement.** После завершения multi-segment цепочки
«Стены» каждый saved segment является отдельным candidate host. На partition
размещаются door/window/gate/passage; active draft, column и virtual span не
принимаются. **Доказательство:** resolver/lifecycle unit + desktop smoke.
2. **AC2 — geometry и composite overlap.** Opening cut full-depth с корректными
jamb/symbol для 1/15/100 cm и diagonal partition. При точном покрывающем
room-wall overlap partition выбирается explicit host и весь composite barrier
прорезается; crossing/nearby/второй independent body не затрагиваются.
**Доказательство:** geometry units + reviewed golden.
3. **AC3 — host lifecycle.** Rigid move переносит opening; delete показывает
список и атомарно удаляет после Confirm; Undo/Redo восстанавливает всё.
3. **AC3 — host lifecycle.** Rigid move одного segment переносит его openings и
убирает computed room-wall cut; delete показывает точный список и атомарно
удаляет после Confirm; Undo/Redo восстанавливает host/openings/composite.
**Доказательство:** command units + browser smoke.
4. **AC4 — light.** Interior door/gate пропускают Glow через cut, exterior
passage и window остаются opaque по current policy; failure fail-dark.
**Доказательство:** light visibility units + smoke/golden.
5. **AC5 — render parity.** Plan/View/kiosk/static/Iso используют один resolved
host и не расходятся по center/angle/depth/open state.
**Доказательство:** cross-render smoke + golden.
6. **AC6 — HA/security parity.** Contact/lock/badge/actions совпадают с room-wall
opening, secure/disabled guards не меняются. **Доказательство:** unit matrix + smoke.
7. **AC7 — compatibility.** Legacy openings unchanged; host fields survive
save/export/import/optimize; invalid reference rejected or fail-dark.
**Доказательство:** frontend/backend round-trip tests.
8. **AC8 — accessibility/touch safety.** Dialog/confirmation keyboard доступны,
touch cancel/multi-touch не создают opening. **Доказательство:** browser smoke.
9. **AC9 — cache/performance.** HA tick не rebuild-ит structural geometry;
cache bounded and invalidated by host geometry. **Доказательство:** counters +
performance smoke.
10. **AC10 — no new type.** Config/UI допускает только door/window/gate.
**Доказательство:** schema/source contract.
4. **AC4 — light.** Interior door/gate/passage пропускают Glow через полный
composite cut; exterior/no-floor варианты и window остаются opaque по current
policy; invalid host/boolean failure fail-dark. **Доказательство:** light
visibility units + smoke/golden.
5. **AC5 — #185 room closure.** Room-face detection считает wall axis
непрерывным через door/window/gate/passage как на legacy room wall, так и на
partition host. Endpoint/T/X/collinear closure предлагает room и сохраняет
opening bit-equivalent; `open_span` остаётся gap. **Доказательство:** pure
topology unit + production-bundle smoke, который краснеет на `origin/dev`.
6. **AC6 — no passive topology mutation.** HA state, opening edit/render,
reload и existing closed face не показывают room dialog и не меняют geometry;
только последний accepted Walls segment может инициировать предложение по
#173. **Доказательство:** wall-face graph unit + smoke.
7. **AC7 — render parity.** Plan/View/kiosk/static/Iso используют один resolved
host и не расходятся по center/angle/depth/open state; passage остаётся
symbol-less. **Доказательство:** cross-render smoke + golden.
8. **AC8 — HA/security parity.** Door/window/gate contact/lock/badge/actions
совпадают с room-wall contract, secure/disabled guards не меняются; passage
остаётся inert. **Доказательство:** unit matrix + smoke.
9. **AC9 — compatibility.** Legacy openings unchanged; host fields survive
save/export/import/optimize; invalid reference rejected or fail-dark; schema
принимает ровно четыре уже существующих type. **Доказательство:**
frontend/backend round-trip tests.
10. **AC10 — accessibility/touch safety.** Dialog/confirmation keyboard
доступны, touch cancel/multi-touch не создают opening и не завершают Walls
chain. **Доказательство:** browser smoke.
11. **AC11 — cache/performance.** HA tick и pointermove не rebuild-ят host,
composite или face topology; caches bounded и инвалидируются geometry host /
opening type/length. **Доказательство:** counters + performance smoke.
12. **AC12 — regression #173/#157.** Walls finish/no-auto-resume, room queue,
passage field restrictions, room-wall opening placement и планы без hosted
openings остаются совместимыми. **Доказательство:** existing targeted suites
+ named #132 smoke.
## 20. План автотестов
## 21. План автотестов
### Unit
- host serialization/resolution, t and reversed endpoints;
- room-wall vs partition candidate/tie/length fit;
- room-wall vs partition candidate, composite/non-composite tie and length fit;
- horizontal/vertical/diagonal, 1/15/100 cm cut and jambs;
- overlap reservation, junction patch, coincident independent body;
- overlap reservation, junction patch, coincident derived wall vs independent body;
- move/delete/Undo atomic snapshots;
- interior/exterior/window light policy and fail-dark;
- interior/exterior/window/passage light policy and fail-dark;
- structural-vs-physical collector: all four openings preserve room-face axes,
while `open_span` remains a gap; endpoint/T/X/collinear #185 matrix;
- only the latest accepted segment may cause room proposal; opening/HA updates do not;
- orphan, missing host and cache fingerprint;
- HA state/action host-kind parity.
@@ -318,22 +410,30 @@ properties/diagnostic имеет текстовое accessible name.
- host discriminator/id/t and referential validation;
- config size/count limits, export/import/unknown fields;
- canonical `passage` field restrictions from #157 with partition host present;
- malformed/missing partition rejection;
- full HA harness authority — Linux CI/WSL.
### Browser smoke
- place/edit/drag door, window, gate on partition;
- finish multi-segment Walls chain; place/edit/drag door, window, gate and passage
on one resulting partition without resuming the chain;
- host move, delete Cancel/Confirm and Undo/Redo;
- contact opens, lock confirmation/action, hide_openings;
- Glow across interior passage and blocked by window/exterior passage;
- reproduce #185 on legacy room wall and hosted partition for all four types,
including T closure; verify `open_span` still blocks closure and opening config
is unchanged;
- exact composite overlap selects partition host without an extra chooser and
leaves no opaque wall layer across the opening;
- Plan/View/kiosk/static/Iso parity;
- touch cancel/pinch safety and keyboard confirmation;
- import/optimize round trip.
### Golden
- thick/diagonal partition with all three types, light/dark;
- thick/diagonal partition with all four types, light/dark;
- coincident room-wall/partition composite before and after hosted cut;
- Glow before/after door passage and opaque window;
- hidden Iso panels/cuts and static-card parity;
- expected diffs accepted only from reviewed full Linux artifact.
@@ -345,23 +445,28 @@ properties/diagnostic имеет текстовое accessible name.
- repeated render cache growth 0/bounded caps;
- no per-opening repeated full wall index build.
## 21. Затронутые поверхности
## 22. Затронутые поверхности
- `OpeningCfg`, backend validation and config compatibility registry;
- opening placement/resolver, wall-thickness/physical geometry and command stack;
- `plan-snap-overlay`/wall-face structural collector and #173 room queue;
- Flat/static/Iso opening renderers;
- Glow/light and current sun physical consumers;
- Plan dialog/i18n, import/export/align/optimize;
- unit/backend/smoke/golden/performance fixtures;
- `docs/ARCHITECTURE.md`, `docs/CANVAS.md`, `docs/WALL-THICKNESS.md`,
`docs/LIGHT.md`, `docs/SUN.md`, `docs/USER-GUIDE.ru.md`, `docs/TESTING.md`.
- `docs/ARCHITECTURE.md`, `docs/CANVAS.md`, `docs/UX-MODES.md`,
`docs/WALL-THICKNESS.md`, `docs/LIGHT.md`, `docs/SUN.md`,
`docs/USER-GUIDE.ru.md`, `docs/TESTING.md`.
## 22. Риски и откат
## 23. Риски и откат
| Риск | Мера |
| --- | --- |
| Host inference режет не ту стену | explicit partition id+t |
| Composite overlap режет nearby/crossing body | collinear full-interval coverage + negative units |
| Junction union закрывает passage | cut-aware physical union tests |
| #185 возвращает физическую кладку в проём | отдельные structural и physical projections |
| Opening начинает пассивно открывать room dialog | topology-delta и no-passive smoke #173 |
| Delete теряет entities | atomic command snapshot + confirmation |
| Light проходит через window/outside | existing type/floor-side policy |
| Older writer оставляет orphan | backend referential validation |
@@ -372,25 +477,31 @@ after room cuts. Уже сохранённые host objects должны либ
read-preserved/diagnostic, либо требовать downgrade warning; автоматически
преобразовывать их в room-wall openings нельзя.
## 23. Release-артефакты
## 24. Release-артефакты
Implementation commit имеет `User-Visible: yes` и одновременно обновляет:
- `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md`;
- `docs/USER-GUIDE.ru.md` — placement/types/move/delete/light;
- `docs/ARCHITECTURE.md`, `docs/CANVAS.md`, `docs/WALL-THICKNESS.md`,
`docs/LIGHT.md`, `docs/SUN.md`, `docs/CONFIG-COMPATIBILITY.md`;
- `docs/USER-GUIDE.ru.md` — Walls finish, placement/types/move/delete/light и
closure через стену с проёмом;
- `docs/ARCHITECTURE.md`, `docs/CANVAS.md`, `docs/UX-MODES.md`,
`docs/WALL-THICKNESS.md`, `docs/LIGHT.md`, `docs/SUN.md`,
`docs/CONFIG-COMPATIBILITY.md`;
- `docs/TESTING.md`.
Нужны reviewed Flat/Iso/Glow golden artifacts, targeted browser/performance
reports and exact Linux backend evidence. Visual baselines принимаются только
через `golden:accept -- --reviewed` по полному Linux artifact.
## 24. Принятые технические предположения
## 25. Принятые технические предположения
- partition host хранится explicit id+t, materialized x/y/angle сохраняются;
- room-wall openings остаются implicit для backward compatibility;
- ambiguous exact placement tie отклоняется вместо скрытого host выбора;
- exact covering room-wall/partition overlap выбирает partition host как
owner-approved composite; прочие ambiguous ties отклоняются;
- structural room topology may use uncut wall axes, while all physical/light
consumers continue using type-specific cuts; shared persisted geometry не
создаётся;
- partition window не становится exterior sun source;
- invalid host/cut fail-dark and hidden from ordinary View;
- точная форма discriminator fields может меняться на ревью без изменения
+1 -1
View File
@@ -88,7 +88,7 @@ GitHub Issues и GitHub Projects (v2) остаются единственным
| [#107](https://github.com/Matysh/houseplan-card/issues/107) Переключение виртуального источника света «Всегда» | [107-virtual-light-toggle.md](107-virtual-light-toggle.md) |
| [#122](https://github.com/Matysh/houseplan-card/issues/122) Изометрический режим Stage 2: скрытый режим и визуальная полировка | [122-isometric-stage2.md](122-isometric-stage2.md) |
| [#123](https://github.com/Matysh/houseplan-card/issues/123) Split из вершины не меняет наружную геометрию стен | [123-corner-split-wall.md](123-corner-split-wall.md) |
| [#132](https://github.com/Matysh/houseplan-card/issues/132) Проёмы в независимых перегородках | [132-partition-openings.md](132-partition-openings.md) |
| [#132](https://github.com/Matysh/houseplan-card/issues/132) Проёмы в независимых стенах (+ bug [#185](https://github.com/Matysh/houseplan-card/issues/185)) | [132-partition-openings.md](132-partition-openings.md) |
| [#137](https://github.com/Matysh/houseplan-card/issues/137) Узлы и линии привязки в редакторе Плана | [137-plan-snap-overlay.md](137-plan-snap-overlay.md) |
| [#141](https://github.com/Matysh/houseplan-card/issues/141) Бесшовные стыки перегородок и открытых контуров | [141-wall-junctions.md](141-wall-junctions.md) |
| [#157](https://github.com/Matysh/houseplan-card/issues/157) Тип проёма «Открытый проём» | [157-open-passage.md](157-open-passage.md) |