151 lines
6.9 KiB
Markdown
151 lines
6.9 KiB
Markdown
# ADR 0042 — K1 run ledger and regression telemetry
|
|
|
|
Status: proposed for acceptance
|
|
Date: 2026-08-22
|
|
|
|
Named physical references and redacted evidence hashes are retained in
|
|
[`docs/lab/010_K1_MISSION_CORE_INTERNAL_LIVE_BASELINE_20260822.redacted.md`](../lab/010_K1_MISSION_CORE_INTERNAL_LIVE_BASELINE_20260822.redacted.md).
|
|
That report deliberately distinguishes the fast Mission Core internal
|
|
ideal-path reference from the accepted recovery-capable checkpoint and from
|
|
manufacturer/LixelGO evidence.
|
|
|
|
## Context
|
|
|
|
The K1 integration has repeatedly returned to the same visible failures after
|
|
otherwise successful recovery work: delayed first point cloud, a camera that
|
|
repeatedly disappears and reopens, browser decoder failures, slow START/STOP,
|
|
and connection-mode transitions that disturb an already accepted Bridge path.
|
|
|
|
The current evidence is individually strong but operationally fragmented. Raw
|
|
MQTT capture, camera fMP4 epochs, acquisition checkpoints, browser diagnostics,
|
|
redacted manifests and operator timing notes use different identities and must
|
|
be correlated manually. A successful run is described in Ops, but is not yet an
|
|
executable baseline that can reject a later regression.
|
|
|
|
The repository already owns an accepted telemetry plane under ADR 0031:
|
|
Telegraf and a bounded native JSONL outbox publish through authenticated MQTT to
|
|
the Mission Core normalizer and TimescaleDB. Introducing another broker or
|
|
database solely for K1 would create a second lifecycle, credential boundary and
|
|
recovery problem without improving the local K1-to-Mission-Core evidence path.
|
|
|
|
## Decision
|
|
|
|
Every physical or replayed K1 acquisition is one explicit **K1 run**. The run is
|
|
identified by the acquisition id and its evidence-session lineage. All derived
|
|
events carry the same redacted identity, code revision, UI build id, connection
|
|
mode and monotonic clock origin.
|
|
|
|
The authoritative write path is:
|
|
|
|
```text
|
|
K1 control, MQTT receiver, camera gateway and browser diagnostics
|
|
-> local append-only K1 run journal
|
|
-> bounded durable outbox
|
|
-> authenticated telemetry MQTT topic
|
|
-> existing Mission Core telemetry normalizer
|
|
-> existing TimescaleDB
|
|
-> run comparison and acceptance report
|
|
```
|
|
|
|
The local journal remains the source of truth during network loss. Database
|
|
availability never gates START, STOP, raw evidence capture, camera archival or
|
|
local recovery. Delivery resumes from the outbox when the telemetry contour is
|
|
available.
|
|
|
|
The initial event contract is `missioncore.k1-run-event/v1`. Each event contains:
|
|
|
|
- `run_id`, `acquisition_id`, redacted `evidence_session_id` lineage;
|
|
- UTC and monotonic timestamps plus a per-run sequence number;
|
|
- Mission Core commit, UI build id and K1 compatibility-profile id;
|
|
- connection mode, host-path epoch and producer generations without addresses,
|
|
credentials, project names or raw device identifiers;
|
|
- event code, stage, outcome and bounded numeric facts;
|
|
- source component and source schema version.
|
|
|
|
The required timeline includes at least:
|
|
|
|
- operator START intent, physical command publication and confirmed SCANNING;
|
|
- calibration start/end when the device exposes those facts;
|
|
- first authoritative PCL received and first PCL published to Rerun;
|
|
- browser Rerun store admitted and first visible point-cloud frame;
|
|
- camera producer init, first media, browser first frame and sustained playing;
|
|
- camera decoder errors, preview-reader retirements, IDR admission, queue age,
|
|
bytes and fragment counts;
|
|
- connection gap start, recovery attempts, recovered binding and gap end;
|
|
- operator STOP intent, confirmed READY and archive finalization;
|
|
- terminal run result and automatically evaluated acceptance checks.
|
|
|
|
An acceptance report is generated from the journal after each run. It compares
|
|
the run with a named accepted baseline and reports exact deltas. The following
|
|
conditions are hard failures rather than performance warnings:
|
|
|
|
- any browser `MEDIA_ERR_DECODE`;
|
|
- any decode error in the archived camera stream;
|
|
- a missing first point-cloud admission or missing terminal archive;
|
|
- loss of acquisition/control lineage;
|
|
- a device state asserted by the UI without authoritative device evidence.
|
|
|
|
Latency and FPS thresholds are versioned baseline checks. They are never
|
|
implemented by silently reducing point count, image quality, bitrate or source
|
|
FPS. A threshold change requires its own reviewed acceptance run.
|
|
|
|
The engineering work format changes accordingly:
|
|
|
|
1. Name the accepted baseline and the single invariant targeted by the change.
|
|
2. Make one bounded implementation increment.
|
|
3. Run focused synthetic tests before a physical test.
|
|
4. Perform one canonical UI run; do not substitute direct device commands.
|
|
5. Generate and retain the run comparison automatically.
|
|
6. Do not merge a change that improves its target while regressing an already
|
|
accepted invariant.
|
|
|
|
## Rejected alternatives
|
|
|
|
### Redis
|
|
|
|
Redis is useful for disposable cache and coordination. It is not the evidence
|
|
system of record for offline physical runs and does not replace a durable local
|
|
journal or analytical store.
|
|
|
|
### Kafka
|
|
|
|
Kafka is not admitted for this local single-producer contour. The existing MQTT
|
|
plane already supplies authenticated fan-out and reconnect delivery, while the
|
|
local outbox supplies offline durability. Kafka would add a second broker and
|
|
operational quorum without repairing the K1, RTSP, browser or local-network
|
|
boundaries. It can be reconsidered only when independent high-volume consumers,
|
|
cross-site retention or replay requirements exceed the accepted MQTT contour.
|
|
|
|
### ClickHouse
|
|
|
|
ClickHouse is not admitted as a second telemetry database. Existing TimescaleDB
|
|
already stores run identity, timestamps and JSON payloads and is sufficient for
|
|
the current event volume and comparisons. The event schema remains storage
|
|
neutral, so a later measured analytical-volume limit can justify a reviewed
|
|
ClickHouse migration without changing producers.
|
|
|
|
## Implementation increments
|
|
|
|
1. Generate a local K1 run report from the evidence and diagnostic artifacts
|
|
already produced today; no runtime transport change.
|
|
2. Emit the versioned append-only event contract directly during a run and seal
|
|
it with the evidence session.
|
|
3. Tail the bounded outbox through the accepted ADR 0031 telemetry plane and
|
|
extend the normalizer with K1 run series.
|
|
4. Add baseline comparison and a CI/replay gate. Physical acceptance remains a
|
|
separate operator-controlled UI test.
|
|
|
|
No product window, status family or K1 control command is introduced by this
|
|
decision.
|
|
|
|
## Consequences
|
|
|
|
- A stable K1 run becomes executable regression evidence rather than a prose
|
|
memory.
|
|
- Camera, point-cloud, control and recovery events can be compared on one clock
|
|
and one run identity.
|
|
- Wi-Fi or telemetry-plane loss cannot erase the local run or block the device.
|
|
- The existing telemetry stack is extended instead of duplicated.
|
|
- The first implementation work is an evidence/reporting increment; it does not
|
|
authorize broad recomposition of the fragile K1 communication path.
|