NODEDC_MISSION_CORE/docs/01_IMPLEMENTATION_PLAN.md

13 KiB

Implementation plan

This plan supersedes the app-dependent experiment order in the reference Bible. Each gate produces evidence and an explicit GO, PAUSE or BLOCKED result.

Current checkpoint — 2026-07-18

Stage Result
Stage 0 host/repository GO — isolated Python 3.12 environment and private Git
Gate 1 physical operation GO — autonomous double-click start/stop verified
Stage 1 BLE discovery GO — repeatable advertisement and GATT profile
Stage 2 BLE provisioning GO — reviewed 99-byte profile, LAN association confirmed
Stage 3 application session GO — MQTT 3.1.1 on confirmed K1 TCP 1883
Stage 4 artifacts/flows GO — bounded capture, hashes and negative control
Stage 5 point cloud GO — raw-LZ4 protobuf, 1,140 live frames decoded
Stage 5 pose GO — 1,215 live frames decoded and motion-correlated
Stage 5 modeling telemetry GO (read-only) — bounded ModelingReport decoder and device-reported scan time/distance/speed are integrated before the preview queue
Stage 5 camera GO (live) — left/right RTSP/H.264 preview observed, read-only runtime adapter and physical UI acceptance completed
Stage 6 live viewer GO — React Control Station, embedded self-hosted Rerun cloud/trajectory, plugin-owned spatial controls and live device/Mac metrics
Stage 7 observation archive GO (point/pose/telemetry contract) — durable catalog, recovery, capture-clock-bounded RRD preparation, archived metric time series, saved-session timeline and atomic playback are implemented
Stage 7 recorded cameras GO (contract), acceptance pending — acquisition-owned fMP4 archive and player are implemented/tested; one real archived K1 camera plus point-cloud session has not passed playback yet
Plugin isolation GO (laboratory control plane) — vendor backend/frontend and optional scene controls are plugin-owned; manifest/runtime descriptor parity, versioned handshake, lifecycle health and transport correlation fail closed while execution remains in-process
K1 application control PAUSE (offline execution gate complete) — exact five-batch response-barrier orchestrator passes the retained 10-request dialogue; the 36-byte application authority loads only from macOS Keychain; current publisher boundary is structurally write-disabled and never touches its sink; runtime wiring, physical START/STOP and durable save remain closed gates
Stage 8 product storage PAUSE — retention, replication, encryption, capacity monitoring and long-run browser/WASM stress remain deployment gates

USB project copying remains optional ground truth rather than a blocker for the now-verified network path. Owner-operated LixelGO traffic verifies the MQTT start/stop mapping and RTSP camera transport. The exact start/stop protobuf encoder, response correlator and device-status state machine now exist without a publisher. Retained PCAP plus client static analysis prove that OpenAPI is one private application-level value in this LixelGO build, not a per-scanner credential. The selected BLE peripheral returns its own LAN IP; the initial unbound DeviceInfoRequest then returns vendor ID, serial, model, activation and version facts for that live K1. Mission Core's shadow bootstrap reproduces the 10 observed pre-START requests byte-for-byte across five recovered batches: initial DeviceInfo binding; ModelingStatus plus RTK read; time sync plus DeviceInfo/RTK; NTRIP read; then cloud/RTK/DeviceInfo reads. The first ModelingStatus request has no mandatory synchronous response barrier; readiness is separately attested through live DeviceStatus. A fixed macOS Keychain loader now reads the exact 36-byte authority without environment/file/browser fallback. The response orchestrator correlates required headers/results and rejects identity/profile drift. The installed publish boundary is a separate write-disabled type that cannot call its injected sink. Runtime wiring, a reviewed write-capable type and durable post-stop save remain unproven. The physical button remains the known-safe fallback.

The Stage 6 live path uses a bounded raw-first bridge: loss in the visualization queue cannot discard MQTT evidence. The queue holds four preview messages; ModelingReport is consumed by a plugin-injected observer before that queue and does not compete with point/pose frames. A project name is mandatory at preparation, NFKC-normalized/trimmed on both sides, rejected for control or surrogate characters or more than 96 characters, and retained only as display metadata.

