Files
NODEDC_MISSION_CORE/docs/audits/2026-09-06-node-k1-bridge-implementation.md
T

165 lines
10 KiB
Markdown

# K1 Bridge on the onboard computer
Authority: the owner's 2026-09-06 request and two annotated Fleet screenshots.
The earlier Node context is historical evidence, not a new instruction. X4 work
is paused while its battery charges. Hardware acceptance below remains pending
until the owner powers on K1 and supplies the target WLAN in the application.
## Product surface decision
The operator occasionally adds a wireless sensor to one selected onboard
computer. The primary entity is that computer's device inventory. Discovery,
network observations, credentials and device control belong to that computer;
the operator's Mission Core is a paired remote console. Node's local console
uses the same form and backend contract.
Selected composition: a plus beside refresh in the device inventory opens the
canonical modal Window, titled «Подключение устройства к БК». The target board
is visible before discovery or credentials. K1 is selected from an explicit
scan on that board. The operator chooses a board-observed WLAN or enters an
SSID, then submits one Bridge operation. Success requires observed device
connectivity; dispatch alone is never shown as connected.
An independent Fleet connection workspace was considered: it separates the
action from its board and can imply operator-local radios. A new primary root
was also unnecessary. The owner explicitly selected the inventory plus and
authorized moving the existing operator-local connection workspace into LAB,
with all its current modes and functions, under «Тестовые устройства».
The stable workspace ID is retained for saved navigation.
This is domain content in admitted list/detail and modal compositions. Reuse
`Window`, `WindowFooterActions`, `TextField` (including password), `Select`,
`Button`, `IconButton`, `ResourceRow`, `SettingsCard`, `StatusBadge`,
`ActivityIndicator`, `ToastStack`; icons `plus`, `refresh`, `network`, `camera`,
`eye`, `settings`, `close`, `play`, `stop`. These exist in the sibling Design
Guideline registries. No new generic visual entity is introduced.
State grammar: board unavailable; service unavailable; ready to scan;
scanning; no candidates; candidate selected; network list unavailable with
manual entry; ready to connect; connecting; observed connected; failed before
write; outcome unknown after possible write. A stale discovery/runtime or
changed board invalidates the form. Closing the modal clears its password.
Closing after dispatch does not claim cancellation of a physical operation.
## Execution and security boundaries
Only Bridge is admitted on Node. Reuse the reviewed firmware 3.0.2 profile and
99-byte 7f01 operation with 7f02 observation and exact endpoint verification.
No Quick Connect, host association, AP enable, subnet scan or firmware action
is exposed by the Node adapter. BLE notifications, where used by the existing
profile, can entail the standard temporary CCCD subscription write.
Use the existing authenticated Node/Core channel. A device-enrollment command
targets the paired node and a worker runtime/discovery generation, even before
a device session exists. Wi-Fi credentials must not enter the existing durable
sensor-command journal, Fleet database, error text, evidence or argv. Pending
secret payloads are short-lived memory only. A restart, expired command or
uncertain dispatch never retries a provisioning write with a new identity.
The Node worker is the sole hardware owner for both consoles.
Linux adapters must observe BlueZ and NetworkManager on the board. Host-route
verification uses the kernel route to the exact K1 address; a tunnel/default
route cannot silently qualify as the required local Bridge path. Existing
macOS adapter behavior and the accepted local LAB workflows are retained.
## Rerun profile boundary
| Profile | Source / clock | Settings authority | Lifetime |
| --- | --- | --- | --- |
| Live acquisition | Current board camera/LiDAR / stream_time | Live preview settings | Active acquisition and execution binding |
| Recorded session | Immutable admitted recording / session_time | Session replay, trajectory, time and playback settings | Recording identity |
| Laboratory result | Immutable admitted result and recording / session_time | Result-specific scene, evidence layers, diagnostic selections | Result identity |
The native renderer and recorded data pipeline can be shared, but each profile
has an explicit discriminator. Crossing profiles remounts the renderer so its
refs, subscriptions and pending recovery cannot leak into another profile.
LAB uses its own factory and result identity. Source recording/application IDs
remain unchanged: profile separation does not rewrite evidence lineage.
The Node publishes native RRD through ordered WebRTC data channels and the
existing camera gateway publishes H.264/fMP4 through a second channel. Signalling
uses paired sensor operations; ICE admits private LAN/Tailscale host candidates
only, with no STUN/TURN. The Node Rerun sink opens no gRPC port. Both hosts inject
the existing isolated native Rerun renderer into the shared sensor UI.
Two viewers at most are admitted. Decoded preview envelopes use latest-value
queues; encoded RRD bytes are never dropped within an open recording. Slow
consumers are closed. Camera preview leases share the canonical recording
producer. Closing a viewer releases its peer and delivery lease; acquisition
STOP remains a separate explicit operator action. These bounds concern delivery;
sustained native-viewer CPU/GPU/memory acceptance requires the real board test.
Node live settings (point size, accumulation, color, palette, points, trajectory,
grid) invoke only `viewer.settings.update` behind `profile=live-acquisition`.
Recorded and LAB profiles keep their own controls. LAB result changes remount
the renderer as well as changes between the three profile kinds.
## Validation and current acceptance
- Focused backend tests: board binding, expiration, replay prevention, secret
non-persistence, restart/unknown outcomes and Linux route classifications.
- Architecture gate; frontend typecheck, unit tests and build sequentially.
- Node package build and installation provenance; service health after reboot.
- Browser: both plus controls, target board, scan/empty/error states, manual
SSID, password clearing, keyboard Escape, normal/expanded live viewer.
- Real K1: one explicit scan/select/Bridge, actual DeviceInfo verification,
device appears in both inventories; camera and LiDAR acquisition/stop;
reconnect and restart; regression of local LAB and recorded replay.
No hardware acceptance or successful deployment is claimed by this document.
## Completed validation
- Core architecture gate: 4/4; complete frontend suite: 764/764 after updating
navigation expectations. Core and Node typechecks and production builds pass.
- Node Go tests pass, including redacted enrollment journal, one dispatch per
intent, restart outcome unknown, wrong node/expired request/host mutation deny.
- Focused Python Fleet, pairing, Node SDK, existing BLE scanner and Rerun tests
pass (one existing optional case skipped). Empty Node adapter construction,
public state and teardown pass locally, with no hardware discovery/listener.
- Six WebRTC tests pass, including an actual bounded loopback data-channel
roundtrip. Missing camera preserves the RRD channel; rejected offers release
the peer. Native RRD sink emits an RRF2 header without opening gRPC.
- All 51 Linux wheel hashes and archive members were checked. The only admitted
.pth is Rerun's literal package-directory declaration; bootstrap adds that
exact directory without executing path hooks. Ubuntu 24.04/amd64/Python 3.12
and fixed root-owned runtime paths are enforced. Installation checks idle
acquisition and stops the old K1 worker before replacing its modules.
- Canonical Core checkout was updated and its exact launch agent restarted.
`/api/liveness` and the new enrollment API pass; the paired board remains
online. Exactly one integrated backend remains on 8000, none on 8765.
- In-app browser: Fleet no longer contains the old connection workspace; LAB
opens Test devices with the existing K1 scenario. The vehicle inventory plus
opens the board-scoped modal. Unavailable-service state and Escape were
verified against the real paired board, which still runs the prior Node.
## Package and remaining work
Prepared package: `apps/node-agent/build/mission-core-node_0.7.0_amd64.deb`.
Size: 429540264 bytes. SHA-256:
`10b1164b57c31cd3edcced8653faf14cb9dc459db06442f0b417bc7f23bd4e76`.
The adjacent provenance includes base revision, exact source hashes, pinned Go
and Design Guideline identity and the locked wheel manifest. Maintainer scripts
inside the package match the reviewed sources.
The automatic approval reviewer rejected a proposed source-only Linux smoke
transfer because the board address was considered insufficiently authorized.
No proprietary source/package or application key was sent after that rejection.
Only dependency wheels and their build fetch script were staged in a separate
Downloads directory earlier; no board service/system installation has occurred.
An explicit confirmation of the exact target, package and encrypted credential
migration was requested after the concrete package was ready.
After that confirmation: install the package with the board administrator's
normal authentication, import the existing application key via protected stdin
and `systemd-creds`, verify Linux worker/BlueZ/NetworkManager and both UIs, then
ask the owner to power K1 for the admitted Bridge and acquisition tests. Wi-Fi
credentials are entered in the application only. Do not claim hardware, reboot,
expanded live-view, camera/LiDAR or sustained-resource acceptance before these
checks. Board source archives are retained by the canonical K1 runtime; Node's
recorded-session browse/export surface is not introduced in this change.
Direct Ops tools were unavailable in this session. This local audit records
profile distinctions and engineering evidence; no live Ops card update is
claimed. The user's historical attachments were context, not authorization.