# ADR 0006: Vendor-neutral observation sources and live-only timeline Status: accepted for the experimental Mission Core runtime, 2026-07-16. Scope update, 2026-07-17: the live device descriptors in this ADR remain live-only. ADR 0008 adds a separate host-owned recorded-source catalog, seekable `session_time` playback and workspace layout; it does not retroactively turn a live RTSP lease into recorded evidence. ## Context The spatial scene and camera workspace must accept one device, a custom rig or a future multi-sensor vehicle without adding vendor-specific branches to the host UI. The currently verified K1 profile exposes one spatial visualization path and two path-labelled H.264 camera preview producers. The direct physical gate showed that only one K1 preview producer can deliver frames at a time. A shared point-cloud/video clock and camera intrinsics/extrinsics remain unavailable. Hard-coded camera slots, direct RTSP URLs in React components and an apparently seekable timeline would therefore create three false contracts: a fixed sensor count, browser ownership of device transport and replay that does not exist. ## Decision 1. A device plugin normalizes its capabilities into `ObservationSourceDescriptor[]`. Mission Core consumes only these generic descriptors. 2. `id` identifies a runtime source instance; `sourceId` identifies the producer inside the plugin model; `semanticChannelId` describes the canonical channel. Transport addresses are not identities. 3. Provider metadata and device/session/acquisition binding are separate. A new acquisition may change layout context without changing the logical producer. 4. The host owns visibility, z-order, position, resize and fullscreen. A plugin cannot inject global layout behavior. 5. Direct device RTSP URLs do not cross into the generic UI. The read-only K1 adapter publishes an opaque, same-origin fMP4/WebSocket delivery lease. 6. A descriptor may declare a generic activation group, capacity and selection state. The K1 camera producers share one group with `maxActive=1`; frontend layout enforces it for UX and the plugin remains the backend authority. 7. Until a bounded buffer and clock mapping exist, the shared timeline is `live-only`, `seekable=false`, `sessionRecording=false` and explicitly marked `host-arrival-best-effort`. 8. Directional 3D camera frustums are not rendered until calibration and extrinsics are available and verified. An unresolved camera may be listed as a source, but its orientation must not be invented. ## Current K1 mapping | Producer | Canonical channel | Host representation | | --- | --- | --- | | `sensor.lidar.primary` | `spatial.point-cloud.live` | primary Rerun viewport | | `sensor.camera.left` | `camera.preview.live` | auxiliary media window / camera card | | `sensor.camera.right` | `camera.preview.live` | auxiliary media window / camera card | Both camera producers share the proven canonical channel and remain distinct by `sourceId`. The plugin publishes both catalog rows dynamically, but delivery is present only on the selected producer. Selecting the peer tears down the old RTSP/FFmpeg generation before a new browser lease is issued. ## UI consequences - The spatial scene source picker renders any number of plugin-published sources. - Auxiliary media uses the design-system `WorkspaceWindow`, constrained to the scene bounds, with controlled drag, resize, close and maximize state. - The Cameras workspace filters media modalities and renders 0, 1, 2 or N cards; only its grid scrolls when the source count exceeds available space. - Point-cloud focus and camera focus stay inside the application panel rather than taking over the browser viewport. - Empty and declared channels remain honest placeholders; no demo frames or synthetic sensor values are substituted. ## Follow-up gate The local laboratory adapter now terminates RTSP/RTP with FFmpeg, copy-remuxes H.264 High L4 without transcoding and publishes complete bounded fMP4 segments to a generic MSE player. ADR 0008 subsequently added acquisition-owned durable segments, a prepared recorded-media manifest and host-arrival-best-effort rewind on the saved-session timeline. This is not proof of a shared device clock or frame-accurate LiDAR/camera alignment. Portable FFmpeg packaging, multi-consumer fan-out and remote/WAN delivery remain open. See ADR 0007 and ADR 0008. ## Code anchors - `apps/control-station/src/core/runtime/contracts.ts` - `apps/control-station/src/core/observation/useObservationLayout.ts` - `apps/control-station/src/components/ObservationSources.tsx` - `apps/control-station/src/components/ObservationTimeline.tsx` - `apps/control-station/src/workspaces/Workspaces.tsx` - `plugins/xgrids-k1/frontend/src/observationSources.ts` - `src/k1link/device_plugins/xgrids_k1/camera.py`