Files
NODEDC_MISSION_CORE/docs/adr/0013-k1-local-connection-matrix.md
T
DCCONSTRUCTIONS 0752e5c6bf Стабилизация переключения Bridge и Quick Connect
Безопасно восстанавливает управляющее подключение и локальные checkpoint без повторных команд сканеру.

Добавляет PCAP/Bridge guardrails и регрессионные проверки одношагового переподключения.

Известный дефект: после второго подключения интерфейс не присоединяется к новой генерации preview правой камеры. В живой Quick Connect-сессии STOP был принят, но READY не подтвердился до таймаута; автоматический повтор STOP запрещён.
2026-08-23 00:15:28 +03:00

16 KiB

ADR 0013: explicit K1 local connection matrix

  • Status: amended 2026-08-08; 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.

The 2026-08-08 physical Bridge trace corrected the earlier field model: the first 7f02 text slot is WIFI_AP in AP state but contains the joined network name in FW 3.0.2 station state. Mission Core therefore normalizes that station response to WIFI_CLIENT internally and admits Bridge/Direct only when the raw post-write name exactly matches the current explicit request plus a valid non-AP private address. The raw name is not persisted in the secret-free network audit or published through API state.

The limitation still applies when recording an interrupted attempt that has no exact post-write network-name observation. A changed private DHCP address alone cannot identify the selected network. An already AP-ready baseline likewise cannot prove the outcome of an interrupted Quick-to-Quick attempt. Mission Core therefore records that attempt as terminal outcome-unknown and never replays it automatically. The historical uncertainty is not a permanent barrier: after the old active operation and cleanup have ended, a later explicit operator scan, selection, and connect is a distinct session with its own one reviewed write.

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.

One explicit six-second BLE discovery and the later Apply action form one operator intent without a second discovery. 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 Apply; it never exposes the handle through API state or treats the macOS UUID as durable device identity. UI row selection itself performs no GATT or backend I/O.

The operator-visible candidate list, local selected draft and admitted active session are separate contracts. Every explicit scan replaces the candidate set. Selection only binds a local form to one result from the latest admitted generation. Wall-clock age does not remove that generation while the operator completes the form. Apply admits only its exact retained handle and live GATT validation may create the active session; a remembered UUID is never mutation authority. Proven disconnect, explicit stop, app/backend restart, another explicit Scan, or a committed mode transition revokes the applicable candidate or live session. Rediscovery never auto-connects.

Quick Connect to Bridge is an explicit topology transition, not another scan heuristic. Selecting Bridge — or choosing another K1 while Bridge is already selected — sends one idempotent local reset_scenario CAS. It seals retained receiver/camera/control ownership, invalidates candidates and credentials and retires old physical lineage truthfully, while sending no device command, BLE, host-network write or automatic Scan. The next explicit Scan starts the clean discovery flow, while Apply remains the topology and device-mutation boundary. The operator selects one discovered K1, sees the Bridge credentials immediately and submits once. The new GATT session reads internal baseline 7f02 and emits exactly one reviewed 99-byte station write. A connect failure ends that attempt. An ambiguous post-write failure is terminal outcome-unknown audit, not a permanent cross-session fence. There is no automatic BLE or network-write retry.

Likewise, an exact REST network_applied result with unready/unknown control spends that Apply and its credentials without making the read-model attempt a permanent topology lock. Recommended Verify is pinned to the backend current/configured target. A separately explicit new intent still requires current server policy: Bridge prepares select-device before a later fresh scan; Quick and Direct run an admitted fresh scan, select only its latest row and create a new idempotency Apply; a mode or same-mode new-device transition uses one idempotent local-only reset_scenario before that fresh scan. None of these new-intent UI paths reuses the old intent or runs as a hidden frontend/mutating continuation. The service-owned same-intent read-only bootstrap declared below is the sole post-ACK exception.

The Apply REST call returns as soon as the exact durable network_applied proof is available. The service may continue the same intent's supervised control bootstrap read-only after that ACK. This performs no BLE/host mutation or retry and creates no frontend Verify, Scan, Apply or blocking Apply loader. While the exact child is accepted/running, the UI may show only a passive Сеть настроена · подтверждаем управление indicator and must keep every recovery action disabled. Later control state arrives only as backend presentation convergence; terminal unready/unknown state then exposes the explicit server-policy recovery choices.

Bridge and Quick Connect were physically accepted as separate paths before this amendment. The combined Quick Connect to Bridge transition has automated contract coverage but remains a distinct physical acceptance gate; it must not be reported as field-accepted until one redacted live run records both sides of the transition.

Quick Connect Apply is an exact idempotent ensure-target operation when the selected K1 already reports the canonical AP-ready state. Mission Core accepts that unchanged state only after the one reviewed write-with-response is durably confirmed, then performs the normal exact device-SSID host association. An unconfirmed or merely read-only unchanged observation remains fail-closed; this rule neither retries the BLE write nor weakens Bridge admission.

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 2026-08-06 field regression established that process identity is part of this prepared-host contract. Runtime swiftc compilation produced an ad-hoc helper with an unstable designated identity. macOS then requested Keychain authorization repeatedly and the same process context failed to expose the exact K1 SSID through CoreWLAN even after K1 had acknowledged AP-ready. That runtime-compiled route is rejected. The laboratory adapter uses the previously physically accepted Apple-signed interpreter path, /usr/bin/xcrun swift <reviewed-source>, and validates the source path before launch. A portable product implementation still requires a packaged, precompiled and properly signed helper with a stable bundle identifier, designated requirement, Location/CoreWLAN authorization and Keychain ACL; the current prepared-host path does not claim that packaging work is complete.

Before any BLE write, the helper's preflight is non-interactive. It first checks Keychain item existence through metadata, then validates the selected profile's SSID and exact-firmware-profile provenance inside the helper without returning secret data. Provider material is also read with interaction disabled if a missing device profile must be materialized. The association phase accepts only that already materialized exact profile. It never falls back to the system Wi-Fi Keychain, rewrites a profile opportunistically, or opens a password/authorization dialog after K1 has changed network state. An unavailable or unauthorized profile therefore fails closed with a precise reason code and no automatic device retry.

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 30-second discovery window and at most one association. The larger window covers the physically observed 18.142-second beacon-discovery case; AP-ready confirms K1 state but does not prove that macOS has already observed the RF beacon. 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.

Apply may read BLE baseline internally while establishing a new selected session. Selection never does so, and the normal flow has no mandatory or hidden "verify without write" recovery step. The baseline read does not 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; BLE status alone is not 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.
  • Discovery never auto-connects devices. Mode, selection and input are local only. App restart, disconnect, explicit stop and mode transition require a fresh explicit scan-select-Apply session. Apply performs no hidden rescan or Verify and may cross at most one device-mutation boundary.
  • 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.