Stage 7 adds an independent durable observation-session lifecycle. New native captures durably publish the clock origin before camera production, retain a transport-scoped provisional envelope and atomically switch the capture-summary pointer to a content-addressed session envelope after all producers stop. Completed or recovered captures are prepared once by a bounded backend worker into digest-bound RRD/cache-v9 and camera-manifest generations; a browser replay request never performs conversion. The RRD materializes real origin/end rows plus archived device-reported distance, speed and scan-time series. The saved scene, controller and timeline remain hidden until the complete RRD range and every declared camera pass admission. Sensor-to-display latency and camera/LiDAR sensor-clock alignment remain separate correlation tests.

The generic host clears a prior manual or archived spatial source only after a plugin-owned live/file-replay start succeeds; a failed start preserves the current scene. Once an acquisition is nonterminal, a fail-closed guard blocks saved-session switching, persisted replay reattach and manual source input/apply/reset until that acquisition has been finalized. The successful automatic-source action is an internal start-result boundary and intentionally does not masquerade as an operator source switch. The K1 scene-level stop control is plugin-owned; with the active read-only profile it stops and seals local reception only and never claims to stop the scanner.

Stage 0 — repository and host baseline

Deliverables:

  • local Python 3.12 .venv and lock-file;
  • k1link doctor with no side effects;
  • immutable reference documents and checksums;
  • safety policy, artifact policy, session manifest schema;
  • no Homebrew changes and no K1 interaction.

Acceptance:

  • uv sync --group dev succeeds;
  • uv run k1link doctor identifies a local .venv;
  • tests, Ruff and mypy pass;
  • repository contains no secrets or real captures.

Gate 1 — physical and USB baseline

Code needed: none initially.

Actions:

  1. Record masked device identity, LED boot sequence, battery and visible state.
  2. Determine whether the unit is activated; solid-yellow or an activation prompt is treated as a distinct blocker.
  3. Run one short autonomous button scan: start, keep still for at least 20 seconds, move through a simple scene, stop.
  4. Enter USB mode using the documented physical shortcut if available.
  5. Copy a project tree and selected metadata/logs into an ignored session path.
  6. Hash every copied file and create a redacted manifest.

GO: the unit boots normally and records a usable autonomous project.

PAUSE: USB access is unavailable but the scan succeeds; continue BLE while documenting the missing ground truth.

STOP: serious fault, overheating, activation lock, or destructive/ambiguous device state.

Stage 1 — BLE non-mutating discovery and metadata toolkit

Minimal dependencies: bleak plus the existing CLI stack. Add them only in the repository-local environment.

Commands:

k1link ble scan
k1link ble gatt-dump
k1link ble listen

Requirements:

  • preserve advertisement snapshots, manufacturer/service data and RSSI;
  • describe macOS scanning as active discovery: CoreBluetooth does not support passive scan mode, although discovery does not change K1 configuration;
  • identify by observed name + macOS UUID + advertisement fingerprint;
  • inspect standby, scanning and USB states separately;
  • start with standard Device Information/Battery services;
  • custom characteristic reads are opt-in because proprietary reads may have side effects;
  • notifications are subscribed one characteristic at a time and logged to timestamped JSONL;
  • no arbitrary characteristic or provisioning writes in this stage. Enabling a notification normally updates the standard CCCD descriptor; this temporary, reversible protocol write is disclosed and handled separately from device configuration.

GO: reproducible K1 advertisement and useful GATT map.

PAUSE: permission or pairing/authentication is required.

Gate 2 — existing network behavior

Do not change Deco settings first.

Actions:

  1. Save the Mac interface and route table.
  2. Observe router client list and Mac ARP/neighbor state with K1 off.
  3. Repeat after K1 boot, during standby, scanning and after one power cycle.
  4. Check for new Wi-Fi SSIDs exposed by K1 without attempting to join unknown networks automatically.
  5. Confirm any candidate by disappearance/reappearance with K1 power state.

