Commit Graph
538 Commits
Author SHA1 Message Date
Matysh 118062bb8c test: close device presentation review findings
Issue: #267
User-Visible: no
2026-08-27 22:41:46 +03:00
Matysh 6efc315ba6 refactor: make device presentation decisions explicit
Issue: #267
User-Visible: no
2026-08-27 22:06:10 +03:00
Matysh ba66698f55 refactor: extract resize controller
Issue: #264
User-Visible: no
2026-08-27 20:30:07 +03:00
Codex 78850a8733 build: rebundle after the package.json script addition
Проверка (CI) / Провенанс коммитов: трейлеры и эталоны (push) Failing after 8m3s
Проверка (CI) / Процессный гейт: диапазон, трейлеры, статусы issue (push) Failing after 8m2s
Проверка (CI) / Классификация изменённых файлов (push) Successful in 52s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m30s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 35s
Проверка (CI) / Процесс: process.yml идентичен в main и dev (push) Successful in 7m32s
Проверка (CI) / Документация: гайды, ченджлоги, скриншот-индекс (push) Successful in 7m53s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 23s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Successful in 13m14s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 13m21s
Проверка (CI) / Golden-кадры против принятых эталонов (push) Failing after 26m7s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Failing after 31m4s
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Failing after 34m5s
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Failing after 12m59s
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Failing after 45m46s
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
The bundle embeds the source fingerprint, which covers package.json; the
release:notes script addition moved it, so the three bundle copies must be
rebuilt in the same change.

Issue: #328
User-Visible: no
2026-08-27 18:59:10 +03:00
Matysh ca383febef chore: release v1.68.1
Owner-approved emergency stable hotfix; the release commit changes only version fields, generated bundles and release metadata.

Issue: #324
User-Visible: yes
2026-08-27 17:17:12 +03:00
Matysh 69e410fea3 fix: materialize empty wall catalog for new spaces
Issue: #324
User-Visible: yes
2026-08-27 16:33:47 +03:00
Matysh 1edf5cb3a7 perf: reuse masonry after cancelled resize
Issue: #322
User-Visible: no
2026-08-27 15:38:32 +03:00
Matysh 780b7a6c7a perf: reuse wall topology for light transport
Issue: #322
User-Visible: no
2026-08-27 15:00:30 +03:00
Matysh 59a23de81b perf: reuse validated wall geometry
Issue: #322
User-Visible: no
2026-08-27 13:58:06 +03:00
Matysh 87ff906545 perf: keep room contour cache out of editor previews
Issue: #322
User-Visible: no
2026-08-27 13:11:03 +03:00
Matysh 298030d47e perf: reuse structural room contours
Issue: #322
User-Visible: no
2026-08-27 12:58:02 +03:00
Matysh aaf7611490 build: promote v1.68.0 after beta.4
Issue: #322
User-Visible: yes
2026-08-27 10:29:04 +03:00
Codex 3d4e5580fa build: prepare v1.68.0-beta.4 candidate
Package the two beta.3 write-blocker fixes: the model-upgrade stale-client
guard and the self-resolving zero-wall migration.

