4.8 KiB
ADR 0012: device-bound K1 command authority
- Status: accepted
- Date: 2026-07-18
- Extends: ADR 0004, ADR 0005, ADR 0009 and ADR 0010
Context
Owner-controlled LixelGO traffic proves the K1 modeling START/STOP protobuf
shape, MQTT topic, QoS and correlated success response for one K1 running the
exact xgrids.lixelkity-k1.fw-3.0.2.direct-lan.v1 profile. A bounded offline
audit also proves that Mission Core's encoder reproduces both retained requests
byte-for-byte. This is sufficient to describe the current device dialogue, but
not to replay a captured request or authorize writes to any K1.
The protocol exposes several identities with different authority. Mission Core's provisional device UUID is local inventory identity. The vendor device ID is reported by the live K1 and occupies the request header. The K1 serial is a separate device-binding value. The OpenAPI value is private command material which is absent from live status. LixelGO derives the command session relation from the vendor device ID and request type; it is not a reusable caller session.
Native project durability is also not equivalent to command acceptance. STOP success, stream quiescence, return to READY/steady green and a reusable project on the scanner are separate observations.
Decision
K1 application control is exact-profile, device-bound and fail-closed.
- Mission Core never sends its local inventory UUID, BLE identifier or a K1 serial in place of the vendor request identity.
- Each K1 requires an owner-authorized enrollment containing its vendor device ID, serial and private OpenAPI value. Enrollment secrets are not committed, placed in Ops, returned by APIs or written to logs.
- Before a command can be considered, live MQTT status must attest the same vendor device ID and serial under the exact firmware/topology profile. Replay evidence cannot establish current command authority.
- Identity drift, missing identity, malformed status, profile mismatch or an unexpected lifecycle state blocks command planning.
- START retains the observed LixelGO parameters: record-and-calculate mode 2, LCC scan mode 1, handheld mount mode 0 and the operator's validated project name. STOP contains only the same bound header and action.
- MQTT command semantics remain QoS 2, retain false. Automatic retry is forbidden: an unknown outcome must be reconciled from live status and physical evidence before another command.
- No firmware, activation, account, update or vendor-cloud endpoint is part of the control path. Local direct-LAN MQTT is the only reviewed transport.
- STOP completion has four gates: correlated command result, local stream quiescence and evidence sealing, READY/steady-green device state, then native project verification. Earlier gates must not claim the later ones.
Current implementation boundary
LiveModelingControlSafety observes only live device-status messages. It binds
vendor identity and serial, tracks lifecycle state and creates non-executable
shadow START/STOP plans. Public state and plan output contain only booleans,
counts, action, topic, QoS, retain flag, payload length and digest. The encoded
payload and enrolled values remain private in memory.
The shadow plan is blocked by both vendor-writes-disabled and
publisher-not-installed. There is no MQTT publisher, enrollment endpoint or
automatic retry path. The physical K1 control remains the production fallback.
Promotion gate
A future publisher requires a separate review and an operator-present physical acceptance on the enrolled K1:
- confirm exact firmware/profile, steady-green state, battery and storage;
- close LixelGO and arm raw evidence plus the intended camera receiver;
- attest live READY identity against the device enrollment;
- review the shadow command metadata;
- send one START, without retry, and correlate its exact response;
- observe calibration and first point/pose/camera data;
- send one STOP, without retry, and correlate its exact response;
- seal local evidence while accepting the bounded stream tail;
- wait for READY and steady green before power-off or another scan;
- verify the native project independently through the vendor-supported workflow.
Any unknown response, identity change, activation state, fault, low battery or unexpected lifecycle transition pauses the test. It does not trigger a guessed recovery command.
Consequences
Adding another K1 means creating another private enrollment and proving its exact compatibility profile; it never means reusing captured bytes from the first scanner. The design preserves native record-and-calculate behavior while keeping command authority inside the XGRIDS plugin and out of generic Mission Core. It intentionally postpones convenience automation until identity, credential provenance, one-shot transport behavior and durable save semantics have all passed physical acceptance.