Commit Graph
318 Commits
Author SHA1 Message Date
Codexandclaude[bot] e758c3d9fb fix: quantise the light aperture amount of moving covers (#366)
A gate or door bound to a position-reporting cover fed current_position
into the light-barrier signature at toFixed(3) precision: every percent of
movement produced a new fingerprint, a full physicalBodyParts recompute
and a recut — up to ~100 heavy passes per gate cycle, plus LRU churn.

The light pipeline now consumes one quantised amount
(OPENING_LIGHT_AMOUNT_QUANTUM = 0.05, exact 0 and 1 nodes) at the single
point that feeds BOTH the signature and the cut geometry, so the cache key
and the drawn aperture agree by construction and a full sweep costs at
most 21 recomputes. The door LEAF animation stays smooth — _openingAmt is
quantised only for the light pipeline, nowhere else. Binary contact doors
are byte-identical to the previous behaviour (pinned by unit).

Assumption recorded in the spec: the 5% visual step of the light cut is
indistinguishable on real plans; if field impressions disagree, the
quantum is a one-constant change (0.02 => <=51 recomputes) or the decision
falls back to a debounce. LIGHT.md §Caching documents the grid.

Issue: #366
User-Visible: yes
2026-08-29 08:15:51 +00:00
Sergey Matyuninandclaude[bot] 953eda4f6e fix: scale furniture strokes with plan zoom
Issue: #361
User-Visible: yes
2026-08-29 07:55:23 +00:00
Codex 7c31725ac9 feat: warn about huge backdrops and offer a safe reduced copy (#39)
A picked raster is now classified from its HEADER BYTES ONLY before anything
heavy happens: src/backdrop-probe.ts parses PNG IHDR (+colour type/tRNS for
alpha), JPEG SOF and WebP VP8/VP8L/VP8X at fixed offsets, never using a file
field as an allocation size; hostile or truncated headers collapse to
'unknown', which warns without numbers instead of passing silently. The
thresholds live in that module as the single calibration point
(WARN_DECODED_BYTES 128 MiB ≈ 32 MP, HARD_DIMENSION 16384 — the browser
canvas cap, DOWNSCALE_TARGET_PX 4096), derived from the desktop-Chromium
matrix now committed as demo/benchmark_backdrop_decode.mjs with a
conservative tablet margin documented in the spec.

The shared pick flow (src/backdrop-pick.ts) feeds BOTH lazy runtimes — the
editor space dialog and the onboarding first-space dialog — so the guard
cannot drift between them, and nothing of it enters the eager View graph.
Warn shows the real numbers and three actions; the reduced copy decodes
EXIF-aware, keeps aspect and alpha (PNG stays PNG, opaque becomes JPEG
q0.9) and flows through the ordinary planFile → upload path. Hard has two
phases with one outcome: beyond 16384 px only Cancel; a failed or timed-out
(10 s) reduce closes with a toast, clean staging and NO silent fallback to
the original the user just declined. SVG never reaches the probe. The safe
path swaps the manual byte-loop base64 for FileReader — half the JS-heap
peak on every upload, byte-identical output (parity asserted in the smoke).

Proofs: header-table units incl. a fuzz set of hostile headers and ±1
threshold bounds; smoke_backdrop_guard on the real bundle — zero decode
calls before the choice, byte parity of keep-original, a real 6200 px
reduce to 4096 for both alpha and opaque branches, cancel-only hard
dialog, both phase-2 failures (reject and hang under the test-only timeout
override), re-pick after refusal, SVG bypass; four registry mutants
(probe-always-safe, alpha-dropped, hard-demoted, phase-2 silent fallback).
Spec anchor corrected alongside: the server plan limit is 8 MB
(MAX_PLAN_BYTES), attachments are the 50 MB path — an 8 MB JPEG is easily
80-160 MP decoded, so the client-side guard stays the primary defence.

Issue: #39
User-Visible: yes
2026-08-29 10:13:09 +03:00
Sergey Matyuninandclaude[bot] 5d37438e11 fix: make devices inert in the Background editor
Issue: #362
User-Visible: yes
2026-08-29 06:39:28 +00:00
Matysh e728eab876 build: prepare v1.69.0-beta.3 candidate
Проверка (CI) / Классификация изменённых файлов (push) Successful in 16s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 14s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 15s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 35s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 40s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 59s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 3m47s
Package door-state-aware Glow, smoothed vacuum trails, cold-View reliability fixes and the furniture placement preview reviewed since beta.2.

Issue: #20
Issue: #209
Issue: #357
Issue: #358
Issue: #359
User-Visible: yes
2026-08-29 01:14:03 +03:00
Matysh fd762fa744 fix: restore reviewed furniture preview tree
The code-review worker published its report from a stale local snapshot and unintentionally reverted the already reviewed implementation artifacts. Restore every affected path exactly to the reviewed 84bdc7ef tree while retaining CODE-REVIEW-359-r1.md.

Issue: #359
User-Visible: no
2026-08-29 00:51:43 +03:00
claude[bot] bb2919f8c0 docs: review document for #359
Issue: #359
User-Visible: no
2026-08-28 21:49:12 +00:00
Matysh 8b66d67d3d feat: preview furniture placement
Issue: #359
User-Visible: yes
2026-08-29 00:34:06 +03:00
Matysh 9d2ef12c96 feat: smooth vacuum trails (#209)
Issue: #209
User-Visible: yes
2026-08-28 23:16:58 +03:00
Matysh f62926fbeb feat: make Glow follow door opening state (#20)
Issue: #20
User-Visible: yes
2026-08-28 22:33:07 +03:00
Codex bb3c1fd12f fix: a cold View survives a telemetry-bearing vacuum (#358)
Systematic audit after #357 ("can there be more bugs with this root
cause?"): _vacMapId was the one remaining hard stub reachable from the
eager View path. It runs inside willUpdate for every vacuum whose
integration reports live telemetry (Tasshack, XCME, Valetudo), so on a
cold tab the #337 stub threw there and the exception took the whole Lit
update cycle with it — the card froze on its very first frame. The demo
mower has no position attributes, telemetry resolved to null, and every
existing smoke (warm and cold) sailed past the branch.

The card now owns the implementation (both dependencies — _vacEntity and
vacMapIdWithFallback — were already eager); the editor runtime delegates
back to the host. The HP-1541-01 invariant (selected_map: 0 is a real map
id, nullish not truthy) moves verbatim and is pinned by the new smoke.

Hardened alongside (audit Lows): _decorShapeDown gets the same
cold-tab guard its twin _decorShapeDbl received in #337 — decor shapes
render in View and CSS pointer-events alone must not be what prevents a
throw; the _vacCalConfirm dialog renders behind the same _editorRuntime
gate as every other editor dialog instead of relying on the implicit
"only the runtime ever sets it".

smoke_cold_view_vacuum: cold tab, vacuum with vacuum_position and
selected_map: 0 — the card commits three successive telemetry frames
(willUpdate alive, not merely the first paint), map id resolves to '0',
no editor chunk requested, a decor pointerdown is a quiet no-op. A
registry mutant restores the delegation and is killed by that smoke.

Issue: #358
User-Visible: yes
2026-08-28 21:49:50 +03:00
Codex 49174e81f7 fix: a cold View resolves taps without the lazy editor runtime (#357)
Field report from the dacha: the wall switch "Гостиная основной свет",
whose controls name three virtual light sources, periodically ignored taps
— no toggle, no glow — until its settings dialog was opened once with no
changes. "Periodically" was every fresh tab: the #337 lazy split left
_toggleIntent (and the confirm-line helpers) on the card as stubs
delegating into the editor runtime, so a plain View tap on a cold tab
threw `Houseplan editor runtime is not loaded` synchronously inside the
click handler. Opening any editor surface loaded the runtime and "healed"
the tab for its lifetime.

The View card now owns toggle resolution: _toggleIntent calls
resolveToggleIntent directly (device-toggle.ts was already in the initial
graph; the card owns _planHass/_fullRegistryHass/_virtualLights), and
_toggleStateText/_toggleConfirmationStateText/_toggleConfirmationLines
moved with it. The editor runtime delegates back to the host — one source
of truth, editor consumers (dialog preview, hint lines) unchanged.

Every product smoke preloads the runtime, so none of them could see this
class of regression. The new smoke_cold_view_toggle mirrors the field
config on a genuinely cold tab: a real switch drives three passive
virtual lamps with one tap, a controlled lamp drives its switch back,
tap_confirm renders its state lines and confirms, and the editor chunk is
never requested. A registry mutant restores the old delegation and is
killed by that smoke.

Issue: #357
User-Visible: yes
2026-08-28 21:02:19 +03:00
Matysh 399df907ee build: prepare v1.69.0-beta.2 candidate
Проверка (CI) / Классификация изменённых файлов (push) Successful in 15s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 45s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 25s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 27s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 44s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 4m29s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 5m39s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Package the expanded furniture library, room-aware climate placement, controller-state parity, resilient editor delivery, revision-safe writes and the reviewed supporting fixes since beta.1.

Issue: #159
Issue: #317
Issue: #318
Issue: #335
Issue: #339
Issue: #340
Issue: #341
Issue: #353
Issue: #354
Issue: #356
User-Visible: yes
2026-08-28 20:37:13 +03:00
Matysh 7909ab6eed feat: expand furniture library
Issue: #159
User-Visible: yes
2026-08-28 18:52:03 +03:00
Codex 1397afefd5 fix: the locale runtime the card ships is the code the tests prove (#354)
The production LANGUAGE_RUNTIME was a handwritten twin of the tested
LanguageRuntime class (germanDictionary/Pending/Failed): equivalent on the
day it was written, invisible to every i18n-runtime test afterwards. The
registry now exports one page-scoped `new LanguageRuntime(LANGUAGE_REGISTRY,
…)` instance — the whole existing suite starts proving the object production
actually runs, and a contract unit (instanceof + source free of the old
field names) keeps the duplicate from returning.

The class gains an optional `loadFailed(code)` hook — fired once when a
dictionary load settles into English fallback — and the registry fans it out
through `subscribeLanguageLoadFailures`. Only the View card subscribes (it
alone owns toast infrastructure): a failed language pack now shows the new
`toast.locale_load_failed` message (en/ru/de) instead of a console-only
warning; space card and both GUI editors keep the console warning as before.

Proofs: contract unit, hook unit, subscription unit; smoke_german_locale
extended — the both-attempts-failed scenario now asserts the visible toast;
two new registry mutants (handwritten-twin returns, toast dropped).

Issue: #354
User-Visible: yes
2026-08-28 17:49:59 +03:00
Codexandclaude[bot] 78c6020747 fix: lazy delivery survives flaky networks and stale caches (#353)
Network failure of the editor runtime is no longer terminal: the loader
re-arms to idle and the next explicit press starts a fresh cycle, while a
fingerprint mismatch on either attempt stays terminal. The toast now says
what actually helps — retry advice for the network, refresh advice for a
foreign build — via one shared lazyLoadFailureMessage helper (new i18n key
editor.retry_advice in en/ru/de).

The field smoke caught a second, deeper bug on the way: Chromium records a
FAILED module in the page module map permanently, so retrying the same URL
(even the cache-busted one) never touched the network again. Every retry
now carries a per-cycle nonce and becomes a genuinely new module request.

A proxy-cached stale entry no longer kills the card silently: the entry
facade is rewritten at build time from a static re-export into a top-level
`try{await import(...)}catch{...}` — importers keep the happy-path
guarantee (await import(entry) still resolves only after
customElements.define), and the catch defines a fallback element with a
localized "reload the page" panel. Content-hashed chunks are served with
`public, max-age=31536000, immutable`, and verifyBundleTree now fails on
orphan chunks that the manifest does not name.

Proofs: loader units for re-arm/terminality/toast wording + an AST check
that both loaders forward the terminality flag; smoke_entry_stale (en/ru)
against a tree without the main chunk; smoke_lazy_editor_chunk extended —
second press after network failure now really opens the editor; pytest for
the immutable header; orphan-tree unit; five new registry mutants.
TESTING.md budget line updated to the #352 ceiling alongside.

Issue: #353
User-Visible: yes
2026-08-28 14:32:08 +00:00
Matysh 24c9a169ac fix: require revision for saved layout replacements
Issue: #356
User-Visible: yes
2026-08-28 17:23:01 +03:00
Matysh 6c9752f5e6 fix: follow marker placement for room climate
Issue: #317
User-Visible: yes
2026-08-28 16:48:10 +03:00
Matyshandclaude[bot] 72913fee84 fix: show entityless active controllers
Issue: #318
User-Visible: yes
2026-08-28 13:07:58 +00:00
Matyshandclaude[bot] 3e437ca3ec fix: reject config writes without a revision
Issue: #340
User-Visible: yes
2026-08-28 11:26:19 +00:00
Matyshandclaude[bot] ca16d1fe59 Fix vacuum trail lifecycle persistence
Issue: #335
User-Visible: yes
2026-08-28 11:01:40 +00:00
Codexandclaude[bot] ac077d9b6d fix: a mixed-thickness legacy apex converges honestly (#339)
isDegenerateApexCorner measured the inner-face convergence as
max(h1,h2)/tan(theta/2) — for a 10-degree apex between a 15 cm and a 30 cm
wall that overstates the distance (171.5 cm against the true 128.3/128.9 on
160 cm edges), the corner failed the "inside both edges" test and rendered
as the #329 trident again. Worse, the verdict depended on which neighbouring
edge carried the thicker wall.

The check now intersects the two actual face lines: the meeting point lands
at (hOther + hOwn*cos(theta))/sin(theta) along each edge, degenerate only
when inside both. With equal halves this reduces algebraically to the old
h/tan(theta/2), so equal-thickness verdicts are unchanged by construction —
pinned by the untouched section-4 units and the full golden matrix (136
scenes verified). New units cover both traversal orders of the mixed apex,
the one-point outset tip, the 30-degree ordinary pair and the zero-thickness
guard.

The write path is untouched: P1 forbids new sub-15-degree corners since
issue 329, this is purely how a legacy document renders.

Issue: #339
User-Visible: yes
2026-08-28 10:46:27 +00:00
Matysh 801e49092f fix: keep lazy editor release version synchronized
Issue: #337
User-Visible: yes
2026-08-28 12:47:30 +03:00
Matysh 58ebf8b4cd build: prepare v1.69.0-beta.1 candidate
Проверка (CI) / Классификация изменённых файлов (push) Successful in 18s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 40s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 51s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 15s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 22s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 11m19s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 11m46s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Package the complete German interface, the unified Device lifecycle catalog,
wall-junction correctness and performance work, and the supporting delivery
infrastructure reviewed since v1.68.1.

Issue: #29
Issue: #62
Issue: #264
Issue: #267
Issue: #329
Issue: #330
Issue: #331
Issue: #333
Issue: #337
Issue: #348
User-Visible: yes
2026-08-28 12:24:15 +03:00
Matysh 12cd8a1af3 feat: add complete German localization
Add Deutsch across all card surfaces and backend flows, backed by the language registry introduced in #62. German loads as a fingerprint-checked page-shared locale chunk so EN/RU remain synchronous and the initial View budget stays intact. Root render gates prevent mixed-language flashes, retry once, and fail open to English. Extend parity, runtime, bundle, browser and visual coverage, plus contributor and user documentation.

Issue: #348
User-Visible: yes
2026-08-28 11:58:46 +03:00
Matyshandclaude[bot] 2c65fcec03 perf: lazy-load editor runtime
Issue: #337
User-Visible: yes
2026-08-28 05:40:28 +00:00
Codex 508945c088 fix: a 0° pair is the shared-wall model, not a duplicate — field revert of #331 §2.2
Red dev caught it ninety minutes after the merge: smoke_plan_drawing_repairs
and smoke_resize_pointer_real_plan went red because the new "a 0° wedge is
always a duplicate" rule refused two ordinary edits — creating a room over
an existing partition ring (#308's legal overlay) and resizing a wall until
it lands on a neighbour's. The premise was wrong at the model level: a
shared wall of two adjacent rooms IS two co-located owner atoms on one line,
so every shared-wall node carries a legitimate 0° pair by construction.
Bisection pinned the exact cut: with only the 0° rule reverted, both smokes
are green again; keys, incidence, the iterative walk and fail-closed stay.

Spec revision 4 records the revert and returns "an exact duplicate wall is
invisible to П1" to the status of a KNOWN LIMITATION — an honest detector
needs owner identity, which is a separate decision for the owner to make.
The zero-wedge mutant is removed with its rule; the .5-tick parity unit now
observes quantisation through valence instead of the retired duplicate
visibility; changelogs drop the over-promise.

Issue: #331
User-Visible: yes
2026-08-28 05:20:45 +03:00
Codex 58f3acbbde fix: junction limits are honest at the boundaries (#331)
Six normative cuts, both mirrors symmetric (spec revision 3):

- §2.1 node keys quantise to 1e-7 with the repository's canonicalisation
  formula (sign·floor(|v|·1e7+0.5)/1e7, -0 normalised) — toFixed(6) keys
  split one node into two on floating debris and produced two false П4
  refusals on a legitimate resize (reproduced: -1e-8 vs 0). Node pairs
  within 2e-7 of each other (raw coordinates) are ONE node, and the
  node-to-wall incidence uses the same quantum.
- §2.2 a ~0° wedge IS a violation: two rays leaving a node the same way are
  a duplicated or overlaid wall (a butt joint yields 180°, never 0°) — the
  worst degenerate case was invisible while 0.5° was refused.
- §2.3/§2.4 the wall run is an iterative edge walk over the collinear
  component: no recursion (10 000 atoms answered, not RangeError), no
  silently dropped fork (the old .find lost every branch but the first),
  O(E) by construction, and collinearity is measured against the BASE
  segment's axis so an arc of 0.9°-per-atom pieces cannot pose as one wall.
- §2.5 an exception while judging the CANDIDATE refuses the write with the
  junction.limit_check_failed toast (fail-closed, as the #278 guard); the
  baseline branch stays fail-open by design and the smoke proves the
  asymmetry by breaking only the second call of the deterministic pair.
- §2.6 the python mirror narrows its except on the candidate side only:
  a genuine migration bug (TypeError) surfaces as an honest WS error, while
  a previous-side bug keeps the wide "no baseline" fallback — the two AC6
  cases pin the asymmetry so swapped sides turn a unit red.

Parity fixtures gain the new boundary classes (debris node, duplicate wall,
collinear fork); four new mutants pin the filter, the key precision, the
dropped branch and the fail-open hole.

Issue: #331
User-Visible: yes
2026-08-28 04:39:46 +03:00
Codex c90f5bf052 perf: junction limits scale — executor, rev cache, linear П3/П4, shared masonry pass (#330)
Six cuts, zero verdict changes (spec §3; equivalence pinned by units, the
parity suite and the smokes):

- §4.1 the CPU chain of ws_config_set and ws_plan_optimize runs in the
  executor; write_lock still serialises writes, only the HA event loop is
  freed (2.8 s of blocking per 576-atom write before).
- §4.2 the stored document's violation counts are cached on the runtime by
  rev (store.py junction_baseline); a repeated write never re-judges
  `previous`. validate_junction_limits takes baseline_counts and returns the
  candidate's counts to cache after a successful save.
- §4.3 П3 builds its node index once per check in both mirrors
  (289→11 ms TS, 285→~50 ms py).
- §4.5 П4 uses a bucket grid with the threshold as cell size in both
  mirrors (104→19 ms TS, 372→44 ms py); pair enumeration switches to
  lexicographic order — same verdict set, equivalence pinned against a
  brute-force oracle on cell borders.
- §4.6 a document already carrying the current catalogue is judged as-is:
  a no-op re-migration cost 815 ms py / 69 ms TS. Legacy documents migrate
  exactly as before (the #329 H1 test stays green).
- §4.7 П5 shares one junction-topology pass per check and pays the masonry
  union only when multi-wall nodes exist — and the resize path hands over
  the preflight's own artifact, so a pointermove never builds the union
  twice (4.2 s → 88 ms full candidate on the benchmark grid).

The frontend baseline is cached per (document identity, config epoch): ten
pointermoves make N+1 limit computations, not 2N — pinned by the smoke on a
real pointer gesture.

demo/benchmark_junction_limits.mjs (npm run benchmark:junction-limits) pins
the budgets for both mirrors: TS full candidate ≤100 ms (measured 88), py
warm validate ≤250 ms (measured 45), cold legacy ≤3.5 s — that path is
one-off and lives in the executor.

Issue: #330
User-Visible: yes
2026-08-28 03:07:11 +03:00
Matyshandclaude[bot] aa9444491d fix: align device catalog with plan rooms
Issue: #29
User-Visible: yes
2026-08-27 23:17:53 +00:00
Matyshandclaude[bot] cab8d128bf feat: add device lifecycle catalog
Issue: #29
User-Visible: yes
2026-08-27 23:17:52 +00:00
Codex f514fb27fe feat: junction limits refuse the write in every editing surface (#329)
П3 measures the WALL, not the catalogue atom: a short filler segment that
compensates a thickness step (owner's fixture, 5 cm = (30-20)/2) is a legal
continuation of a long same-thickness wall, so the rule walks the maximal
collinear run through the shared nodes before judging the length.

Resize stops at the last allowed position and names the broken rule instead
of the generic "geometry cannot be saved"; the Thickness dialog refuses
through its own toast. Both channels are pinned by demo/smoke_junction_limits
plus three mutants (angle threshold, write barrier, degenerate apex bevel).

Issue: #329
User-Visible: yes
2026-08-27 23:31:42 +03:00
Codex 214355f424 fix: a degenerate sharp corner renders as a normal sharp apex (#329 §4)
Owner correction (chat, 2026-08-27): no flat chamfer at the tip — a plain
sharp apex. Proven by execution on the issue fixture: the outset contour fell
back to a two-point bevel (the 4·h mitre limit against an 87 cm reach) while
the inset contour folded into a bow-tie, and subtracting that fold carved the
V-notches — together they made the trident. Now a degenerate corner (below 15
degrees, inner faces meeting inside both walls) contributes ONE outset point
at the plan's own vertex — no bevel, no metres-long mitre needle — and its
inset is clipped at the convergence line so no fold is subtracted. Plain and
merely sharp pairs keep the full mitre of #310. The write-side limits of
П1-П5 stop new plans from creating such corners at all.

Issue: #329
User-Visible: yes
2026-08-27 23:30:26 +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 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 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 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
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
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 cfc1bb063e fix: preserve migrated wall interactions
Issue: #282
User-Visible: yes
2026-08-26 02:21:26 +03:00