Issue: #316
Issue: #319
User-Visible: yes
2026-08-27 08:11:42 +03:00
Codex 0f36ef55d5 fix: an opening without an in-place carrier migrates unhosted (#316, review r1 H1 + r2 M2)
CODE-REVIEW-316-r1 H1: the §3.3 degraded pool picked an angle-compatible wall
at ANY distance, but the backend geometry-match invariant («wall opening
geometry must match its host») requires the host to agree with the opening's
own x/y — the migrated document was rejected by CONFIG_SCHEMA and the write
wedged again on the schema layer. The pool is removed from both migrations
(TS and the Python mirror): without an in-place eligible carrier the opening
goes straight to the unhosted degraded state, exactly the alternative the
spec's «assumed freely changeable» section reserved; the spec is revision 6.
New tests replay the reviewer's reproduction on both sides, and the frontend
test is proven able to fail by restoring the pool (executed red).

CODE-REVIEW-316-r2 M2: the schema-level host check is shared with #132
partition openings, so its unhosted relaxation is now pinned by a regression
test — a stale writer that keeps a partition-hosted opening but silently
drops its host is still rejected by validate_partition_opening_hosts.

Issue: #316
User-Visible: no
2026-08-26 23:41:35 +03:00
Codex ffb232398a fix: the initial wall-model migration resolves every opening conflict itself (#316)
Implements spec revision 4 (green r4). §3.1 — a legacy open_spans/open_to cut
never zeroes the atom that carries an existing contour opening: the opening's
edges become atom boundaries, the door keeps its real wall and the zero run
continues on both sides. §3.2 — an ambiguous carrier resolves
deterministically: current host, then distance, thicker cm, smaller id.
§3.3 — an opening with no usable carrier persists unhosted: a valid degraded
v9 state, inert in the physics, rendered by its own x/y, kept by later writes
and re-placeable in the editor (backend schema accepts it). §3.4 — the
initial migration never throws over an opening; a post-v9 write that LOST its
carrier keeps the fail-closed opening-host refusal. The Python migration
mirror implements the same rules with byte-identical output (verified on the
span+door fixture including the segment id).

The new smoke replays #316 end to end: a conflicted space no longer blocks
drawing on an empty plan. The golden scene span-over-door-migrated-dark
renders the migrated fixture pinned byte-for-byte to the real writer; two
gate mutants revert §3.1 and §3.4 and are red by execution.

Issue: #316
User-Visible: yes
2026-08-26 22:06:43 +03:00
Codex 3ab6fa9f8a fix: the first write of a newer wall model is not an outdated client (#319)
A stale client can only echo the stored model_version, never raise it. The
'unchanged wall catalogue' refusal now applies only when the submitted model
is not above the stored one; the first v9 write over a v8 document with an
orphan open_span/open_to legitimately drops the legacy projection without
touching the catalogue and passes. The regression pair fixture is produced
by the real writers (stored: v1.68.0-beta.2, sent: current migration) and is
pinned on the frontend byte-for-byte so it cannot drift.

Issue: #319
User-Visible: yes
2026-08-26 18:20:15 +03:00
Matysh 8bfd56eb59 build: prepare v1.68.0-beta.3 candidate
Package the reviewed zero-thickness wall model and legacy virtual-wall migration.

Issue: #306
User-Visible: yes
2026-08-26 14:28:35 +03:00
Matysh f15bdc678b fix: address zero-wall review findings
Issue: #306
User-Visible: yes
2026-08-26 14:01:58 +03:00
Matysh a66fb7ef53 feat: unify zero-thickness walls
Issue: #306
User-Visible: yes
2026-08-26 13:39:52 +03:00
Codex c821dad436 build: prepare v1.68.0-beta.2 candidate
Package self-explaining preflight refusals, the universal Thickness tool
and reliable model-v8 room drawing.

Issue: #269
Issue: #295
Issue: #313
Issue: #314
User-Visible: yes
2026-08-26 11:20:47 +03:00
Codex b542f44bd6 fix: preflight diagnostics hash the judged candidate and the fallback dies with its dialog (#295)
CODE-REVIEW-295-r1, both Medium findings:

M1 — _preflightDiagnostics hashed this._serverCfg, the saved config a space
export would reproduce anyway. The hash now comes from the candidate the
preflight actually judged: the report path passes r.config / d.config and the
copy button reads the dialog's own candidate. The smoke no longer masks the
difference — its dialog carries a candidate whose geometry differs from the
saved config, and swapping the two must change the reported hash.

M2 — the inline clipboard fallback survived dialog close and reopen, so a
later refusal could hand the previous refusal's JSON to a bug report. The
field now dies with its dialog: reset on open (_previewAlignDialog) and on
every close path (escape, mode reset, successful apply, hp-close, cancel).

Both regressions are pinned by execution: reverting either fix turns the
extended smoke red (fingerprintTracksCandidate / fallbackClearedOnClose),
and two new gate mutants keep it that way.

Issue: #295
User-Visible: no
2026-08-26 10:52:47 +03:00
Codex 1cdd4ed6de fix: a refused geometry preflight names its reason and hands over diagnostics (#295)
Диалог «Оптимизировать» при отказе перечисляет причину по каждому
пространству (7 значений OptimizeGeometryFailureReason получили RU/EN
строки), даёт «Скопировать диагностику» — JSON-блок с origin: runtime,
версией карточки, отпечатками и классами исключений (граница приватности
checkOptimizeGeometry; privacy-тесты дополнены позитивной проверкой) — и
пишет одну структурированную запись в dev-лог (дедупликация по fingerprint).
При недоступном clipboard блок раскрывается прямо в диалоге.

Совет «обновите House Plan» больше не безусловный: websocket
houseplan/config/get теперь возвращает integration_version (бэкенд-тест),
и подсказка показывается только при реальном расхождении с версией карточки;
старый бэкенд без поля — подсказки нет.

Три новых мутанта (потеря причины в диалоге, блок без reason, отключённый
dev-лог) — краснота каждого проверена исполнением; смок
smoke_preflight_diagnostics на dev падает.

Issue: #295
User-Visible: yes
2026-08-26 10:28:29 +03:00
Matysh 64e9bf8f6b Cover dense v8 draft invariants
Issue: #314
User-Visible: no
2026-08-26 09:56:35 +03:00
Matysh 2347e8df88 Fix atomic model-v8 draft writes
Issue: #314
User-Visible: yes
2026-08-26 09:13:50 +03:00
Codex 676610c0cd fix: align marker.show_entities with the user guide wording (#269)
USER-GUIDE.ru.md — канон формулировок интерфейса (AGENTS.md): флаг диалога
привязки называется «Показывать сущности», как в трёх местах гайда и в
преобладающей форме флагов самого словаря. en.json не меняется.

Issue: #269
User-Visible: yes
2026-08-26 09:04:07 +03:00
Codex ed126d6a43 fix: keep a stored zero draft thickness and guard both thickness writers (#313)
По находкам CODE-REVIEW-313-r1:

High — резолвер больше не превращает сохранённый 0 сегмента драфта в 15:
ноль — легитимное значение (docs/WALL-THICKNESS.md §6), к дефолту 15 падает
только ОТСУТСТВУЮЩАЯ запись. Смок дополнен: hit нулевого сегмента несёт 0,
диалог показывает пустое поле, Apply без правки отказывает и не портит
данные.

Medium — гвард #278 усилен: паттерн допускает перенос строки после скобки,
и счётчик требует РОВНО ДВЕ точки коммита wall_thickness — мутация любой из
них (включая новую независимую) красит юнит; краснота второго патча мутанта
проверена изолированным исполнением.

Issue: #313
User-Visible: no
2026-08-26 08:35:58 +03:00
Codexandclaude[bot] 5e5dad277c fix: the Thickness tool serves standalone walls and saved drafts (#313)
Кандидаты _wallThickHit расширены: интервалы комнат ∪ перегородки ∪ сегменты
сохранённых драфтов (активная цепочка исключена, как в снап-геометрии); при
точном наложении побеждает независимая кладка — она владеет хит-зоной и
рисует видимое тело (решение владельца, согласовано с select и кейсом #308).
Диалог для независимой кладки без кнопки «на всю комнату»; запись — в
partition.cm / draft.segments[i].cm той же физической транзакцией с одним
Undo. Ноль/пусто для независимой кладки отклоняется существующим тостом
диапазона; switch записи — единственный шов, куда #306 повесит ветку
«ноль превращает перегородку в виртуальную стену».

Мутант wall-thickness-writer-bypasses-common-barrier расширен вторым патчем
на новую точку коммита (#278-гвард), краснота обоих проверена исполнением.
Смок smoke_wallthick_standalone: hit/диалог/запись/отказ нуля/приоритет
наложения/hover — на dev падает.

Issue: #313
User-Visible: yes
2026-08-26 05:09:48 +00:00
Matysh a78deb7ce7 build: prepare v1.68.0-beta.1 candidate
Validate / smoke (1) (push) Failing after 25m57s
Validate / smoke (3) (push) Failing after 20m46s
Validate / docs (push) Failing after 40s
Validate / process-workflow-sync (push) Successful in 39s
Validate / golden (push) Failing after 19m23s
Validate / smoke (2) (push) Failing after 34m44s
Validate / changes (push) Successful in 1m2s
Validate / process-gate (push) Failing after 1m5s
Validate / smoke_done (push) Skipped
Validate / hacs (push) Failing after 19s
Validate / hassfest (push) Failing after 18s
Validate / performance_smoke (push) Failing after 21m41s
Validate / provenance (push) Successful in 1m10s
Validate / frontend (push) Successful in 9m51s
Validate / reuse (push) Successful in 56s
Validate / backend (push) Failing after 10m9s
Package stable wall identity, wall junction polish and active-chain visibility.

Issue: #282
Issue: #307
Issue: #309
Issue: #310
User-Visible: yes
2026-08-26 03:27:57 +03:00
Matysh f37efdad8a fix: keep wall-hosted passages open in static view
Issue: #282
User-Visible: yes
2026-08-26 02:53:19 +03:00
Matysh ad54716d21 build: refresh wall model artifacts after dev rebase
Issue: #282
User-Visible: no
2026-08-26 02:23:57 +03:00
Matysh 0f54daf37b fix: preserve passage validation during wall migration
Issue: #282
User-Visible: yes
2026-08-26 02:21:15 +03:00
Matysh 71ac4a6639 fix: enforce wall model barrier in backend optimize
Issue: #282
User-Visible: yes
2026-08-26 02:20:57 +03:00
Matysh e1059e2e29 fix: preserve wall identity through structural edits
Issue: #282
User-Visible: yes
2026-08-26 02:20:57 +03:00
Matysh b336eee996 feat: stabilize persisted wall segment identity
Issue: #282
User-Visible: yes
2026-08-26 02:20:57 +03:00
Codex 0b782ee714 fix: host-gated groups belong to their owner surface; split mixed media wrappers (#266)
CI-шард смока поймал сдвиг каскада, невидимый golden-набору:
smoke_device_icon_design — alert-shell стал серым, dark-unavailable core
светлым. Причина: классификатор считал ведущий :host(...) владельцем
селектора и уносил гейтнутые группы устройств в base — ВПЕРЁД их поверхности,
меняя победителя при равной специфичности. Теперь :host-префикс — гейт, а не
владелец: владелец — первый значимый токен после него; смешанные @media
режутся на последовательные по-зонные копии обёртки (reduced-motion обёрток
стало 12 поверх тех же правил 10 исходных — юнит заякорен на факт, сверка
scope-ключом доказывает, что ни одно правило обёртку не потеряло). Два
мутантных якоря вернулись в devices.styles.ts; исключение юнита
непересечения опустело.

Гейты: refactor-proof diff пуст · golden 129/129 без переприёмки · смоки
device_icon_design, plan_snap_overlay, preloader OK · npm test 1318/0.

Issue: #266
User-Visible: no
2026-08-26 01:55:00 +03:00
Codex 0d9320fe1d refactor: extract the base styles and finish the aggregator (#266 slice 5/5)
52 блока host/переменных/кросс-поверхностных групп → src/styles/base.styles.ts;
styles.ts — 19-строчный сборщик [base, plan, devices, chrome, dialogs] с
задокументированным контрактом порядка каскада. Два оставшихся мутантных
якоря (:host-гейт ховера устройств) переадресованы на base.styles.ts.

Юниты инвариантов (test/styles-split.test.mjs): состав и порядок сборщика;
непересечение (scope+селектор) между файлами — единственное именованное
исключение: кросс-поверхностная группа «:host(...) .dev:hover, .dev:focus-
visible» живёт в base по §1.1; выживание медиа-обёрток — 2 forced-colors и
10 prefers-reduced-motion (в ТЗ и ревью фигурировали 8 — фактический счёт по
исходнику 10, юнит держит точное число). fix-test-build научился точке в
имени модуля (styles/base.styles → .js). ARCHITECTURE.md — раздел Styles.

Refactor-proof diff (scope-ключ) пуст; golden 129/129 без переприёмки; смоки
plan_snap_overlay/preloader OK; npm test 1318/0; бандл 1 291 440 → 1 291 458
(+18 байт).

Issue: #266
User-Visible: no
2026-08-26 01:34:20 +03:00
Codex 55f7126afd refactor: extract the plan surface styles (#266 slice 4/5)
250 блоков сцены плана (stage, стены/оси/снап, декор, iso, resize ink) →
src/styles/plan.styles.ts, склейка [inline, plan, devices, chrome, dialogs].
Refactor-proof diff пуст; golden 129/129; обязательные смоки медиа-обёрток
(spec §7) smoke_plan_snap_overlay (forced-colors) и smoke_preloader
(reduced-motion) — OK; npm test 1315/0.

Issue: #266
User-Visible: no
2026-08-26 01:34:20 +03:00
Codex bf52524de3 refactor: extract the devices surface styles (#266 slice 3/5)
82 блока устройств/маркеров/пылесосов → src/styles/devices.styles.ts, склейка
[inline, devices, chrome, dialogs]. Три мутантных якоря (.dev .valtext,
--dev-size, capsule radius) переадресованы на новый файл. Refactor-proof diff
пуст; golden 129/129; npm test 1315/0.

Issue: #266
User-Visible: no
2026-08-26 01:34:20 +03:00
Codex 7d094fd2ea refactor: extract the dialogs surface styles (#266 slice 2/5)
271 блок диалогов/форм/кнопок/пикеров → src/styles/dialogs.styles.ts, склейка
[inline, chrome, dialogs]. Контрактные тесты, которые греппят CSS-исходник,
переведены на хелпер readAllStylesSource (styles.ts + все импортированные
файлы поверхностей) — greps видят весь лист на любом состоянии сплита.
Refactor-proof diff пуст; golden 129/129; npm test 1315/0.

Issue: #266
User-Visible: no
2026-08-26 01:34:20 +03:00
Codex c684f178cb refactor: extract the chrome surface styles (#266 slice 1/5)
66 блоков тулбаров/вкладок/меню → src/styles/chrome.styles.ts; остальное
инлайном в прежнем порядке, склейка [inline, chrome]. Refactor-proof diff
пуст; golden 129/129 без переприёмки; npm test зелёный.

Issue: #266
User-Visible: no
2026-08-26 01:34:20 +03:00
Codex de0867b001 fix: restore the full pair apex and trim the poking butt end (#310)
Узел ровно двух лучей снова закрывается полным mitre — стены сходятся в
точку, фаска #309 остаётся только веерам узлов ≥3 лучей. Настоящий зубец
убран: pairButtEndTrimWedges возвращает адресный клин — часть тела стены
снаружи наружной грани соседа и не дальше 2·halfDepth от узла — который
physicalBodyParts и превью вычитают из тела до разрезов проёмов. Это второе
адресное вычитание конвейера узлов рядом с латеральным тримом #271.

Узлы-двойки невидимы детектору #302 (карта требует ≥3 лучей): контракт «без
дыр» для них закрыт парным сеточным юнитом (кладка = полосы ∪ патч − клинья)
на spike-узле фикстуры владельца и синтетике. 3 новых мутанта, краснота
каждого проверена исполнением; парный юнит #309 переписан под полное остриё.

Issue: #310
User-Visible: yes
2026-08-25 23:16:19 +03:00
Codex 101cf70952 fix: cap junction mitres at the visual limit and drop foreign-sector pair patches (#309)
Вылет mitre ограничен VISUAL_MITRE_LIMIT = 1.5·max(h): длиннее — плоская
фаска перпендикулярно направлению вершины (chamferApex), в парных патчах и
в веерах узлов. Узлы ≥3 канонических лучей закрываются веерами
junctionNodeGeometry прямо в linearWallJoinPatches: парный патч живёт в
секторе, противоположном своей паре, и красил ступень поверх тонких полос
(крест 15/15/30/30 из отчёта владельца). Прямые углы (вылет 1.41h)
байтово прежние. Механизм #249 (MULTI_WALL_JOIN_LIMIT,
multiWallBevelCutsAt, mitre контуров комнат) не тронут.

Юниты формы на фикстуре трёх узлов владельца + контрактный детектор дыр;
4 новых мутанта, краснота каждого проверена исполнением. Матрица golden 46:
три новые сцены junction-309-{step,spike,hump}-dark.

Issue: #309
User-Visible: yes
2026-08-25 21:50:28 +03:00
Codexandclaude[bot] 1134345444 fix: keep the active chain axis and nodes above the wall bodies (#307)
Каждый клик персистит сегмент цепочки в room_drafts, и его непрозрачная
кладка рисовалась поверх markup-слоя — жёлтая ось и узлы исчезали на уже
поставленных частях. Разметка активной цепочки вынесена в свой слой между
телами стен и снап-оверлеем: ось и узлы видны, снап-геометрия не тронута,
самопривязка по-прежнему запрещена. Смок с пиксельными пробами падает на
прежнем порядке слоёв.

Issue: #307
User-Visible: yes
2026-08-25 16:53:09 +00:00
Matysh 489f68eea9 build: prepare v1.67.0-rc.3 candidate
Package the reviewed S8 work and refresh release metadata and bundles.

Issue: #265
Issue: #301
Issue: #302
Issue: #303
Issue: #304
User-Visible: yes
2026-08-25 19:12:27 +03:00
Codex d3927f2e56 build: rebundle on the merged tree (#302)
Обе копии байт в байт; npm test 1304/1304 на объединённых исходниках.
Ссылка ниже — прогон, подтверждающий ревью кода, из которого бандл собран.

Issue: #302
User-Visible: no
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/32859268589
2026-08-25 17:44:16 +03:00
Codex d3ed299d2a refactor: fans are the whole additive node — dead support re-union removed (#302)
С адресным тримом (он не режет полосы обычных узлов) возврат саппорт-квадов в
тело стал мёртвым слоем: полный юнит-набор зелёный без него — проверено
исполнением, а не предположено. По дисциплине мутационного реестра
избыточный слой убран (fans only), его мутант `junction-supports-not-restored`
снят: у #271-узлов трим режет только ЗА пределами саппорта, возвращать
нечего. Саппорт-квады остаются экспортом `junctionNodeGeometry` — детектор и
тесты используют их как источник контрактной истины.

`npm test` 1303/1303; `golden:verify` 126/126; контракт-проба репро — 0;
`smoke_junction_holes` OK.

Issue: #302
User-Visible: no
2026-08-25 17:34:19 +03:00
Codex ec8dc6fde1 fix: close both code-review mediums and drop the dead paper layer (#302 r1 M1,M2)
**M1.** `docs/WALL-THICKNESS.md` §3 «Junction nodes» переписан под решение №5:
полный mitre, фаска #249 в отставке, `bevelMultiWallBody` — только адресный
латеральный трим. Прежний абзац описывал отменённое утреннее решение.

**M2.** Guard мутанта `junction-fans-disabled` собирает `test-build` и бандл
перед смоком: `smoke_junction_holes` — единственный смок, импортирующий из
`test-build`, и в чистом worktree он падал `ERR_MODULE_NOT_FOUND` до
применения мутации. Ревью прав: после переякорения guard'а на смок я не
перегнал его штатным харнесом — только ручной test-build-патч, который worktree
не видит.

**Low + следствие.** `bevelMultiWallPaper` удалена как мёртвый код; следом
измерено (фикстура #197 и репро владельца — байт в байт с веерами и без), что
и `paperWithNodeCorners` бумаге ничего не даёт: footprint ∪ shell уже
покрывает каждый узел. Слой удалён целиком, бумага возвращена к rawPaper.
Осиротевший мутант `multi-wall-paper-full-origin-cut` (#261, «белый клин от
вычитающего разреза бумаги») снят с обоснованием: в бумаге не осталось ни
одного вычитания — этот класс регресса невозможен по построению.

`npm test` 1303/1303; `golden:verify` 126/126; контракт-проба репро — 0.

Issue: #302
User-Visible: no
2026-08-25 17:34:19 +03:00
Codex 9dbdbec03d build: rebundle and mend the baseline manifest after the rebase onto #265 (#302)
Ребейз на свежий dev (#265 import seam + его эталон) слил baselines-index из
двух источников; поштучное слияние потеряло `matrixVersion: 45` и держало
хэши двух сцен, чьи PNG пришли из dev. Индекс поправлен по фактическим
файлам, `golden:verify` — 126/126 с валидным манифестом. Бандл и отпечаток
скриншотов пересобраны из объединённых исходников (`npm test` 1303/1303).

Issue: #302
User-Visible: no
Release: v1.68.0-beta.1
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/32848447191
2026-08-25 17:34:19 +03:00
Codex aac501516e feat: full mitre at every node — the #249 chamfer retires (#302, decision #5)
Владелец, осмотрев первые эталоны сета, отменил дневное решение о сохранении
фаски: `junction-y-60-equal50` показывал вырез, `junction-acute30-mixed` —
торчащие углы. По визуальному сравнению трёх вариантов принято: узлы
смыкаются полным mitre, как обычное пересечение стен на чертеже.

Итоговое правило веера (одно на все случаи):

- mitre принимается, когда он В СЕКТОРЕ пары (вперёд по лучам для обычной
  пары, назад — для рефлексной: наружный угол между крайними лучами, где и
  жил вырез Y-60), в пределах классического `MITRE_LIMIT` и не дальше конца
  толстого саппорта (#271);
- рефлекс без валидного mitre замыкается плоской хордой между гранями;
- обычная пара без mitre — локальный бевел: ход по граням ограничен толстым
  саппортом, лимитом и двойной толщиной пары, чтобы хорда осталась деталью
  угла. Гигантские бевел-«бабочки» и mitre вне сектора — две реальные ошибки
  промежуточных версий, обе пойманы на сценах сета до пуша.

Слой `bevelMultiWallBody` сохранён только как АДРЕСНЫЙ латеральный трим для
узлов с вырожденно-коротким толстым саппортом (#271); все прочие узлы — чисто
аддитивные, следы трима на них исчезли. `bevelMultiWallPaper` из бумаги
удалён. Обе записи CHANGELOG приведены к финальному контракту.

Тесты: юниты §302 усилены; площадь фикстуры #197 +0.6 юнита²; мутанты
переякорены, краснота каждого проверена исполнением.

Issue: #302
User-Visible: yes
2026-08-25 17:34:19 +03:00
Codex ef22c2c6fd build: rebundle after the rebase onto #301/#303 (#302)
Ребейз на свежий dev (поиск в селекторах проёмов #301, честная подсветка
толщины #303) объединил исходники; бандл и отпечаток скриншотов пересобраны
из результата. Обе копии бандла байт в байт; `check-docs` passed; полный
`npm test` 1298/1298 и golden verify 126/126 на объединённом коде.

Issue: #302
User-Visible: no
2026-08-25 17:34:19 +03:00