Files
NODEDC_MISSION_CORE/docs/audits/2026-09-07-k1-node-operation-identity-r4.md
T

3.6 KiB

Node K1 operation identity R4

The owner's next Core Fleet UI attempt at 12:19 MSK failed on installed Node 0.8.1 / K1 0.1.1+private.1. The newly added journal diagnostic recorded action=scan exception=ValueError. The board still had discovery generation zero. Its BlueZ controller was powered and not rfkill-blocked. This was an execution failure before discovery, not evidence that K1 was absent.

Reproduced cause

The Node protocol requires op_ followed by 32 lowercase hexadecimal digits. The K1 OperationJournal accepts a UUID, optionally prefixed by op-. Passing the Node ID unchanged fails in device_lifecycle._identifier before any BLE call. R3 corrected the missing runtime fence but its service stub hid this second boundary mismatch. The new regression reproduced the exact ValueError with the real NodeBridge, facade, compatibility service and operation journal.

NodeBridge now translates the host ID into the plugin UUID format. The mapping is deterministic and preserves all 128 bits. Host IDs remain unchanged in the Go broker, durable Node journals and HTTP responses. The plugin's validators, LAB callers and lifecycle authority are unchanged. Connection attempt and recovery IDs are projected back to host IDs so continued UI observation can still match the exact request after the Wi-Fi acknowledgement.

The same conversion covers scan, provision, verify, START and STOP. The acquisition prepare child uses a deterministic UUID derived from the host intent, distinct from its START operation. It no longer appends an invalid _prepare suffix to an operation ID. Repeated intent IDs reach the same journal row; no random replacement IDs, automatic provisioning replay or migration of old unknown operations were introduced.

Error evidence and UI

An invocation failure reads only its exact existing plugin journal row. A recorded scan failure reaches the caller as failed; an exception before any row exists remains an unconfirmed execution. Neither is a successful empty search. Both produce a Bluetooth search error in the shared enrollment UI, while a confirmed zero-candidate result still displays K1 not found. Search failures do not display the Wi-Fi connection notice.

Unexpected worker failures log admitted action, exception class and source function/line locations only. Exception text, source text, local variables, request payloads and credentials are excluded.

Validation and limits

The scan regression keeps the actual service, journal, BLE arbiter and scanner logic, replacing only BleakScanner's OS radio endpoint. It verifies successful discovery and a failed radio start, correct host result correlation, and one radio invocation when the exact command is repeated. Acquisition IDs are checked against the actual OperationJournal. Projection does not mutate the plugin's native state. Frontend tests distinguish failed, rejected, unknown and confirmed empty scans and retain network/bootstrap/recovery regressions.

Focused Python bridge, installer, Fleet enrollment, BLE scanner and operation journal suite: 73 passed. Core frontend suite: 789 passed, no failures or skips. Build and installation acceptance is recorded below when completed.

Release versions are Node 0.8.2 and optional K1 0.1.2+private.1. Existing private release bytes and application material are retained. This is a Node adapter correction; no Rerun profile, protocol frame, MQTT recovery state machine or shared lifecycle validator was modified. Physical Bluetooth discovery, Bridge, live camera/LiDAR and interruption recovery still require fresh-cache UI acceptance. No agent CLI hardware command is part of this test.