Preserve onboard preview recordings across backpressure and share the complete spatial scene

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 17:47:10 +03:00
parent 9b6534287a
commit 9bba44f7c4
30 changed files with 957 additions and 494 deletions
@@ -117,3 +117,12 @@ is preserved by package removal/upgrade; public R12 preparation leaves it in
place and the service consumes the same systemd credential. Thus this artifact
is an update for the existing R11 board, not a self-contained credential-bearing
installer for a new board. The older private release is not altered.
## Installed outcome and failed stability acceptance
The owner subsequently reported installer exit 0. Read-only dpkg inspection
confirmed Node 0.8.9 and K1 0.1.9, with active service and zero service restarts.
Camera and cloud appeared, but repeated outbox Full / media backpressure caused
preview recording replacement and history loss. R12 is not accepted as stable.
The follow-up investigation and correction are recorded in
`2026-09-07-k1-onboard-preview-continuity-r13.md`.
@@ -0,0 +1,93 @@
# K1 onboard preview continuity and canonical scene R13
## Observed regression
The owner confirmed R12 installation exit 0. Read-only package inspection
confirmed Node 0.8.9 and K1 0.1.9. The service was active with NRestarts=0.
Camera, points and trajectory appeared, but the live scene repeatedly went black
and accumulation/route restarted. A bounded journal selection for that exact run
showed repeated `Node RRD subscriber failed exception=Full`, plus media delivery
RuntimeErrors. This is failed preview acceptance, not an accepted R12 release.
The encoded outbox previously raised Full after 500 ms. SCTP delivery also
terminated a peer after two seconds of backpressure. Every replacement peer
constructed a new RerunBridge, called begin_session and discarded trajectory and
recording identity. Separately, the UI hid the entire scene whenever source age
expired. No scanner/service restart is needed to explain these symptoms.
## Continuity contract
Preview protocol v3 keeps one native recording per acquisition view. The browser
keeps its native channel and acknowledged batch cursor while disposable WebRTC
peers recover. The board retains the corresponding subscriber for up to five
minutes after disconnection. Every complete RRD batch is numbered and ACKed;
a lost ACK causes retransmission of identical bytes, and the browser deduplicates
it. Cursor mismatch/expired resumption reports a terminal reopen instruction;
it must never silently create replacement history. Explicit view close frees
capacity immediately; acquisition close retires every view.
The encoded outbox is bounded to two queued batches, one pending batch and one
encoder-held batch, each no larger than 8 MiB. It waits without killing the
recording. Decoded input coalesces independently per modality. The acquisition
producer/archive never waits for the preview. Route snapshots come from the
already bounded acquisition-owned trajectory, including motion during preview
congestion. This is a disposable live view, not a replay of every archived frame.
The chosen accumulation window still governs how long points remain visible.
Data-channel buffering is bounded at 256 KiB. Backpressure pauses sending while
the peer is alive; a 30-second keepalive expiry bounds abandoned peers. Preview
close/recovery does not send START, STOP, Wi-Fi, BLE or camera-producer commands.
Camera lease renewal requires an existing active recording and restarts only
the browser decoder. Source age includes time spent receiving each RRD payload;
repeated metadata cannot make old points fresh. Stale history remains visibly
marked instead of being replaced with a black canvas.
## Exact scene composition
The owner supplied the direct LAB scene as the composition reference. Shared
`SpatialScene` now owns the existing toolbar, renderer allocation, device-control
slot, source controls, engine status, metrics, navigation hint, timeline and media
slots. Direct live and recorded hosts retain their existing renderers, profile
factories, AI/replay controls and authority. Their markup is consumed through
the shared scene instead of being independently re-created in the K1 Node UI.
The original K1 phase/telemetry capsule is extracted as `K1SpatialSession`, with
pure shared phase/metrics vocabulary. Direct and onboard views use the same
calibration/completion copy, timing, route, speed and capsule geometry. The
onboard adapter receives the actual acquisition phase; manual STOP uses the
existing guarded operation. The scene stays mounted during calibration and STOP.
The onboard scene uses the same ApplicationPanel header and floating camera
window: title “Пространственная сцена”, live/wait status, expand and close. It
omits LAB, descriptive subtitle, disk action and unused AI mode buttons. The
three engine/layers/display tools, accumulation and movable/resizable camera
remain. The enrollment “Настроить устройство” primary button occupies full width.
No new Design Guideline primitive, navigation root, recorded blueprint, archive
format, credential source or physical reconnection supervisor is introduced.
## Validation
- Full Control Station regression: 804/804 passed after shared composition/model
extraction. Focused UI checks are repeated after final media lifecycle changes.
- Python: 92 relevant tests across native RRD (6), media (10), Node control (22),
installer (11) and camera gateway (43) covered by the combined pass and final
affected-subset pass. The final native/media/control subset passed 38/38.
- Regressions include a blocked native outbox beyond 500 ms, ACK loss/resumption
of the same native subscriber, expired cursor rejection, explicit view disposal,
SCTP backpressure beyond two seconds, native RRD fragmentation, and idle/resume
of a real bounded loopback WebRTC peer with camera. No physical device commands.
- Both UI typechecks and production/package builds are required before staging;
final artifacts and installation outcome are recorded below when available.
The owner confirmed STOP; the paired Fleet snapshot was subsequently idle with
control phase completed. Canonical Mission Core remains on port 8000. CUA exposes
an in-app browser without documented cache/click controls, not the owner's
Chrome session. Opening the home page is not clean-cache hardware acceptance.
Required owner UI acceptance remains: clear Chrome cache before each run; START,
calibration, camera/points, move the scanner, ensure route survives a delivery
pause; move/resize camera; STOP and observe finalization. No Ops write or Git push
is retried after the earlier automatic-approval rejections.
R13 is a matched public update: Node 0.8.10 and K1 0.1.10, protocol v3. It uses the
existing root-owned encrypted K1 credential. No Keychain read or secret-bearing
installer is part of this build. The standard installer safe-state guard remains.