NODEDC_MISSION_CORE/docs/adr/0013-k1-local-connection-ma...

9.3 KiB

ADR 0013: explicit K1 local connection matrix

  • Status: amended 2026-07-20; Bridge is the product path, Quick Connect retained as a prepared-host laboratory path
  • Date: 2026-07-19
  • Extends: ADR 0004, ADR 0005 and ADR 0012

Context

Mission Core v0.5.0 exposed only the already accepted shared-LAN path even though the product UI named the other XGRIDS connection directions. Retained owner-operated evidence establishes two different network ownership models:

  • the K1 joins a network whose credentials are sent in the reviewed 99-byte BLE provisioning frame; and
  • the controller joins the K1 access point and then reaches the same local MQTT/RTSP data plane at the observed AP address.

Official workflow notes separately name Bridge, Direct Connect and Quick Connect. The names alone do not authorize another BLE command or an inferred credential decoder.

Decision

Plugin v0.6.0 exposes three explicit, fail-closed choices under one exact firmware 3.0.2 compatibility profile:

UI mode Topology Device action Host action Acceptance
Bridge direct-lan one reviewed BLE provisioning write none physically accepted in Mission Core
Direct Connect controller-hotspot the same reviewed BLE provisioning write operator prepares the hotspot and route implementation complete; physical run pending
Quick Connect device-ap one fixed reviewed 100-byte AP-enable write preinstalled exact-firmware credential provider, bounded exact-SSID discovery and one association physically accepted on one prepared Mac; not portable bootstrap

Bridge remains the default. Every API request carries both connection_mode and its exact topology attestation; mismatched pairs are rejected before any network action. Acquisition and camera admission must match the active mode. The fixed K1 AP address is admitted only after a successful Quick Connect host association.

Bridge and Direct Connect do not have a fixed product IP. The address reported by BLE characteristic 7f02 is a DHCP lease observation scoped to the current connection, never device identity and never a durable configuration value. Before a new application-control session, an implicit-host acquisition, or a factory-calibration read, Mission Core performs one read-only 7f02 read for the selected CoreBluetooth device and replaces the previous target. An address change creates a new device_session_id and invalidates calibration captured for the previous session. An active acquisition is never retargeted in place. The later correlated MQTT DeviceInfo response supplies model, firmware, serial and vendor identity; IP equality alone cannot identify a K1.

Product decision on 2026-07-20: Bridge/direct-LAN is the continuing route. Quick Connect remains visible and executable on an already prepared host, but is not a deployment dependency or portability claim.

Direct Connect does not introduce a new vendor payload. The operator first starts a hotspot on the controlling device and enters that hotspot's SSID and password. Mission Core performs the same single, physically reviewed BLE write used by Bridge and accepts only the non-AP private IPv4 returned by K1 status.

Quick Connect does not accept a credential from the browser/API. The first implementation incorrectly jumped from BLE discovery directly to host Wi-Fi association. A physical negative run showed that the selected K1 was still on the existing LAN and the expected AP was not visible. Re-review of the exact LixelGO branch recovered the missing state transition: after BLE connection it writes one 100-byte 7f01 frame, zero except for 0x01 at offset 99, and treats the callback as the AP-launch result before invoking the OS Wi-Fi connector.

Mission Core now performs that bounded AP-enable write at most once. The first physical run reached WIFI_AP at the reviewed AP address, and a targeted CoreWLAN scan found the SSID matching the selected BLE advertised name. It also disproved the earlier assumption that LixelGO carried one global Quick Connect profile: retained client analysis exposes WiFiAP_SSID and WiFiAP_Password as fields of each device record.

A subsequent run found that 7f02 may retain WIFI_AP / 192.168.56.1 after the SSID stops beaconing. Static review then recovered the missing discriminator: LixelGO maps response byte 51 to its AP-ready flag and waits up to 15 seconds for that flag. Mission Core therefore mirrors LixelGO: every new operator Quick Connect action emits exactly one reviewed enable frame, including from a WIFI_AP baseline, and admits host discovery only after byte 51 becomes non-zero. This is not an automatic retry.