GO-A: K1 joins a remembered LAN. Provisioning leaves the immediate critical path and work moves to the application-session gate.

GO-B: K1 exposes its own AP. Document it as a separate topology and determine whether Mac can join without modifying router configuration.

BLOCKED: neither association nor AP exists; provisioning becomes Stage 2.

Stage 2 — no-app provisioning research

This stage answers whether SSID/PSK can be sent safely from Mac. A generic BLE transport does not define the vendor payload.

Evidence sources allowed before a write:

  • GATT UUIDs, properties and descriptors;
  • standard service identification;
  • read/notify state transitions correlated with network state;
  • owned K1 project logs and metadata;
  • public official firmware/documentation static evidence if separately reviewed;
  • deterministic structure inferred without sending device mutations.

Before enabling any write profile, document:

  • exact service/characteristic and required security mode;
  • packet framing, encoding, ordering and length rules;
  • SSID/PSK redaction and secure input path;
  • checksum, nonce, token, certificate or signature fields;
  • commit/connect command and status response;
  • timeout, failure state, power-cycle behavior and rollback;
  • one explicit confirmation flag in addition to a named reviewed profile.

GO: a deterministic provisioning profile exists with an explained expected state transition and safe rollback.

HARD BLOCK: K1 knows no network, exposes only opaque vendor GATT, and no evidence source reveals the protocol. Random writes are not an alternative.

Stage 3 — application session and targeted capture

Prerequisite: confirmed K1 IP or direct AP topology.

Implementation order:

  1. Passive ARP/mDNS/SSDP and K1-filtered tcpdump baseline.
  2. Small targeted TCP connect check against the confirmed IP.
  3. Service detection only where the prior step supplies evidence.
  4. Parse K1 logs for daemon names, ports and protocol strings.
  5. Add protocol-specific connection attempts only for demonstrated endpoints.
  6. Model WIFI_ASSOCIATED_BUT_NO_DATA_SESSION explicitly.

k1link net capture must show the exact interface/filter, request privilege in the foreground, handle Ctrl+C, and never configure persistent sudo or ChmodBPF.

GO: Mac becomes a K1 endpoint or receives a reproducible scan-correlated flow.

BLOCKED: application session requires an unavailable mutual-auth token, certificate or undocumented handshake.

Stage 4 — session artifacts and flow analysis

Implement only after real traffic exists:

  • versioned session manifest;
  • UTC and monotonic timeline events;
  • SHA-256 inventory;
  • TCP reassembly and UDP flow grouping;
  • packet/byte rates, length histograms, entropy and first-byte fingerprints;
  • idle versus scanning correlation;
  • negative-control flows to reduce false positives.

GO: repeatable flows can be separated and ranked without losing raw evidence.

Stage 5 — decoders by evidence priority

Priority:

  1. device/scan status;
  2. point-cloud preview;
  3. pose/trajectory;
  4. camera/panorama/video.

Add dependencies per decoder extra, not to the base environment. Point-cloud and video signature probes operate on reassembled flows, not isolated packet payloads. A candidate becomes a decoder only after a controlled physical test confirms it.

MVP GO: K1-to-Mac scan-correlated data can be captured reliably and at least one useful stream is decoded or structurally identified.

Deferred work

  • ROS2/MCAP bridge;
  • onboard computer and drone integration;
  • automated scan-button electronics;
  • OpenWrt/monitor-mode infrastructure;
  • firmware or internal-Linux analysis;
  • physical end-to-end shared-timeline playback for a newly archived session containing point cloud plus one selected K1 camera;
  • operator-owned Keychain provisioning/execution lease, authorized command transport and stable-artifact proof after the observed stop lifecycle;
  • long-running large-session WebViewer/WASM memory telemetry;
  • production retention, replication, encryption and cross-platform packaging.