feat(k1): wire canonical control session to UI

This commit is contained in:
DCCONSTRUCTIONS
2026-07-18 17:53:55 +03:00
parent 36f0c93d2a
commit 7b7b5d6cad
24 changed files with 1591 additions and 184 deletions
+22 -19
View File
@@ -21,7 +21,8 @@ The plugin owns:
- BLE discovery hints and K1 GATT metadata;
- the reviewed firmware-3 Wi-Fi provisioning profile;
- K1 LAN status and private-address validation;
- subscribe-only MQTT transport and report-topic allowlist;
- subscribe-only data MQTT transport plus a separately bounded canonical
application-control transport;
- native `.k1mqtt` capture;
- firmware-scoped protobuf/LZ4 and legacy codecs;
- normalization of K1 point cloud and pose, plus raw-only preservation of the
@@ -31,8 +32,9 @@ The plugin owns:
- K1-specific operator instructions and compatibility tests.
- the scoped React `device.connection` contribution and its BLE/Wi-Fi and
acquisition pipeline UI.
- the dormant application-control facade boundary: explicit shadow arm/disarm,
a 15–300 second Keychain-backed in-memory authority lease, and redacted state.
- the interactive canonical application-control session: one socket owner,
separate workspace/project/START/STOP UI checkpoints, live status gates,
single-action physical permits and no automatic retry.
The plugin does not own:
@@ -61,10 +63,11 @@ legacy router; both paths now cross the same runtime transport and delegate to t
`XgridsK1CompatibilityService` methods. Synchronous capture/runtime operations
run outside the FastAPI event loop.
Model switching calls the plugin deactivation hook. An active acquisition uses
semantic `acquisition.stop` in `capture-only` mode; replay and pre-v1alpha2
sessions retain the legacy `stream.stop` shim. Neither path claims that the
physical K1 stopped without separate operator evidence. BLE, MQTT, codec,
Model switching calls the plugin deactivation hook. It is rejected while the
canonical K1 control socket is open, so navigation can never become an implicit
device STOP. Operator-manual acquisition uses semantic `acquisition.stop` in
`capture-only` mode; replay and pre-v1alpha2 sessions retain the legacy
`stream.stop` shim. BLE, MQTT, codec,
archive discovery and RRD export modules now live under the plugin package
after replay parity and physical K1 regression. The current transport remains
in-process and its health is lifecycle-only; process isolation, crash/restart
@@ -81,18 +84,18 @@ device I/O with:
uv run python plugins/xgrids-k1/profile_loader.py
```
Plugin v0.4.0 does not widen device authority. Its application-control
coordinator has no request-emission method, no live MQTT sink and no UI control;
`vendor_writes_enabled` remains false. A separate uninstalled acceptance-only
transport now implements exact subscriptions, QoS2 completion, response
barriers and no-retry poisoning. The admin CLI can provision the fixed Keychain
item through Apple's hidden prompt without accepting the value as an argument.
Neither path is imported by the facade. The first physical attempt emitted only
bootstrap ordinals 1–6 and failed closed on live batch-3 response correlation;
START was not emitted and the K1 remained READY. The temporary lab Keychain item
was deleted. An OS-independent plugin/edge authority provider, redacted live
response comparison and a newly permitted full START/STOP acceptance remain
required.
Plugin v0.5.0 installs that reviewed transport behind explicit plugin actions.
Opening control performs only the connection-owned operations 1–6. Workspace
entry releases operation 7; saving the project and preparing local reception
releases operations 8–10; a separate START click carries the project name and
then waits for bound `SCANNING + project + init_ready` before operations 13–14.
STOP is separately permitted, never retried, and keeps the same socket until K1
reports unbound READY and the operator confirms a steady green indicator. The
admin CLI still provisions the fixed Keychain item through Apple's hidden
prompt without accepting the private value as an argument. No physical command
is emitted merely by loading the plugin, opening the page, navigating, polling
state or running repository tests. Full v0.5.0 physical acceptance remains an
operator-run gate.
The optional owner-controlled iPhone/LixelGO observation tool lives under
[`lab/iphone-capture/`](lab/iphone-capture/). It pins `pymobiledevice3` in a