Fix onboard BLE admission and stage wireless device enrollment

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 12:11:48 +03:00
parent 2fdf1d3cc4
commit 77acb377e2
17 changed files with 297 additions and 65 deletions
@@ -0,0 +1,77 @@
# Node discovery admission and wireless enrollment R3
The owner tested the newly installed private K1 package through the Core Fleet
UI after clearing Chrome cache. At 11:55 MSK, choosing Find K1 produced an
unconfirmed-action notification. The board continued reporting idle with no
discovery generation change. Installation and worker readiness from R2 remain
valid observations; physical discovery was not accepted by that readiness check.
## Proven defect
NodeBridge passed `duration_seconds` and `operation_id` to `discovery.scan`,
but omitted `expected_snapshot_runtime_id`. The real XgridsK1PluginFacade
requires that field before invoking its BLE service. It raised
SnapshotRuntimeConflict before discovery, and the worker's generic HTTP 409
became the broker's unconfirmed-action result. Journald had no diagnostic entry
because that exception was deliberately swallowed without logging.
The earlier Node test replaced the facade, so it did not exercise this real
admission boundary. A regression test now replaces only the physical service:
the original code reproduces SnapshotRuntimeConflict; the fixed code admits
one scan with the exact requested runtime ID and rejects an old runtime without
another service call. No BLE I/O occurs in this test.
The adapter now forwards the admitted command's runtime ID. The runtime fence
itself is unchanged. Worker failures also emit only the admitted action and
exception class to the service journal; exception text, request bodies,
credentials and device data are never logged there.
## Owner-approved UI composition
The operator job is adding a supported wireless sensor to the chosen onboard
computer through its device-list plus action, in Core or the Node application.
The owner requested the same bounded modal with the title
«Подключение беспроводных устройств к БК» and a supported-device selector first.
The selector comes from installed sensor UI contributions. No hardware form or
request is mounted before choosing the model. Only XGRIDS LixelKity K1 is
currently contributed; a second model is not claimed to have a backend.
The host owns WirelessEnrollmentWindow and the selector; the selected plugin
owns its device workflow and actions through a typed render contract. This
replaces the single EnrollmentView slot that disappeared whenever more than one
plugin supplied a view. Ambiguous contribution IDs remain unavailable. The
alternative of putting a hard-coded model dropdown inside the K1 plugin was
rejected because it would leave the shared plus action owned by one vendor.
After choosing the K1 model, the operator can search Bluetooth and choose a
found scanner. Wi-Fi selection, credentials and Connect appear only for that
selected current candidate. Search, network lookup, verification and Connect
show their pending indicator and text inside their own button; the detached
bottom indicator is removed. Repeated actions/model changes are disabled during
an operation; closing stops observation without replaying or cancelling the
physical intent. Runtime/discovery changes retire selected-device credentials.
This is domain content in the existing modal. It reuses the pinned Design
Guideline Button, ActivityIndicator compact icon slot, Select, Window,
WindowFooterActions, ResourceRow, SettingsCard, TextField, StatusBadge and
ToastStack. No design-system geometry, CSS, icon or new product root was added.
Core Fleet and Node share the same component. LAB, recorded and live Rerun
settings and the K1 network/acquisition recovery state machine were not edited.
## Software acceptance
- Core architecture: 4 checks passed; TypeScript passed.
- Core full frontend suite: 787 passed, no failures or skips.
- Core production build passed; canonical port 8000 serves the exact new index
with Cache-Control no-store and operational readiness true.
- Node UI boundary check, TypeScript and production build passed; Go build and
Go package tests passed.
- 25 Python Node bridge, installer/import-boundary and Fleet enrollment checks
passed, including the real-facade regression and retained secret/idempotency
checks. Ruff and whitespace checks passed.
Node 0.8.1 and private K1 0.1.1+private.1 identify the replacement release;
previous R2 artifact bytes are retained. Exact source/release hashes and board
installation results belong in the following acceptance addendum. Hardware UI
discovery, provisioning, camera/LiDAR and recovery remain pending until a new
owner run with cache cleared before the test.