The same review proved that LixelGO does not close its BLE manager between the AP-ready callback and native Wi-Fi connect. A failed Mission Core run had done exactly that: byte 51 changed from zero to one, the Python BLE context exited, and the following cold Swift/CoreWLAN process missed the beacon. The corrected implementation holds the selected BleakClient open through bounded native SSID discovery and the single association call.

BLE discovery and the selected device action form one host session. A physical run proved that immediately rediscovering the same K1 by its CoreBluetooth UUID can fail even though the preceding scan exposed it. Mission Core retains the non-serializable BLEDevice handle process-locally and uses that exact handle for the next selected network action; it never exposes the handle through API state or treats the macOS UUID as durable device identity.

The corrected host boundary derives a non-secret, device-scoped profile ID from the selected SSID. The reviewed client contains per-device WiFiAP_SSID and WiFiAP_Password fields, but the 2026-07-20 review of the exact official K1 3.0.2 firmware recovered their upstream source: the scanner's bundled NetworkManager AP script assigns one firmware-constant WPA2 material, while lixel_nman constructs XGR- plus six device-identity characters with a MAC fallback. It is neither an iPhone credential nor a per-device secret.

The laboratory implementation can install a firmware-scoped credential source from the authenticated official archive. The offline importer validates the exact SHA-256, streams the bounded application-partition range, requires one valid AP declaration and writes the value to the OS secure store through helper stdin. On macOS, the Keychain helper materializes the selected device profile from that opaque source before any BLE write. A missing provider fails closed. The browser, API, argv, logs, manifests and evidence never receive the secret; the importer's short-lived mutable buffer is zeroized after the Keychain handoff.

The host-network boundary, rather than the XGRIDS frontend, owns platform association. Browsers expose no Wi-Fi join API, and Apple's iOS NEHotspotConfiguration consent flow is unavailable on macOS. The current implementation therefore uses a short-lived Swift/CoreWLAN + macOS Keychain helper; Windows Credential Manager and Linux Secret Service adapters remain separate platform work. The helper performs repeated read-only exact-SSID scans inside one 15-second discovery window and at most one association. It never repeats the BLE command, guesses a password or treats 7f01 as a credential-read command. The credential-bearing 99-byte station-provisioning frame and fixed 100-byte AP-enable frame are separate reviewed payloads.

No reviewed BLE characteristic or response supplies the AP credential. That does not prove a universal negative for every vendor build, but it means the current plugin has no evidence-backed device-side credential acquisition path. The owner also observed no explicit device/account pairing in the normal LixelGo onboarding flow; this is consistent with a firmware-defined AP secret, but does not establish account-wide authorization for arbitrary scanners.

Connection verification refreshes the session-scoped lease with the same read-only BLE status operation. It does not write a characteristic, re-provision Wi-Fi, scan the subnet, change a host route, or touch VPN configuration. The later canonical MQTT session supplies the real data-plane connection and live DeviceInfo identity check. A BLE lease observation is therefore not by itself a claim that MQTT/RTSP is reachable.

Consequences

  • The UI now represents all three intended directions instead of disabled placeholders.
  • Quick Connect can temporarily remove the controlling host from its previous Wi-Fi network. The operating system may require Wi-Fi/location permission.
  • A new host needs a separate exact-firmware provider installation. The current application does not obtain it from BLE and does not bootstrap it by itself.
  • Automatic firmware download, iPhone extraction and hard-coded credential delivery are explicitly rejected product routes. Windows/Linux adapters are therefore not scheduled for this Quick Connect path.
  • Direct Connect requires an already-running hotspot and a controller route; Mission Core does not create or manage that hotspot.
  • The application-control, START/STOP and raw-first acquisition protocol is unchanged after a target address is admitted.
  • Direct Connect remains explicitly pending one owner-operated physical acceptance cycle. Quick Connect AP activation and host association are physically accepted only on the prepared K1/FW 3.0.2 Mac stand. Bridge is the only accepted portable product path in this matrix.