Commit Graph
126 Commits
Author SHA1 Message Date
Matysh 69e410fea3 fix: materialize empty wall catalog for new spaces
Issue: #324
User-Visible: yes
2026-08-27 16:33:47 +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 a66fb7ef53 feat: unify zero-thickness walls
Issue: #306
User-Visible: yes
2026-08-26 13:39:52 +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 2347e8df88 Fix atomic model-v8 draft writes
Issue: #314
User-Visible: yes
2026-08-26 09:13:50 +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 fc9f513082 test: align import fixtures with wall model v8
Issue: #282
User-Visible: no
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
Matysh 2143e88824 test: close import seam review gaps
Validate / reuse (push) Successful in 1m13s
Validate / hacs (push) Failing after 24s
Validate / hassfest (push) Failing after 33s
Validate / frontend (push) Successful in 6m16s
Validate / backend (push) Failing after 7m3s
Validate / smoke (3) (push) Failing after 18m38s
Validate / smoke (2) (push) Failing after 19m10s
Validate / golden (push) Failing after 23m1s
Validate / smoke (1) (push) Failing after 45m54s
Validate / smoke_done (push) Skipped
Validate / performance_smoke (push) Failing after 50m53s
Validate / process-workflow-sync (push) Successful in 34s
Validate / docs (push) Successful in 51s
Validate / provenance (push) Successful in 1m16s
Validate / process-gate (push) Failing after 1m16s
Validate / changes (push) Successful in 46s
Issue: #265
User-Visible: no
2026-08-25 15:16:40 +03:00
Matysh 51810164c2 refactor: unify import reference seam
Issue: #265
User-Visible: yes
2026-08-25 14:47:04 +03:00
Sergey Matyunin b9db5d4750 fix: close #296 review gaps
Issue: #296
User-Visible: yes
2026-08-24 22:50:00 +03:00
Sergey Matyuninandclaude[bot] 89ac96a8af fix: reconcile hidden walls during Optimize
Issue: #296
User-Visible: yes
2026-08-24 19:10:27 +00:00
Sergey Matyunin 4ccf4a3ccc fix: enforce exact lattice coordinates
Issue: #291
User-Visible: yes
2026-08-24 17:13:21 +03:00
Sergey Matyunin 07bd1a6781 fix: reconcile outer walls before resize
Issue: #281
User-Visible: yes
2026-08-24 10:43:33 +03:00
Sergey Matyunin 38ea8a9b9e fix: validate optimize opening rehosts
Issue: #280
User-Visible: yes
2026-08-24 10:33:05 +03:00
Matysh a952f5fd07 feat(api): let config/get and layout/get return less
Issue: #256
User-Visible: no
2026-08-23 10:22:51 +03:00
Sergey Matyunin 120b491eba test: require schema-valid Optimize fixture
Issue: #248
User-Visible: no
2026-08-23 01:24:49 +03:00
Sergey Matyunin cbdd5a7e73 fix: keep Optimize idempotent across storage reload
Issue: #248
User-Visible: yes
2026-08-23 01:13:27 +03:00
Sergey Matyunin 6a151d1ead fix: preserve markers when deleting final space
Issue: #244
User-Visible: yes
2026-08-23 00:35:48 +03:00
Sergey Matyunin f6f877e393 fix(spaces): repair orphaned plan references
Issue: #244
User-Visible: yes
2026-08-23 00:34:55 +03:00
Sergey Matyunin 4a798e3e13 fix: canonicalize persisted geometry
Issue: #224
User-Visible: yes
2026-08-22 14:47:38 +03:00
Codex 2935c293e1 fix: reject absolute urls in the content resolver, register the mutants
Review CODE-REVIEW-225-r1.

M1: urlsplit(url).path was trusted even when the url carried a scheme or an
authority, so "https://evil.example/houseplan_files/files/m1/doc.pdf"
resolved onto a local file while _looks_internal kept calling it external —
the mirror image of the inconsistency this resolver exists to prevent. Only a
same-document reference is resolved by its path now.

M2: the three mutants the spec described are registered in
scripts/mutation-gate.mjs instead of living as a one-off manual run. The
traversal entry drops both structural checks at once on purpose: taken one at
a time the defence is layered (sanitize_marker_id turns ".." into "misc") and
the mutant would be equivalent — established by running it.

Issue: #225
User-Visible: no
2026-08-20 22:00:22 +03:00
Codex 4a84734b18 fix: resolve internal content urls by path, not by string
A backup holding a PDF attachment could not be imported back: legacy links
carry a cache-buster (".../files/m1/doc.pdf?v=1783170649"), and the resolver
compared the raw tail with its sanitized form, so the query made the name
differ from itself. The reference then read as internal by prefix and
non-canonical by name, which is exactly the combination _content_state must
refuse — every such document failed with invalid_content.

Parse the url as a url: the path addresses the file, the query and the
fragment address the transfer. Path segments keep doing the guarding, so
dropping the query cannot widen what a segment is allowed to be.

