chore(node): preserve pre-canonicalization experiment snapshot
Historical working copy retained for audit before consolidation into main. The canonicalized plugin architecture and later fixes already live in main; this snapshot is not a release or a request to restore obsolete source layout.
This commit is contained in:
@@ -171,6 +171,25 @@ mode. It never fragments or retries the payload automatically.
|
||||
|
||||
## Expected transition and evidence of acceptance
|
||||
|
||||
### Firmware station error replies
|
||||
|
||||
Offline review of the exact 3.0.2 `lixel_nman` callback found that station
|
||||
`wifi_connect` returns are passed directly to the 7f01 GATT write result:
|
||||
4 denotes its SSID-not-found paths and 6 denotes its credentials-required path.
|
||||
Generic Bluetooth libraries label the same values INVALID_PDU and
|
||||
REQUEST_NOT_SUPPORTED. Preserve those raw values but do not discard the
|
||||
reviewed device interpretation. The evidence and disassembly addresses are in
|
||||
[the callback audit](audits/2026-09-06-k1-station-reply-semantics.md).
|
||||
|
||||
Apply this interpretation only to the selected exact firmware station profile
|
||||
and its annotated 99-byte write-with-response failure. It does not apply to
|
||||
Quick Connect, a failed baseline read or arbitrary ATT errors. It grants no
|
||||
retry, network-state confirmation or ledger resolution. The firmware performs
|
||||
Wi-Fi work before completing this callback; a delayed reply alone is not proof
|
||||
that the BLE connection request was the slow stage.
|
||||
|
||||
### Acceptance observations
|
||||
|
||||
A completed GATT write only proves transport completion. It does not prove that
|
||||
the K1 joined Wi-Fi or began beaconing. The application polls `7f02`; the
|
||||
observed response frame contains a fixed-width text slot, an address slot, a
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
# K1 Bridge: provisioning recovery and first-scan discovery
|
||||
|
||||
Scope: the operator-local K1 connection in LAB on canonical Core `8000`.
|
||||
The onboard installation is a separate pending acceptance task.
|
||||
|
||||
The later [firmware callback audit](2026-09-06-k1-station-reply-semantics.md)
|
||||
explains the two fresh 19:22/19:23 UTC failures and supersedes the earlier
|
||||
generic ATT interpretation below with a bounded FW 3.0.2 station diagnosis.
|
||||
|
||||
## Evidence and diagnosis
|
||||
|
||||
Three explicit Bridge attempts returned HTTP 502 on 2026-09-06 at
|
||||
18:04:50, 18:05:13 and 18:05:43 UTC. All failed at `gatt-write` with
|
||||
`BleakGATTProtocolError`, ATT 4 `INVALID_PDU`. Each attempted one 99-byte
|
||||
write-with-response; acknowledgement and a joined Wi-Fi address were absent.
|
||||
The characteristic advertised `read, write`; the observed write-without-response
|
||||
capacity was 253 bytes. This capacity alone does not prove a successful ATT write.
|
||||
|
||||
A separately admitted, exact-target Bridge `connection.verify` at 18:15 UTC
|
||||
read K1 state without a provisioning write or host Wi-Fi switch. K1 answered,
|
||||
but supplied no shared-LAN address (`connection-verify-address-unavailable`).
|
||||
A preceding request was rejected at input validation because of the diagnostic
|
||||
operation identifier format; it performed no device I/O.
|
||||
|
||||
The same ATT error exists in August's private logs. The accepted August Bridge
|
||||
record uses the same Bleak 3.0.2, write mode, frame length and capacity. Successful
|
||||
historical writes also include an empty network baseline, so an empty baseline
|
||||
does not justify adding an AP-enable command or rejecting Bridge in advance.
|
||||
The exact reason for the peripheral's rejection remains unproved; a wrong Wi-Fi
|
||||
password, frame-format regression or MTU failure must not be asserted from this
|
||||
error alone. No alternate transport mode, frame, retry, START or STOP was sent.
|
||||
|
||||
Private evidence is retained under the ignored incident directory, with UTC and
|
||||
monotonic timestamps, redacted events and SHA-256 artifact index. Credentials and
|
||||
raw packet contents are absent from this report and source changes.
|
||||
|
||||
## Software causes and refactor
|
||||
|
||||
- The Connect hook had three overlapping result/error branches. Its failed
|
||||
HTTP path accepted the server snapshot but returned `observedState: null` to
|
||||
the form; the form therefore lost the exact operation and its ATT diagnosis.
|
||||
- A completed Bluetooth search suppressed the recovery surface even after the
|
||||
subsequent, click-owned Connect failed. The disabled credential form instead
|
||||
promised a future safe continuation despite there being no running operation.
|
||||
- Recovery guidance claimed an automatic recovery or a completed UI reset that
|
||||
had not occurred. The lead status fell back to idle despite a terminal failure.
|
||||
- Durable JSON logging omitted the write-mode, frame-size and GATT-property
|
||||
fields already supplied by the BLE implementation.
|
||||
|
||||
`networkProvisioning.ts` now owns the single submission, bounded observation of
|
||||
that exact idempotency key, monotonic snapshot selection and reviewed failure
|
||||
copy. An existing operation is only observed, never resubmitted. The runtime
|
||||
hook retains exact applied-network/control-authority checks and React action
|
||||
ownership. The form renders the returned operation and allows explicit recovery
|
||||
after its failed attempt even when its preceding search is complete. It still
|
||||
clears the credential immediately upon submission.
|
||||
|
||||
The frozen BLE frames and canonical MQTT dialogue are unchanged. Ops reference:
|
||||
MISSIONCOR-3, “Mission Core. Lixel K1 / XGRIDS Integration”, and
|
||||
`docs/lab/002_LIXELGO_IPHONE_LOCAL_PROTOCOL_20260716.redacted.md`.
|
||||
That iPhone capture begins at the IP stack and does not contain Bluetooth HCI.
|
||||
The reviewed BLE profile remains `docs/04_K1_WIFI_PROVISIONING_PROFILE.md`.
|
||||
|
||||
## Validation and remaining acceptance
|
||||
|
||||
Focused frontend: 227 passed, including new behavioral cases for HTTP 502,
|
||||
existing-key non-replay, lost-response success, pending settlement, stale REST
|
||||
versus newer WebSocket, superseded intent and unrelated journal rows. The
|
||||
rendered regression covers completed search followed by failed Connect and
|
||||
requires enabled recovery choices instead of the trapped form.
|
||||
|
||||
Full frontend suite: 772 passed sequentially; TypeScript and final production build passed. Application architecture: 4 passed.
|
||||
|
||||
BLE and persistent-diagnostic tests: 34 passed. Canonical guardrail: four
|
||||
immutable LixelGO captures verified in their original checkout, frozen
|
||||
protocol/Bridge contour unchanged, 32 synthetic sentinels passed. The convenience
|
||||
script initially failed because raw captures are deliberately absent from the
|
||||
active worktree; its original-location integrity check passed without copying
|
||||
or changing the captures. Ruff and diff checks passed.
|
||||
|
||||
A later runtime journal records an explicit successful Bridge write at 18:42 UTC,
|
||||
followed by application-control acceptance, canonical START and the first point
|
||||
frame, then a confirmed STOP at 18:44 UTC. These actions occurred while the
|
||||
assistant was editing/testing discovery; they were not dispatched by this
|
||||
investigation. The success followed the recovery-UI refactor and preceded the
|
||||
new discovery implementation. It proves a subsequent successful physical
|
||||
connection, not the cause or permanent resolution of the intermittent ATT error.
|
||||
Do not automatically replay the earlier failed attempts.
|
||||
|
||||
## First-scan miss
|
||||
|
||||
The operator reported that an already active K1 is absent from the first search
|
||||
and appears on the second. This was reproduced on the original six-second
|
||||
implementation: 18:32 UTC returned four devices and zero K1 candidates; a second
|
||||
explicit scan at 18:35 UTC returned five devices including the expected K1.
|
||||
These observations do not distinguish radio advertisement latency from macOS
|
||||
state and do not establish that the camera was powered off.
|
||||
|
||||
Discovery now opens one native Bleak scanner context. It listens for an initial
|
||||
six-second window and, if no K1 name has appeared, continues the same context
|
||||
up to a twenty-second bound, stopping on a later K1 candidate. There is no hidden
|
||||
second scan, GATT connection, provisioning retry or cache-based candidate
|
||||
promotion. Name matching only ends discovery; compatibility and connection
|
||||
still require their separate evidence. The owner arbiter, generation revocation,
|
||||
native-handle capture and cancellation cleanup remain in place. A caller's
|
||||
explicit shorter duration is respected.
|
||||
|
||||
The shared frontend request/countdown, backend default and Node Bridge source
|
||||
use the twenty-second bound. Completed operations and private structured logs
|
||||
now include scanner startup, total elapsed time, first-candidate time and whether
|
||||
the initial window was extended. They contain no Wi-Fi credentials.
|
||||
|
||||
After the new canonical process started, the first explicit UI search at
|
||||
18:51 UTC found the expected K1. Native startup took 766 ms, first K1 detection
|
||||
2023 ms from scanner construction, and total discovery 6768 ms. Extension was
|
||||
not needed. The browser showed the fresh candidate and the arbiter returned idle.
|
||||
This is one successful process-restart test; the browser cache was not cleared.
|
||||
The operator requested a separate test after browser-cache clearing. That
|
||||
acceptance is pending: the available in-app browser automation exposes no cache
|
||||
clearing capability, and the clear-browsing-data keyboard shortcut had no effect.
|
||||
The operator was asked to clear it; no cache clearing is claimed.
|
||||
|
||||
Additional discovery validation: 73 backend tests passed (scanner, owner arbiter,
|
||||
persistent diagnostics and Node Bridge), seven facade discovery tests passed,
|
||||
138 focused frontend tests passed, and architecture checks passed. TypeScript
|
||||
and production build passed. Final focused discovery checks, Ruff, whitespace
|
||||
and the frozen protocol/Bridge comparison passed. The previously completed full
|
||||
772-test frontend pass applies to the recovery refactor; only affected suites
|
||||
were rerun for the subsequent discovery change.
|
||||
|
||||
Canonical Core remains on port 8000; no listener exists on 8765. Onboard source
|
||||
is synchronized separately; this investigation does not install or rebuild the
|
||||
pending Node package.
|
||||
|
||||
## Ops publication
|
||||
|
||||
The existing Ops canon was read. Automatic approval review rejected the attempted
|
||||
card update because consultation was authorized but publication of internal
|
||||
technical details was not. No Ops card was changed; this local report is the
|
||||
reviewable result pending explicit publication authorization.
|
||||
@@ -0,0 +1,129 @@
|
||||
# K1 live reference comparison and missing camera
|
||||
|
||||
Scope: operator-local K1 Bridge data acquisition on canonical Mission Core 8000.
|
||||
No new physical START, STOP, provisioning or RTSP request was sent during this
|
||||
investigation. The comparison uses the existing 6 September capture.
|
||||
|
||||
## Authoritative references found in Ops
|
||||
|
||||
MISSIONCOR-3, “Mission Core. Lixel K1 / XGRIDS Integration”, block “Внутренние
|
||||
эталоны Mission Core” and its comment dated 22 August 2026 identify:
|
||||
|
||||
- Fast reference A: eaad9de, 20260822T105904Z_viewer_live. START to calibration
|
||||
under 5 seconds; calibration 21 seconds; after calibration cloud 2 seconds,
|
||||
right camera 4 seconds; STOP to physical onset 1 second.
|
||||
- Recovery reference B: 1001a31, 20260822T130323Z_viewer_live. START 14 seconds;
|
||||
calibration 22 seconds; cloud +1 second, camera +8 seconds; STOP onset 7 seconds.
|
||||
|
||||
The linked canonical report is
|
||||
[Lab 010](../lab/010_K1_MISSION_CORE_INTERNAL_LIVE_BASELINE_20260822.redacted.md).
|
||||
These are measured internal references for one K1 FW 3.0.2 and Bridge/direct LAN,
|
||||
not a transferable SLA or a standalone Rerun preset. A used a short physical
|
||||
ledger; B retained mature recovery history. Source quality was not reduced.
|
||||
|
||||
MISSIONCOR-66, “Mission Core. Канон интеграции Rerun”, and MISSIONCOR-74,
|
||||
“Additional Core · Переносимая кастомизация Rerun”, define the separate
|
||||
presentation contracts:
|
||||
|
||||
| Surface | Current profile | Clock and media |
|
||||
| --- | --- | --- |
|
||||
| Live acquisition | live-acquisition | stream_time; upstream live Rerun; right camera through the independent RTSP → durable fMP4 → MSE path |
|
||||
| Saved Sessions / Data | recorded-session | session_time; progressive recorded admission; RecordedFmp4Player follows the shared playback clock |
|
||||
| Canonical LAB result | laboratory-result | session_time; result-specific settings; merged RRD with native AssetVideo/VideoFrameReference; separate presentation gate |
|
||||
|
||||
The live receiver does not inherit the LAB full-readiness gate. Changing point
|
||||
size, accumulation or blueprint cannot repair a camera producer that never
|
||||
started. The current live display settings include accumulation 47 seconds,
|
||||
point size 1 and height/viridis; no evidence identifies those visual values as
|
||||
part of the fast reference, so they were not arbitrarily reset.
|
||||
|
||||
### Settings isolation limitation found during the audit
|
||||
|
||||
Distinct profile kinds, clocks and media admission do not prove complete
|
||||
settings isolation. App.tsx still owns one sceneSettings/displayDraft pair for
|
||||
live and Data, and useWorkspaceLayoutProfile() loads and saves one
|
||||
observation.spatial profile containing scene settings. The normal settings
|
||||
committer suppresses backend writes while recorded replay is presented, but it
|
||||
still updates the common in-memory settings. The persisted layout restore/apply
|
||||
path also has no profile-kind namespace. LAB uses its own resultId-scoped draft
|
||||
and durable view profile.
|
||||
|
||||
Therefore this audit confirms distinct presentation contracts and LAB settings
|
||||
ownership, not full live/Data settings isolation. No shared settings, layout,
|
||||
Rerun renderer or replay code was changed for this camera repair. The focused
|
||||
profile tests below do not cover the remaining live/Data settings coupling.
|
||||
Separating that storage and state requires its own transition/race and browser
|
||||
regression checks; it must not be folded into a camera-path fix implicitly.
|
||||
|
||||
## Observed 6 September failure
|
||||
|
||||
Existing session 20260906T184240Z_viewer_live:
|
||||
|
||||
| Metric | Fast A | Recovery B | Recent run |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| MQTT callback → publication p50 | 23.839 ms | 83.934 ms | 93.151 ms |
|
||||
| MQTT callback → publication p95 | 41.541 ms | 223.589 ms | 208.989 ms |
|
||||
| Preview drops | 0 | 70 | 58 |
|
||||
| Point decode errors | 0 | 0 | 0 |
|
||||
| Camera archive | complete | complete | absent |
|
||||
|
||||
Run lengths differ; drop counts are not normalized performance rates. Device
|
||||
calibration onset and first visible pixels were not independently measured in
|
||||
the recent run, so the historical operator timings are not falsely compared to
|
||||
backend timestamps. The recent run published 1,028,061 points in 386 PCL frames.
|
||||
|
||||
At 18:43:15 UTC the browser admitted a Rerun store; this alone is not proof of
|
||||
visible point pixels. Between 18:43:20 and 18:43:50 the backend logged 22 failed
|
||||
post-authoritative-PCL camera activations. First-PCL admission took 4–34 ms.
|
||||
No camera producer activation success or camera media artifact exists in this
|
||||
session. The private formatter discarded exception details, preventing recovery
|
||||
of each historical exception stack from those records.
|
||||
|
||||
## Reproduced storage defect and bounded repair
|
||||
|
||||
The running checkout is separate from MISSIONCORE_DATA_DIR. Acquisition uses
|
||||
resolve_missioncore_evidence_dir(), but XgridsK1CameraGateway previously confined
|
||||
session paths to repository_root. The actual session is outside the checkout.
|
||||
An offline call using the real existing session directory deterministically
|
||||
raised “camera recording root must stay inside the repository” before authority
|
||||
reservation, FFmpeg preparation or network I/O. Camera remained idle, matching
|
||||
the observed pre-producer failure. This mismatch necessarily blocks recording
|
||||
at the configured path even though the original exception stacks were lost.
|
||||
|
||||
The gateway now receives an explicit evidence_root from the existing service
|
||||
composition. It confines both acquisition-owned and selected-preview recording
|
||||
to that root after resolving paths. It rejects sibling directories and symlink
|
||||
escapes. The source checkout remains the FFmpeg-binary lookup root; the fallback
|
||||
for standalone gateway callers preserves their existing repository confinement.
|
||||
No RTSP arguments, video quality, stream choice, camera producer lifecycle,
|
||||
START/STOP, MQTT dialogue, Rerun blueprint or LAB/archive viewer policy changed.
|
||||
|
||||
Private exception diagnostics now retain only the exception class and final
|
||||
filename/line/function. They omit exception text, locals, source lines and
|
||||
absolute paths. This makes future failures attributable without leaking data.
|
||||
|
||||
## Validation and remaining physical acceptance
|
||||
|
||||
- Camera gateway suite: 42 passed, including seven new external-root,
|
||||
composition-wiring and path-confinement cases. Synthetic FFmpeg produced
|
||||
and archived media in the configured external directory.
|
||||
- Camera acquisition lifecycle: 37 passed.
|
||||
- Persistent diagnostics suite: 8 passed, including exception-location redaction.
|
||||
- Focused frontend profile, environment, LAB view profile and recorded-camera
|
||||
journal checks: 14 passed. These are contract-level checks, not physical
|
||||
playback acceptance or proof of complete settings isolation.
|
||||
- Mypy on camera.py and runtime_diagnostics.py: passed.
|
||||
- Ruff and git diff --check: passed.
|
||||
- Protocol, BLE provisioning/AP, physical ledger/coordinator, MQTT,
|
||||
connection supervisor, runtime and archive remain identical to c041a56.
|
||||
- The broad frozen-contour guard also includes camera.py, so it now deliberately
|
||||
detects this narrow camera storage change. Its baseline was not advanced or
|
||||
weakened. This is not a claim that the full freeze check passes unchanged.
|
||||
|
||||
The canonical idle service was refreshed and its replacement was confirmed
|
||||
ready on port 8000 at 19:10:22 UTC; no frontend rebuild was required. A new
|
||||
operator-started physical run is still
|
||||
needed to verify right-camera appearance, durable media and browser playback.
|
||||
The existing failed session is preserved and is not retroactively repaired.
|
||||
|
||||
Ops was consulted read-only. This local report was not published to a card.
|
||||
@@ -0,0 +1,95 @@
|
||||
# K1 station replies: misleading ATT error and fresh failures
|
||||
|
||||
Scope: the two operator-started Bridge attempts on Core 8000 following the
|
||||
operator-reported browser cache clear. No device write, START/STOP, Wi-Fi switch,
|
||||
subnet scan or firmware execution was performed by this investigation.
|
||||
|
||||
## Fresh evidence
|
||||
|
||||
| Attempt, UTC | K1 first advertisement | Complete scan | Connect operation | Reply |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| 19:22:25 | 1.308 s | 6.366 s | 51.399 s | ATT 4 INVALID_PDU |
|
||||
| 19:23:55 | 2.208 s | 6.023 s | 7.587 s | ATT 4 INVALID_PDU |
|
||||
|
||||
Both attempts reached the validated GATT contract, baseline status read and
|
||||
one 99-byte write-with-response. Neither write was acknowledged as successful.
|
||||
The observed command capacity was 253 bytes. Empty passwords are rejected
|
||||
before this path; presence does not prove correctness. Individual connect and
|
||||
write durations were not recorded, so total latency is not falsely attributed
|
||||
entirely to the Wi-Fi operation or entirely to CoreBluetooth.
|
||||
|
||||
Private snapshots, operation identities and the disassembly are retained under
|
||||
the ignored `.runtime/k1-connect-incident-20260906/fresh-1922/` directory with
|
||||
0600 files, UTC/monotonic timestamps and a SHA-256 artifact index.
|
||||
|
||||
## Firmware-level explanation
|
||||
|
||||
The reviewed official FW 3.0.2 artifact is the immutable source documented in
|
||||
[Lab 004](../lab/004_K1_FW302_AP_CREDENTIAL_PROVIDER_20260720.redacted.md).
|
||||
Its extracted `lixel_nman` executable is 323,464 bytes, SHA-256
|
||||
`aead745e4e0073ae99e84e851e5560161f2d560d5804f21e5268116efbb1dc42`,
|
||||
ELF build ID `205fb546e44667ca0e74159a7672269a81b754f5`.
|
||||
|
||||
Bounded offline AArch64 disassembly established:
|
||||
|
||||
1. At 0x14588 the service registers characteristic 7f01, with write callback
|
||||
0x17e48 selected at 0x14598.
|
||||
2. Its station branch calls `wifi_connect` at 0x18034 → 0x15440. The return
|
||||
value is retained in w28 at 0x18038 and passed as the write-result error at
|
||||
0x17fc4 → 0x291a8.
|
||||
3. `wifi_connect` returns 4 in its network-not-found branches: 0x16190 and
|
||||
0x16a2c. Adjacent diagnostics refer explicitly to the SSID not being found.
|
||||
4. The branch matching NetworkManager's credentials-required output returns
|
||||
6 at 0x1641c. This describes an unsuccessful credential path, not proof
|
||||
of the exact incorrect character or how the form was populated.
|
||||
|
||||
Thus the device's application return codes collide with generic ATT names:
|
||||
4 is displayed as INVALID_PDU and 6 as REQUEST_NOT_SUPPORTED. The existing
|
||||
Mission Core message discarded the reviewed device meaning. Neither changing
|
||||
the 99-byte layout nor switching write mode follows from these observations.
|
||||
The callback performs Wi-Fi work before returning, so its response is not merely
|
||||
an instantaneous transport acknowledgment.
|
||||
|
||||
This is an interpretation under the selected exact firmware profile. It is not
|
||||
a universal ATT error mapping, proof of the live firmware before DeviceInfo,
|
||||
or confirmation that the network configuration remained unchanged. The actual
|
||||
SSID/radio condition still needs a corrected operator-run connection test.
|
||||
The old screenshot displays a network name whose exact spelling was queried;
|
||||
this report does not assume that spelling is a typo or assume K1 can see it.
|
||||
|
||||
## Bounded correction
|
||||
|
||||
`wifi_failure.py` owns the pure profile-scoped classification. The service uses
|
||||
it only for Bridge/Direct, selected FW 3.0.2, an annotated gatt-write failure,
|
||||
a dispatched/unconfirmed 99-byte write-with-response and BleakGATTProtocolError.
|
||||
It retains the original exception code and raw ATT facts. Quick Connect,
|
||||
baseline-read failures, other firmware and unrelated errors retain their
|
||||
original diagnostics. Retry flags, mutation ledger and ambiguity remain intact.
|
||||
|
||||
The frontend shares the station guidance between the form and recovery panel.
|
||||
It offers “Указать сеть Wi-Fi заново” through the existing explicit reset and
|
||||
scan flow. The pending stage explains K1 Wi-Fi connection. It does not populate,
|
||||
store, inspect or change the password. The GATT helper, packet bytes, MQTT,
|
||||
physical command control and all Rerun profiles are unchanged in this increment.
|
||||
|
||||
## Validation
|
||||
|
||||
- 19 focused backend cases passed: 16 classification boundary cases, two
|
||||
service-level reply cases and the existing ambiguous-write recovery case.
|
||||
They verify one submission, retained raw codes, failed/unconfirmed state and
|
||||
an unresolved ledger rather than promoting an error to success.
|
||||
- 24 classification/diagnostic cases passed; mypy and Ruff passed.
|
||||
- 775 frontend tests passed, including rendered station guidance and the
|
||||
explicit same-device network setup action. Architecture: 4 passed.
|
||||
- Production typecheck and build passed. The replacement canonical Core was
|
||||
confirmed ready at 2026-09-06T19:41:10.665304+00:00.
|
||||
- Browser check: the real Core 8000 Test Devices page loaded; normal and expanded
|
||||
sizes worked. The page was left open. No BLE action was clicked. The new error
|
||||
messages were covered by rendered tests, not represented as a new hardware run.
|
||||
- Hardware Wi-Fi acceptance remains pending the exact target SSID and an
|
||||
operator-started attempt. macOS networksetup did not provide the current SSID;
|
||||
its output was not treated as proof that the host network is down.
|
||||
|
||||
Ops MISSIONCOR-3 was read through the direct MCP. Its iPhone network capture
|
||||
starts at IP and does not contain Bluetooth HCI; it cannot establish the meaning
|
||||
of this GATT callback. No Ops card was written.
|
||||
@@ -0,0 +1,164 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user