Retain K1 connection between scans and admit the next named acquisition

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 21:13:17 +03:00
parent ed9a77ba73
commit c6693d6f44
17 changed files with 586 additions and 274 deletions
@@ -0,0 +1,93 @@
# K1 connection lifetime between recordings — R16
## Observed behavior and cause
The owner reports two successful R15 connections and recordings, then a return
to the device showing “Устройство остановлено” and requiring a separate
connection check. R15 is Node 0.8.12 / K1 0.1.12. The services remained active
with zero restarts through the reported 20:1720:23 MSK interval. A later bounded
Fleet read still showed the K1 acquisition idle, control phase completed, and
online/verified false. This is current state, not proof of a historical Wi-Fi
failure.
The implementation explains the transition deterministically: the interactive
control worker concluded the entire MQTT dialogue after correlated STOP and
fresh unbound READY, set `completed`, and closed its transport in `finally`.
The facade then reduced every completed control session to control loss. The
Node projection correctly withheld connection authority, but the UI further
hid that distinction by prioritizing “device stopped” over connectivity and
instructing the owner to check connection after every completed recording.
No service restart or actual Wi-Fi disconnect is needed to produce this path.
There is a real protocol constraint underneath the original single-scan
implementation: MQTT operation keys and response-correlation ownership are
one-shot within a dialogue. Reusing the old dialogue by clearing consumed keys
would weaken replay/correlation protection. R16 does not reset these guards.
The bounded journal also records failures at 20:18:54 and 20:21:24 at the R15
Node adapter's `Physical state requires explicit reconciliation` check. That
check ran even immediately after the adapter's own admitted START, before its
pending physical edge had settled. R16 returns that owned starting/scanning
state without another dispatch; pre-existing ambiguous physical state still
blocks a new START.
## Corrected lifetime
After confirmed STOP/READY, the completed recording is sealed by the existing
acquisition lifecycle. The command worker retains its socket and services the
existing subscriptions while idle. This wait sends no bootstrap, network
configuration, START or STOP. Real socket failure, stale bound status, identity
change and route/proof expiry keep their existing fail-closed checks.
A subsequent explicit named START releases the next workspace checkpoint. Only
then does the owner retire the previous command socket and create a fresh
canonical dialogue for the same bound device/network. It receives fresh
DeviceInfo, enforces the identity/route and durable ledger checks, then follows
the existing workspace/project/START stages. The control generation advances;
old checkpoints cannot authorize the new cycle. BLE selection, GATT and Wi-Fi
provisioning are not part of this path. No extra operator recovery action is
needed for an uninterrupted connection. Actual loss retains the explicit
verification/recovery path; no automatic network write or physical command
retry was added.
The facade accepts completed control as live only when its socket is retained
and the existing exact, fresh DeviceInfo/control proof satisfies the supervisor.
Legacy completed/closed sockets remain disconnected. Explicit network changes
may retire the retained idle socket through the existing local close boundary.
Both direct and Node START orchestration accept this completed-but-connected
checkpoint. Device inventory/detail badges now report connection; acquisition
progress remains in the spatial session controls.
## Presentation
- Canonical Design Guideline Field owns autofill styling. Browser autofill uses
the existing field material, theme text/caret and keyboard focus indicator.
No K1-only field override or new control was introduced. Registry, component
documentation and the living catalog were updated.
- The shared spatial viewport uses one explicit rounded compositing clip and
an isolated stacking context, including the native canvas/iframe and overlays.
This addresses corner leakage without decorative strokes or changes to the
scene grid, axes or camera resize handle. Confirmation against the owner's
actual GPU-rendered screenshot remains part of visual acceptance.
## Verification and delivery
Synthetic checks are not physical scanner acceptance. The final artifact and
installation evidence are recorded below. No physical scanner command, BLE
probe or credential extraction was performed from CLI. Existing onboard
credentials and pre-install guards are retained. Builds run sequentially on
the 18 GB Mac; Docker was not running. The canonical Core on port 8000 stays
available.
Source checks: 167 control/protocol/Node/supervisor/coordinator tests; 22 selected
acquisition lifecycle tests; 809 Control Station unit tests. Regressions cover
retained idle connection, two explicit scans with distinct command dialogues,
no idle commands/replay, stale CAS, completed connection versus actual loss,
and admission of the owned pending START. Design Guideline production build and
registry validation passed. Production Core build and packaging checks follow.
Full acquisition lifecycle regression then passed: 631 tests (includes the 22
focused tests above). Installer/package lifecycle: 14 passed. Core TypeScript
and production build passed (8.29 s). Ruff and whitespace checks passed.
Design Guideline pin: `26a1bf72a2a32b002e51f910e8faa300333bb6c3`.
R16 package versions: Node 0.8.13 and K1 0.1.13.