Commit Graph
2134 Commits
Author SHA1 Message Date
Codex f4c66bed3f test: prove AC3 on the reconnect path, with a probe that can fail (#397)
CODE-REVIEW-397-r1 Medium: AC3 named the second reader of the same
value — _loadFromServer via _adoptStructuralResponses — and nothing
exercised it. Adding the scenario turned out to be less mechanical than
it looked, and both obstacles are worth recording:

The reconnect path reads BOTH answers, and a differing config clears the
history for its own reason (configChanged). The fake server now echoes
the config the card already holds, so the check answers the layout
question it claims to answer.

The first version of the probe used a round 0.42, which canonicalization
leaves untouched — the check passed with and without the fix, i.e. for
the wrong reason. The probe now starts from a non-canonical position
(0.024999999999999942, which snaps to 0.025), and the scenario runs
immediately after the write, before any reload can align the two sides.

Verified by removing the fix: five checks red, now including
reconnectKeepsHistory and deleteEchoKeepsHistory. Both were green in the
weaker version — which is exactly what the reviewer's Medium was about.

User-Visible: no
Issue: #397
2026-08-31 03:03:59 +03:00
claude[bot] b17f416740 docs: review document for #397
Issue: #397
User-Visible: no
2026-08-30 23:55:36 +00:00
Codex 08d5612265 build: refresh bundle trees and the doc capture for #397
User-Visible: no
Issue: #397
2026-08-31 02:37:18 +03:00
Codex d87cc29804 fix: the card keeps the position it sent, so its echo is not foreign (#397)
B3: _persistDevicePlacement sent canonicalizePosition(...) to the server
and left the raw value in _layout, then recorded the fingerprint over
that raw snapshot. Canonicalization is not identity — it snaps to the
lattice — so 39 of 115 pixel-derived coordinates differ, and the next
_reloadLayoutOnly or _adoptStructuralResponses saw its own write as a
remote edit: history cleared, _layout replaced. The old _persistLayout
wrote the canonical value back; the per-device path introduced by #74
lost that line.

M1: the smoke that was supposed to prove AC10 assigned
serverLayout = structuredClone(c._layout) right before the reload —
erasing by hand the very divergence it existed to catch, so it could not
fail. The fake WS already stores what went over the wire; the
assignment is gone and the check now reddens on the unfixed code
(verified: three checks red without the fix, including this one).

Also proven, because the fix touches their neighbourhood: the echo of a
DELETE keeps the history (the branch removes a key rather than replacing
a value), and an in-flight write still wins the merge against a server
answer holding the old position.

One existing assertion was loosened deliberately: undo now restores a
position that may differ from the raw one by the lattice snap (<1e-9 of
the plan). That is the point of the fix — local and server agree — so the
equality is stated to that precision, with the snap size pinned
separately so a real drift would still fail.

User-Visible: yes
Issue: #397
2026-08-31 02:36:55 +03:00
claude[bot] f4fcb1fac0 docs: review document for #397
Issue: #397
User-Visible: no
2026-08-30 23:25:38 +00:00
Codex 6edcde012a docs: #397 spec revision 2 per SPEC-REVIEW-397-r1
User-Visible: no
Issue: #397
2026-08-31 02:21:20 +03:00
claude[bot] 38b48ee0aa docs: review document for #397
Issue: #397
User-Visible: no
2026-08-30 23:19:33 +00:00
Codex 83692e7959 docs: #397 spec — correct the fingerprint line number
User-Visible: no
Issue: #397
2026-08-31 02:11:19 +03:00
Codex 9fcbb64633 docs: specify the device position echo fix (#397)
User-Visible: no
Issue: #397
2026-08-31 02:10:49 +03:00
claude[bot] a25de7383f docs: review document for #396
Issue: #396
User-Visible: no
2026-08-30 23:00:18 +00:00
Codex f3620f2b27 build: refresh bundle trees and the doc capture after the dev rebase (#396)
User-Visible: no
Issue: #396
2026-08-31 01:40:05 +03:00
claude[bot]andCodex f8cf18a25a docs: review document for #396
Issue: #396
User-Visible: no
2026-08-31 01:37:12 +03:00
Codex d6a2607692 build: refresh bundle trees and the doc capture for #396
User-Visible: no
Issue: #396
2026-08-31 01:37:12 +03:00
Codex 8f485c0b00 fix: the camera keeps the zoom you see and the point you hold (#396)
Three findings of the v1.70.0-beta.1 audit, all on the transition path
added by #82, all of the same shape — the new path did not inherit a
property the old one had.

B1: persisting the zoom moved into _settleCameraTransition only, and a
cancellation never settles. Touching the plan mid-flight — the literal
scenario of the issue — froze the shown frame and threw it away; before
which kind it is: the user one (_stagePointerDown) persists the frame
that stays on screen, the eleven structural ones keep writing nothing.
The distinction is now also written down in spec #82 §13, which had one
line for both.

B2: the anchor was read from the presented (lagging) frame while the
zoom accumulated from the target, so a six-notch trackpad series walked
the point under the cursor 17 px away — against §10's own promise. Both
now come from the same state. Spec §10 said to use the presented frame
and to keep the anchor within 0.5 px; those two are incompatible, and
the paragraph is corrected rather than left as a trap.

M2: the feather freeze keyed on the two gesture flags, which an
animated transition does not set, so every tween frame rebuilt the blur
region. It keys on 'the camera is still' now.

Guards: unit tests pin the anchor at 1e-9 across 8/16/33 ms series and
prove zoom accumulation is untouched; the smoke checks the shown zoom is
the stored one, that a structural cancellation stores nothing, and that
the anchor holds; three mutants (cancel-loses-zoom, anchor-from-
presented, feather-thaws) were run by hand and each reddens.

User-Visible: yes
Issue: #396
2026-08-31 01:36:59 +03:00
claude[bot]andCodex 3421065286 docs: review document for #396
Issue: #396
User-Visible: no
2026-08-31 01:36:53 +03:00
Codex 371f2e9869 docs: #396 spec revision 3 per SPEC-REVIEW-396-r2
User-Visible: no
Issue: #396
2026-08-31 01:36:53 +03:00
claude[bot]andCodex 334dcf2bf8 docs: review document for #396
Issue: #396
User-Visible: no
2026-08-31 01:36:53 +03:00
Codex 7cf22cb54f docs: #396 spec revision 2 per SPEC-REVIEW-396-r1
User-Visible: no
Issue: #396
2026-08-31 01:36:53 +03:00
claude[bot]andCodex 4132e03642 docs: review document for #396
Issue: #396
User-Visible: no
2026-08-31 01:36:53 +03:00
Codex 54f9efb798 docs: specify the camera transition fixes (#396)
User-Visible: no
Issue: #396
2026-08-31 01:36:53 +03:00
claude[bot] cc6bbdf24c docs: review document for #32
Issue: #32
User-Visible: no
2026-08-30 22:28:41 +00:00
Matysh 2f021046aa Update remaining dangerous-action smokes
User-Visible: no
Issue: #32
2026-08-31 01:18:00 +03:00
claude[bot] 2b3d5613f2 docs: review document for #32
Issue: #32
User-Visible: no
2026-08-30 22:06:44 +00:00
Matysh f3ac0ac061 Update free-walls smoke for shared confirmation
User-Visible: no
Issue: #32
2026-08-31 00:59:37 +03:00
Matysh 7b363caabc Accept canonical documentation screenshots
Canonical run: https://github.com/Matysh/houseplan-card/actions/runs/33337407834

User-Visible: no
Issue: #32
2026-08-31 00:50:44 +03:00
Matysh 751769908a Update destructive action smokes
User-Visible: no
Issue: #32
2026-08-31 00:49:56 +03:00
Matysh c91ac74e19 Implement unified dangerous-action confirmation
User-Visible: yes
Issue: #32
2026-08-31 00:46:54 +03:00
claude[bot] 2782f3b1f3 docs: review document for #32
Issue: #32
User-Visible: no
2026-08-30 21:29:56 +00:00
Matysh 4ba1b2730f docs: budget unified confirmation surface
User-Visible: no
Issue: #32
2026-08-31 00:24:32 +03:00
claude[bot] a6b5161f07 docs: review document for #32
Issue: #32
User-Visible: no
2026-08-30 21:23:04 +00:00
Matysh 206bcd1ae7 docs: refresh danger confirmation spec
User-Visible: no
Issue: #32
2026-08-31 00:17:19 +03:00
Matysh 8955c02e3a build: prepare v1.70.0-beta.1 candidate
Package smooth plan navigation, device position history, visible discovery filters, furniture transforms, localized backend errors and the reviewed fixes since v1.69.0.

Issue: #33
Issue: #44
Issue: #74
Issue: #82
Issue: #86
Issue: #381
Issue: #383
Issue: #384
Issue: #385
Issue: #391
User-Visible: yes
v1.70.0-beta.1
2026-08-30 22:52:02 +03:00
Codex 7e27bc7922 fix: type-check against python 3.14, as the runner does (#42)
The new typing step failed on its first CI run — not on our code:
mypy parses the sources of the installed homeassistant, and after #392
that is HA 2026.8.3 on python 3.14, which uses 3.14-only syntax
(parenthesis-free `except`). With python_version = 3.13 mypy stopped at
a syntax error in someone else's file before reaching a single module of
ours, which is exactly the silent-nothing the gate exists to prevent —
except loud.

ruff keeps target-version py313 deliberately: it lints OUR sources and a
lower target only withholds newer-syntax suggestions, while mypy has to
read the dependency tree the runner actually installs.

User-Visible: no
Issue: #42
2026-08-30 22:05:33 +03:00
Codex dddbbe5522 ci: make the strict typing gate actually run (#42)
r6 Medium: AC4 was measurable only on a developer's machine — no
workflow invoked mypy, so a typing regression in any of the six
allowlist modules reached dev unnoticed while the issue claimed
measurable backend quality. Coverage and lint had continuous gates;
typing had a text comparison of a committed list.

The backend job now runs mypy right after ruff, from the same pinned
dependency file (mypy==2.3.1 — an unpinned checker would redden on code
that never changed). The step derives its module list from the
pyproject.toml strict allowlist instead of duplicating it, because a
drifted duplicate is a green step checking the wrong modules, and it
refuses an empty list rather than passing silently.

Guarded twice: a contract test pins all three facts (pinned checker,
a step that really invokes it, list read from pyproject) and the new
typing-gate-stops-running mutant reddens when the invocation is
neutered.

User-Visible: no
Issue: #42
2026-08-30 22:00:52 +03:00
claude[bot] 01fbb77f3b docs: review document for #42
Issue: #42
User-Visible: no
2026-08-30 18:52:32 +00:00
Codex 972e708a71 build: refresh bundle trees and the doc capture after the #392 rebase (#42)
User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex 569867487c fix: adopt the #392 dependency file as the single source (#42)
Rebase resolution: dev's #392 introduced tests_backend/requirements.txt
(python 3.14, phcc 0.13.357, homeassistant 2026.8.3) — exactly the
single-source-of-pins AC of this issue, so the duplicate
requirements_test.txt is dropped and both workflows keep installing from
the #392 file; ruff is added there for the lint step. The backend
reuse key no longer names the dead file (tests_backend/ as a root
already covers the new one); ARCHITECTURE.md points at the real path.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex 9f50778df5 test: close the r4 mediums — structural tuple scan and reuse-key inputs (#42)
M1: the AC5 scanner parses the (field, code, message) literal tuple in
validation.py structurally instead of naming the two known codes — a
third tuple entry with an unregistered code now fails the registry test
(verified with an injected invalid_ghost_entity_mutant_probe), and a
tuple whose string count is not a multiple of three refuses instead of
guessing.
M2: the backend reuse key now includes its direct job inputs introduced
by this issue — scripts/backend-coverage-baseline.txt (the threshold the
comparison step reads), requirements_test.txt (the pip source) and
pyproject.toml (ruff/mypy config) — verified: the key changes when the
baseline changes and is restored byte-for-byte with the file.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex 26d45cf405 build: refresh bundle trees and the doc capture after the dev rebase (#42)
Rebased onto dev with #82 (camera transitions), #74 (marker undo) and
the re-accepted goldens; bundle trees are rebuilt from the rebased
sources and the screenshot capture is retaken on this HEAD — manifest
AND all PNGs committed together.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex fa1aa7a877 test: record the real backend coverage baseline (#42)
87.2% line coverage, taken from the first fully green backend CI job of
this branch (run 33321192996, coverage.xml line-rate 0.8716) — replaces
the 80.0 placeholder as promised before the verdict. The gate refuses
any run below baseline minus 0.1.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex f7ae00019c test: the jamb-margin harness assert reads the JSON details (#42)
The harness test still parsed the legacy 'space=... opening=...
margin_cm=...' string; #42 replaced that message with structured JSON
details (the client localizes from the code and reads the fields). The
assert now parses the payload and checks the same three facts.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex 778da930cb fix: the quality test no longer stubs packages in sys.modules (#42)
Same defect class as #389: _const() planted bare ModuleType stand-ins
for custom_components(.houseplan) and never removed them, so the HA
harness running later in the same pytest process saw a package without
async_setup — 85 test_ha_* failures with 'No setup or config entry
setup function defined'. const.py imports nothing, so the loader needs
no package context at all: load it by file path under a standalone
module name and leave sys.modules untouched (verified: no
custom_components* keys after _const()).

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
claude[bot]andCodex 92cf0ab17c docs: review document for #42
Issue: #42
User-Visible: no
2026-08-30 21:34:32 +03:00
Codex 512ab7f279 docs: commit the recaptured screenshot images, not only the manifest (#42)
The previous commit refreshed docs/images/screenshots.json but left the
re-rendered PNGs out of the index — CI compared the committed manifest
against the committed (stale) images and failed on every hash.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex 6582a06e17 build: refresh bundle trees after the dev rebase (#42)
Bundle trees are rebuilt from the rebased sources (the pre-rebase build
commit was dropped during the rebase and the trees recreated), and the
doc capture is retaken on the rebased HEAD.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex c9dd3401fe fix: pin the last py3.13-compatible test harness and refresh the doc capture (#42)
pytest-homeassistant-custom-component 0.13.317+ require python >=3.14
while the CI runner is 3.13: 0.13.316 is the newest installable release
and resolves to the same homeassistant==2026.2.3 the previously green
unpinned pip line produced. voluptuous is unpinned again — homeassistant
pins 0.15.2 itself and a 0.16.0 pin deadlocks the resolver.
The screenshot capture is refreshed after the any-gate source fix of
e8243d1e, which changed src/ without recapturing (the standing rule:
every src commit needs capture + check-docs).

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
claude[bot]andCodex fa20e37330 docs: review document for #42
Issue: #42
User-Visible: no
2026-08-30 21:34:32 +03:00
Codex 09adfd73a0 fix: CI-compatible dependency pins and an any-free JSON branch (#42)
pytest-homeassistant-custom-component transitively pins the pytest
family and the homeassistant version — re-pinning them deadlocked the
resolver (the sandbox pip index is py3.10-bound and suggested stale
versions). The structured-details branch no longer copies the legacy
(item: any) annotation the new-code any gate rightly rejects.

User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex d274e38d57 test: mutation-gate accepts python guard files (#42)
User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00
Codex 10cdba8435 test: the JSON-details contract counts both branches (#42)
User-Visible: no
Issue: #42
2026-08-30 21:34:32 +03:00