Issue: #225
User-Visible: yes
2026-08-20 22:00:22 +03:00
Sergey Matyunin 56e01148f8 fix: resume vacuum trails after short stops
Issue: #205
User-Visible: yes
2026-08-19 20:55:38 +03:00
Sergey Matyunin 57ba75b9da fix: keep jamb margin on partition openings
Issue: #186
User-Visible: yes
2026-08-19 15:43:23 +03:00
Sergey Matyunin 3fe0f8c443 fix: address partition opening review regressions
Issue: #132
User-Visible: yes
2026-08-19 01:34:51 +03:00
Sergey Matyunin 9f77e3e932 feat: support openings in independent walls
Issue: #132
User-Visible: yes
2026-08-19 01:11:55 +03:00
Sergey Matyunin 8086399aa6 feat: select exact toggle entity
Issue: #178
User-Visible: yes
2026-08-18 21:31:04 +03:00
Sergey Matyunin c9a00b2a37 feat: add open passage openings
Validate / docs (push) Failing after 20s
Validate / provenance (push) Successful in 54s
Validate / hacs (push) Failing after 15s
Validate / process-gate (push) Failing after 50s
Validate / changes (push) Successful in 46s
Validate / hassfest (push) Failing after 14s
Validate / frontend (push) Successful in 5m54s
Validate / backend (push) Failing after 8m1s
Validate / smoke (push) Failing after 4m25s
Validate / golden (push) Failing after 4m26s
Validate / performance_smoke (push) Failing after 8m39s
Issue: #157
User-Visible: yes
2026-08-17 16:45:41 +03:00
Sergey Matyunin a1b8861eff fix: preserve plan-only room label scale
Issue: #167
User-Visible: yes
2026-08-17 13:16:04 +03:00
Sergey Matyunin b369eb5dcd test: preserve ordinary space layout scope
Issue: #167
User-Visible: no
2026-08-17 12:34:45 +03:00
Sergey Matyunin 7f397a6875 feat: add plan-only space export
Issue: #167
User-Visible: yes
2026-08-17 12:33:52 +03:00
Sergey Matyunin f2fcf0d594 Release v1.64.0-beta.2 candidate
Validate / changes (push) Successful in 40s
Validate / provenance (push) Successful in 46s
Validate / process-gate (push) Failing after 45s
Validate / hacs (push) Failing after 12s
Validate / hassfest (push) Failing after 13s
Validate / frontend (push) Successful in 8m16s
Validate / backend (push) Failing after 8m22s
Validate / smoke (push) Failing after 3m27s
Validate / golden (push) Failing after 9m42s
Validate / performance_smoke (push) Failing after 13m13s
Issue: #146
User-Visible: yes
2026-08-14 18:14:02 +03:00
Sergey Matyunin debb13baa2 feat: add four-phase sun background
Issue: #146
User-Visible: yes
2026-08-14 17:17:25 +03:00
Matysh e6366b6548 fix: load virtual_lights by path so offline collection survives
The file declared itself pure but imported the module through the package, and
the package __init__ unconditionally imports homeassistant. Without homeassistant
installed pytest did not skip the file — it stopped collecting the whole
tests_backend directory, taking the previously working pure suite down with it.
test_validation.py had already established the by-path pattern; virtual_lights.py
imports nothing beyond the standard library, so it loads cleanly.

The async tests also dropped their pytest-asyncio dependency in favour of
asyncio.run: the offline environment does not carry the plugin, and without it
the two tests failed as unsupported async defs. The offline gate has to be green,
or nobody runs it.

Verified in both environments: pytest+voluptuous only — 129 passed where
collection previously stopped dead; with pytest-asyncio as in CI — 129 passed.

Issue: #135
User-Visible: no
2026-08-14 10:10:34 +03:00
Sergey Matyunin 1079cdfab2 feat: add persistent virtual light toggles
Issue: #107
User-Visible: yes
2026-08-14 03:32:53 +03:00
Matysh 661eb784fb Fix beta.8 validation regressions
Issue: #75
Issue: #95
Issue: #98
User-Visible: yes
2026-08-12 19:38:34 +03:00
Matysh 9e74051652 Release v1.62.0-beta.8 candidate
Issue: #75
Issue: #76
Issue: #95
User-Visible: yes
2026-08-12 19:18:54 +03:00
Matysh c41231a7ba Release v1.62.0-beta.3 candidate 2026-08-12 02:33:54 +03:00
Matysh 554d2e6544 Release v1.62.0-beta.2 candidate 2026-08-11 22:12:08 +03:00
Matysh 446f33ed31 Release v1.62.0-beta.1 candidate 2026-08-11 19:15:21 +03:00
Matysh f8f1718ad2 Release v1.61.0-beta.5 candidate 2026-08-10 18:01:16 +03:00
Matysh 1ed281b0dd Release v1.61.0-beta.4 candidate 2026-08-10 14:32:20 +03:00
Matysh cd55a8e897 Release v1.61.0-beta.3 candidate 2026-08-10 09:44:31 +03:00
Matysh fb382bfa11 Release v1.61.0-beta.2 candidate 2026-08-10 00:24:42 +03:00
Matysh 112c260314 Release v1.61.0-beta.1
Validate / hacs (push) Failing after 12s
Validate / hassfest (push) Failing after 13s
Validate / frontend (push) Successful in 3m2s
Validate / golden (push) Failing after 51s
Validate / backend (push) Failing after 6m50s
Validate / smoke (push) Failing after 13m44s
Validate / performance (push) Failing after 24m13s
2026-08-09 21:51:33 +03:00
Matysh e177c14603 v1.60.3-beta.1: harden rendering and QA tooling 2026-08-08 21:33:09 +03:00