Безопасно восстанавливает управляющее подключение и локальные checkpoint без повторных команд сканеру. Добавляет PCAP/Bridge guardrails и регрессионные проверки одношагового переподключения. Известный дефект: после второго подключения интерфейс не присоединяется к новой генерации preview правой камеры. В живой Quick Connect-сессии STOP был принят, но READY не подтвердился до таймаута; автоматический повтор STOP запрещён.
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.