feat(perception): integrate calibrated operator pipeline
Add calibrated K1 projection, recorded and near-live perception qualification, unified Rerun operator layers, bounded replay admission, audited viewer controls, worker experiments, and lab evidence.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
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-19
|
||||
## Current checkpoint — 2026-07-20
|
||||
|
||||
| Stage | Result |
|
||||
| --- | --- |
|
||||
@@ -11,7 +11,7 @@ Each gate produces evidence and an explicit GO, PAUSE or BLOCKED result.
|
||||
| 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 2 local connection matrix | GO (implementation) — Bridge remains physically accepted; Direct Connect reuses the reviewed one-shot BLE frame; Quick Connect uses one CoreWLAN host association and no GATT write. Direct Connect and Mission Core Quick Connect still require separate physical acceptance |
|
||||
| Stage 2 local connection matrix | GO for Bridge/direct-LAN; LAB-ONLY for Quick Connect — firmware review proved the K1 3.0.2 AP credential is firmware-constant and the SSID follows the `XGR-` identity/MAC rule. One prepared Mac completed AP-enable, AP-ready, CoreWLAN association and the normal control lifecycle. The successful host had been seeded from the reviewed firmware archive; a copied build on a clean host cannot acquire that material automatically. Automatic firmware download, iPhone extraction and hard-coding were rejected. Bridge remains the product path; Direct Connect remains physically pending |
|
||||
| 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 |
|
||||
|
||||
@@ -16,6 +16,35 @@ profile is not a generic XGRIDS protocol claim and must not be used for fuzzing.
|
||||
- The application sends operator-supplied router credentials; it does not derive
|
||||
them from the K1 and it does not require the password of the K1's own AP.
|
||||
|
||||
The 99-byte `7f01` profile is used when K1 joins an external network (Bridge or
|
||||
controller hotspot). It is not the Quick Connect bootstrap. A live Mission Core
|
||||
negative run on 2026-07-19 proved that host association alone cannot work while
|
||||
the reviewed K1 remains in station mode: `7f02` still reported the existing LAN.
|
||||
|
||||
Re-review of the owner-supplied LixelGO QuickLink branch then recovered the
|
||||
missing first step. After a real BLE connection, LixelGO sends one fixed
|
||||
100-byte frame to the same `7f01` characteristic: bytes `0..98` are zero and
|
||||
byte `99` is `0x01`. Its callback is the AP-launch result; only then does the
|
||||
application passes that device record's `WiFiAP_SSID` and `WiFiAP_Password` to
|
||||
the operating-system connector. Later analysis of the official K1 `3.0.2`
|
||||
firmware recovered the upstream source: `lixel_nman` invokes the bundled
|
||||
NetworkManager AP script, which assigns a firmware-constant WPA2 credential.
|
||||
The persisted app fields are per-device records, but the reviewed firmware
|
||||
material is not per-device. The reviewed app requests write-without-response.
|
||||
Mission Core follows the live characteristic properties on macOS, where this K1
|
||||
advertises write-with-response, and never retries either transport or command
|
||||
automatically.
|
||||
|
||||
The browser/API carries no AP password. An optional laboratory importer authenticates the
|
||||
exact official `3.0.2` archive, resolves the reviewed material without printing
|
||||
it and installs one firmware-scoped credential source in the OS secure store.
|
||||
Mission Core then binds a device-scoped host profile ID to the selected
|
||||
BLE-advertised SSID. Before any device write, the macOS helper materializes that
|
||||
profile entirely inside Keychain from the firmware-scoped source. The actual
|
||||
secret never reaches the browser, API, argv, logs, manifests or evidence. The
|
||||
bounded Python importer holds it only in a short-lived mutable buffer, sends it
|
||||
through helper stdin and zeroizes the buffer.
|
||||
|
||||
Full UUIDs:
|
||||
|
||||
- service: `00007f00-0000-1000-8000-00805f9b34fb`;
|
||||
@@ -38,6 +67,59 @@ There is no checksum, nonce, token, certificate, signature, or separate commit
|
||||
command in this production call path. The implementation must never print,
|
||||
persist, or accept the password as a command-line argument.
|
||||
|
||||
## Quick Connect AP-enable frame
|
||||
|
||||
The separately reviewed Quick Connect device action writes exactly 100 bytes:
|
||||
|
||||
| Offset | Length | Meaning |
|
||||
| --- | ---: | --- |
|
||||
| 0 | 99 | zero |
|
||||
| 99 | 1 | enable device AP (`0x01`) |
|
||||
|
||||
It contains no SSID, password, device identifier or user input. The reviewed
|
||||
client maps response byte 51 of `7f02` to its AP-ready flag. Mission Core
|
||||
therefore requires all three observations before host association: mode
|
||||
`WIFI_AP`, address `192.168.56.1`, and non-zero byte 51. A failed or ambiguous
|
||||
attempt is not automatically repeated.
|
||||
|
||||
The first controlled AP attempt was physically accepted: one write-with-response
|
||||
completed, `7f02` changed to `WIFI_AP / 192.168.56.1`, and a later exact
|
||||
CoreWLAN scan found the SSID matching the selected BLE device. The Mac remained
|
||||
on its previous LAN only because the former host adapter looked up an invalid
|
||||
global profile. That profile inference and its APK importer were withdrawn.
|
||||
|
||||
A later physical attempt established another boundary: `7f02` can continue to
|
||||
report `WIFI_AP / 192.168.56.1` with byte 51 zero after the exact SSID is no
|
||||
longer beaconing. Mode and address alone are therefore not an idempotency or
|
||||
readiness signal. Like the reviewed LixelGO action, each new explicit Mission
|
||||
Core Quick Connect intent emits one AP-enable frame even when the baseline mode
|
||||
already says `WIFI_AP`, then polls for the byte-51 ready flag for at most 15
|
||||
seconds. It never retries the device write automatically.
|
||||
|
||||
Static review of the original client also established a lifecycle requirement:
|
||||
LixelGO keeps the same BLE manager connected after AP-ready and invokes native
|
||||
Wi-Fi association from that live session. Mission Core now retains the same
|
||||
`BleakClient` while CoreWLAN performs bounded exact-SSID discovery and one
|
||||
association. The discovery window may contain multiple read-only scans; it does
|
||||
not repeat the BLE write or Wi-Fi association.
|
||||
|
||||
The next physical attempt exposed a CoreBluetooth lifecycle boundary before any
|
||||
write: K1 appeared in the explicit six-second BLE scan, but a second lookup by
|
||||
its macOS UUID failed moments later. The UUID is a transport-local selector, not
|
||||
a durable rediscovery contract. The runtime now retains the live `BLEDevice`
|
||||
handle from the operator's scan and connects that exact selected handle in the
|
||||
following network action. A fallback lookup remains only for non-UI callers
|
||||
that did not perform discovery first.
|
||||
|
||||
The 2026-07-20 prepared-host acceptance installed the exact firmware provider,
|
||||
found one expected K1 candidate, emitted one AP-enable write, observed AP-ready
|
||||
and completed one CoreWLAN association without an iPhone or manual credential.
|
||||
Mission Core admitted `192.168.56.1`; the operator disconnected afterward only
|
||||
to restore the external chat route. Full redacted evidence and artifact hashes
|
||||
are recorded in `docs/lab/004_K1_FW302_AP_CREDENTIAL_PROVIDER_20260720.redacted.md`.
|
||||
This proves the mechanism on that Mac, not automatic credential acquisition by
|
||||
a copied application on a clean host.
|
||||
|
||||
The Android application unequivocally requests a write without response and
|
||||
negotiates MTU 120, making the 99-byte frame one ATT command. A live read-only
|
||||
CoreBluetooth check reports MTU 256 and a maximum write-without-response size of
|
||||
@@ -53,11 +135,13 @@ mode. It never fragments or retries the payload automatically.
|
||||
## Expected transition and evidence of acceptance
|
||||
|
||||
A completed GATT write only proves transport completion. It does not prove that
|
||||
the K1 joined Wi-Fi. The application polls `7f02`; the observed response frame
|
||||
contains a fixed-width mode slot, an address slot, and a status byte at offset
|
||||
50. The current AP baseline reports mode `WIFI_AP` and address `192.168.56.1`.
|
||||
the K1 joined Wi-Fi or began beaconing. The application polls `7f02`; the
|
||||
observed response frame contains a fixed-width mode slot, an address slot, a
|
||||
status byte at offset 50 and the AP-ready flag at offset 51. The stale AP
|
||||
baseline reports `WIFI_AP / 192.168.56.1 / byte51=0`; the physically observed
|
||||
ready transition reports the same mode/address with `byte51=1`.
|
||||
|
||||
For the controlled experiment, acceptance required at least one of:
|
||||
For Bridge/Direct Connect, acceptance requires at least one of:
|
||||
|
||||
1. `7f02` reports a non-AP IPv4 address;
|
||||
2. the same address appears as a new router/ARP client after the write;
|
||||
@@ -66,10 +150,35 @@ For the controlled experiment, acceptance required at least one of:
|
||||
|
||||
Do not infer success from a write callback alone.
|
||||
|
||||
The Bridge/Direct Connect address is a DHCP lease, not configuration and not
|
||||
device identity. Mission Core re-reads `7f02` without writing before every new
|
||||
LAN control session, implicit-host acquisition and factory-calibration read.
|
||||
If the value changes, it rotates `device_session_id`; it never retargets an
|
||||
active acquisition. A correlated MQTT `DeviceInfo` response supplies the live
|
||||
model/firmware/serial identity barrier.
|
||||
|
||||
The 2026-07-20 reboot/power-cycle check observed the startup race directly:
|
||||
one read returned the earlier `.54` lease while that exact address had no ARP or
|
||||
application endpoint; a later read returned `.52`, where exact probes found
|
||||
MQTT 1883 and RTSP 8554. No subnet scan, route change, network-profile change or
|
||||
VPN action was used. This is why no owner-LAN IPv4 value is a product constant
|
||||
and why a BLE lease observation alone is not reported as live DeviceInfo.
|
||||
|
||||
For Quick Connect, host association is not admitted until the canonical
|
||||
byte-51 ready flag is observed. CoreWLAN then searches only for the exact
|
||||
device-profile SSID for at most 15 seconds and performs at most one association.
|
||||
|
||||
## Safety, recovery and stop conditions
|
||||
|
||||
- Perform one write per explicitly named attempt, using credentials for the LAN
|
||||
already used by the Mac. Never retry automatically.
|
||||
- Perform one write per explicitly named attempt. Never retry automatically.
|
||||
- For Bridge/Direct Connect, use credentials for the operator-selected network.
|
||||
- For Quick Connect, the exact `3.0.2` provider must already exist in the OS
|
||||
secure store. Missing or mismatched firmware material fails before the AP
|
||||
write. Never extrapolate this provider to another firmware or model.
|
||||
- The macOS adapter materializes a device-scoped Keychain item from the exact
|
||||
firmware source, then performs one association. Standard Wi-Fi Keychain and
|
||||
native prompt paths remain compatibility fallbacks, not the reviewed
|
||||
zero-touch path. It never asks the browser for a password.
|
||||
- Do not alter Deco settings, scan the subnet, or guess any credential.
|
||||
- If the status does not change, do not retry automatically.
|
||||
- If the supplied credentials are wrong, reconnect over BLE and overwrite them
|
||||
|
||||
@@ -15,6 +15,9 @@ fully usable with only their available modalities.
|
||||
1. Enter the required project name and start a normal acquisition from **Парк →
|
||||
Локальное устройство**. The NFKC-normalized/trimmed value is local display
|
||||
metadata, not a filesystem path, and becomes the saved-session catalog name.
|
||||
A normal acquisition has no duration deadline and runs until the operator
|
||||
explicitly stops it. Compatibility clients may still request a positive
|
||||
finite duration, without an application-level maximum.
|
||||
2. Open **Наблюдение → Пространственная сцена**. Live point cloud, trajectory
|
||||
and the selected camera remain live-only while acquisition is running.
|
||||
3. Stop acquisition normally, or allow the local service to recover an
|
||||
@@ -165,7 +168,8 @@ a separately attested storage root:
|
||||
export MISSIONCORE_DATA_DIR=/absolute/private/path/mission-core
|
||||
# Full K1 point-plus-camera evidence must currently remain below the checkout.
|
||||
export MISSIONCORE_EVIDENCE_DIR=/absolute/path/to/NODEDC_MISSION_CORE/.runtime/mission-core/evidence/sessions
|
||||
export MISSIONCORE_RRD_CACHE_MAX_BYTES=8589934592
|
||||
# Optional operator retention quota; unset means no application byte quota.
|
||||
# export MISSIONCORE_RRD_CACHE_MAX_BYTES=8589934592
|
||||
export MISSIONCORE_RRD_FREE_SPACE_RESERVE_BYTES=2147483648
|
||||
uv run k1link serve
|
||||
```
|
||||
@@ -226,13 +230,15 @@ keeps the current device scan generation and does not accumulate an earlier
|
||||
distance after the device resets scan time and route distance. These values are
|
||||
not reconstructed from pose integration or a browser timer.
|
||||
|
||||
Expensive cache misses run through the bounded preparation worker and one global
|
||||
cross-process export gate to cap peak RAM, CPU and temporary-disk use. Crash
|
||||
leftovers from candidates, exporter temporary files and staged replay prefixes
|
||||
are scavenged under that lock before quota accounting. Ready cache hits and
|
||||
active response leases do not wait behind that gate. The derived cache has an
|
||||
8 GiB default quota, preserves a 2 GiB default filesystem reserve and evicts
|
||||
least-recently-used RRDs only; it never deletes native evidence.
|
||||
Expensive cache misses run through the single-worker preparation queue and one
|
||||
global cross-process export gate to cap concurrent RAM, CPU and temporary-disk
|
||||
use. Crash leftovers from candidates, exporter temporary files and staged replay
|
||||
prefixes are scavenged under that lock before capacity accounting. Ready cache
|
||||
hits and active response leases do not wait behind that gate. The derived cache
|
||||
has no application byte quota by default, so a single multi-hour RRD is not
|
||||
rejected at 8 GiB. It still preserves a 2 GiB default filesystem reserve. An
|
||||
operator may set `MISSIONCORE_RRD_CACHE_MAX_BYTES` to enable LRU eviction of
|
||||
derived RRDs only; native evidence is never deleted.
|
||||
|
||||
## Capture-clock envelope
|
||||
|
||||
@@ -313,7 +319,9 @@ time are not proven to use a shared device clock. Do not infer frame-accurate
|
||||
calibration from the playback timeline.
|
||||
|
||||
Finalized media is prepared once by the same process-owned background job that
|
||||
materializes the RRD. The gateway records host time only after a complete
|
||||
materializes the RRD. JSONL indexes are read incrementally and no total index,
|
||||
segment-count or archive-byte ceiling is used. The gateway records host time
|
||||
only after a complete
|
||||
`moof+mdat` fragment has arrived, so that timestamp is an availability/end
|
||||
anchor, never a fragment-start timestamp. Preparation reads and SHA-verifies
|
||||
every fragment, parses bounded ISO-BMFF timing tables (`mdhd`, `trex`, `tfhd`,
|
||||
@@ -332,7 +340,7 @@ coverage can be navigated. A missing, ambiguous, oversized or otherwise
|
||||
unparseable timing table fails preparation; the archive remains evidence but is
|
||||
never advertised as seekable media.
|
||||
|
||||
The prepared path-free v2 descriptor and full source stat identity (native raw
|
||||
The durable path-free v2 descriptor and full source stat identity (native raw
|
||||
and timing metadata plus every camera summary, index, init and segment file) are
|
||||
written under the private derived cache with a schema, generation and checksum.
|
||||
Publication uses a private temporary file, file and directory `fsync`, and atomic
|
||||
@@ -379,8 +387,9 @@ camera acceptance run retained point/pose evidence only.
|
||||
provisional `transport` generation, but discovery will not use either to
|
||||
advertise camera coverage. A mismatched origin/envelope/summary fails closed.
|
||||
- A native capture with a missing final summary is accepted only when the raw
|
||||
and metadata prefix is bounded, aligned and structurally valid. It is cataloged
|
||||
as `interrupted`, never silently promoted to `ready`.
|
||||
and metadata prefix is aligned and structurally valid. Recovery streams the
|
||||
metadata JSONL one row at a time with no total-byte or message-count ceiling;
|
||||
it is cataloged as `interrupted`, never silently promoted to `ready`.
|
||||
- A non-newline metadata crash tail can be ignored. Newline-terminated or
|
||||
mid-file corruption fails closed.
|
||||
- Camera recovery retains a contiguous valid segment prefix, quarantines
|
||||
@@ -426,6 +435,7 @@ POST /api/v1/observation-sessions/{id}/blueprint.rrd
|
||||
GET /api/v1/observation-sessions/{id}/media/{artifact}/manifest
|
||||
GET /api/v1/observation-sessions/{id}/media/{artifact}/epochs/{n}/init.mp4
|
||||
GET /api/v1/observation-sessions/{id}/media/{artifact}/epochs/{n}/segments/{m}.m4s
|
||||
GET /api/v1/observation-sessions/{id}/media/{artifact}/epochs/{n}/recording.mp4?generation=<sha256>
|
||||
|
||||
GET /api/v1/workspace-layouts/observation.spatial
|
||||
PUT /api/v1/workspace-layouts/observation.spatial
|
||||
@@ -461,40 +471,40 @@ revision in `If-Match`; stale writers receive HTTP 412 rather than overwriting
|
||||
another saved profile.
|
||||
|
||||
Recorded media routes expose only opaque catalog identifiers and ordinal codec
|
||||
epochs. The required `missioncore.observation-recorded-media/v2` manifest carries
|
||||
a strong `generation_sha256`, exact JS-safe aggregate `byte_length`, and finite
|
||||
epochs. The public compact
|
||||
`missioncore.observation-recorded-media/v3` manifest carries a strong
|
||||
`generation_sha256`, exact JS-safe aggregate `byte_length`, and finite
|
||||
`timeline_start_seconds` / `timeline_end_seconds` for every epoch. Epoch ends
|
||||
participate in the generation digest. Every epoch also declares its init byte
|
||||
length/digest and a complete contiguous segment list with sequence, URL, byte
|
||||
length and digest. The launch source repeats the same aggregate `byte_length`
|
||||
and uses exactly `max(epoch.timeline_end_seconds)` as its end; the spatial RRD
|
||||
end must never pad camera coverage. The browser cross-checks launch, manifest and
|
||||
component lengths. The current browser laboratory policy accepts at most 16
|
||||
camera sources, 128 MiB per source and 512 MiB across the session. This launch
|
||||
preflight finishes before the first camera manifest/init/segment GET; admitted
|
||||
cameras are then downloaded and decode-probed one at a time. Verified raw
|
||||
buffers remain immutable so route changes and player remounts cannot append
|
||||
emptied data. This bounded in-memory strategy is deliberate for the laboratory
|
||||
milestone; an OPFS-backed sealed-generation cache is the next scaling step for
|
||||
larger rigs and must preserve the same launch/manifest/hash admission contract.
|
||||
participate in the generation digest. Each epoch declares one generation-bound
|
||||
`stream_url`, media type and aggregate byte length; thousands of internal
|
||||
segment rows never enter browser memory. The launch source repeats the same
|
||||
aggregate `byte_length` and uses exactly `max(epoch.timeline_end_seconds)` as
|
||||
its end; the spatial RRD end must never pad camera coverage. The browser
|
||||
cross-checks launch and manifest identity, but applies no duration, per-source
|
||||
byte or aggregate-session byte admission ceiling.
|
||||
|
||||
The manifest response ETag is the exact generation, and the manifest GET itself
|
||||
requires that generation in `If-Match`. Init and media GETs likewise require the
|
||||
descriptor's exact SHA `If-Match`, then open through a confined directory file
|
||||
descriptor with no symlink following, verify the declared SHA-256 and serve
|
||||
exact-length bytes with immutable private `no-transform` caching and byte-range
|
||||
support. Physical source ids, RTSP addresses and storage paths never cross the
|
||||
API boundary.
|
||||
The `<video>` element reads the immutable virtual fMP4 through native HTTP Range
|
||||
requests. The server maps each requested interval onto init/segment files,
|
||||
opens them through confined descriptors with no symlink following and verifies
|
||||
the digest of each touched component. It never assembles the full video in
|
||||
backend or JavaScript memory. Responses carry exact `Content-Length` /
|
||||
`Content-Range`, a generation-and-epoch ETag, `Accept-Ranges: bytes` and private
|
||||
immutable `no-transform` caching. The manifest ETag is the exact generation and
|
||||
its GET requires the matching `If-Match`; the stream URL binds that same
|
||||
generation in its query. The older init/segment routes remain internal
|
||||
compatibility surfaces. Physical source ids, RTSP addresses and storage paths
|
||||
never cross the API boundary.
|
||||
|
||||
## Current limit
|
||||
## Current synchronization boundary
|
||||
|
||||
The spatial RRD, trajectory, archived device-metric series and archived fMP4
|
||||
cameras use the same operator scrubber now. Camera epochs are aligned to
|
||||
zero-based `session_time` from the shared host-arrival monotonic clock and
|
||||
rendered through MSE. The metric tab carries device-reported route distance,
|
||||
rendered through the browser's native fMP4/Range pipeline. The metric tab carries
|
||||
device-reported route distance,
|
||||
speed and scan time at their `ModelingReport` receive times. The client selects
|
||||
a camera epoch only inside its declared inclusive interval and verifies that the
|
||||
decoded MSE seekable duration covers that interval. This remains best-effort
|
||||
decoded native-media seekable duration covers that interval. This remains best-effort
|
||||
correlation: codec PTS, K1 sensor exposure time and LiDAR firing time are not
|
||||
proven to share a device clock. A codec epoch whose init segment does not expose
|
||||
a browser-supported codec or whose timing cannot be proven remains retained
|
||||
|
||||
@@ -61,6 +61,306 @@ The result manifest binds the detection artifact's length and SHA-256. A repeat
|
||||
with the same identity validates the existing directory and returns it without
|
||||
calling Triton.
|
||||
|
||||
## Full-epoch panoptic result v2
|
||||
|
||||
`missioncore.recorded-perception-result/v2` is the complete recorded-camera
|
||||
profile. It is separate from the YOLOX detector proof and processes every
|
||||
admitted frame without sampling. Its immutable identity binds the complete
|
||||
compute job, factory-calibration generation and camera slot, exact model
|
||||
revisions/weight files, thresholds, alpha values, runner SHA-256 and publication
|
||||
encoder.
|
||||
|
||||
The current research configuration produces:
|
||||
|
||||
- TorchVision Mask R-CNN ResNet50-FPN v2 instance masks and COCO labels;
|
||||
- Microsoft BEiT ADE20K-150 semantic masks at the original 800x600 frame size;
|
||||
- a seekable H.264 MP4 with the two overlays combined for operator playback;
|
||||
- lossless instance and semantic mask PNGs for later calibrated fusion;
|
||||
- ordered per-frame JSONL and one-second GPU telemetry;
|
||||
- a machine-readable run report with input/config/model identities, decode,
|
||||
inference, encode and end-to-end timing, latency percentiles, throughput,
|
||||
CUDA peak allocation/reservation, process peak RSS, system load and GPU
|
||||
utilization/VRAM/temperature/power samples.
|
||||
|
||||
The worker runs with `--network none` and cached model weights. A preflight
|
||||
revalidates the complete transferred payload, CUDA execution and both cached
|
||||
model generations before decoding a long epoch. The run then repeats payload
|
||||
validation inside the inference container, requires exactly the declared frame
|
||||
count and a strictly increasing session-time row for every frame, and publishes
|
||||
only by atomic rename after every output digest is sealed.
|
||||
|
||||
There is no recorded-duration, frame-count or aggregate-video-byte admission
|
||||
ceiling in this profile. Resource use therefore scales with the real input and
|
||||
is reported, not hidden behind an arbitrary eight-minute laboratory limit.
|
||||
|
||||
## Native panoptic playback
|
||||
|
||||
Full raster masks are not copied into the RRD. That would turn a long video into
|
||||
a multi-gigabyte browser-memory object. Instead Mission Core validates the v2
|
||||
result and exposes its MP4 through the same generation-bound, seekable HTTP
|
||||
Range contract as a recorded camera. Replay advertises an additional opaque
|
||||
source such as `recorded.perception.right`; the Control Station opens it in a
|
||||
native video window on the shared `session_time` timeline. A one-, three- or
|
||||
ten-hour video remains disk/range streamed and does not have to fit in RAM.
|
||||
|
||||
The lossless masks remain private derived evidence. A host-side calibrated
|
||||
fusion step samples them at K1 KB4 LiDAR projections and publishes compact
|
||||
semantic `Points3D`, support-gated `Boxes3D` and diagnostic distances as a
|
||||
separate replaceable generation. Missing or rejected v2/fusion results never
|
||||
replace or invalidate the base raw point-cloud recording.
|
||||
|
||||
## RAVNOVES00 qualification · 2026-07-20
|
||||
|
||||
The first full recorded run admitted all 4,489 frames from
|
||||
`sensor.camera.right` without sampling, failures or skips. The sealed input was
|
||||
363,235,615 bytes over `35.421857292–484.144857292` session seconds. Its
|
||||
immutable result is
|
||||
`result-f4cebdea8a82698a5b8a65d2c3fbdb0428b88b9dc49fe45f8cb37d740ed83d02`.
|
||||
|
||||
Measured RTX 4090 worker results:
|
||||
|
||||
- inference: 2,674.722 s and 1.678 frames/s;
|
||||
- end to end: 2,816.349 s and 1.594 frames/s;
|
||||
- instance latency: 89.826 ms p50, 121.344 ms p95, 915.325 ms max;
|
||||
- semantic latency: 249.678 ms p50, 284.826 ms p95, 406.594 ms max;
|
||||
- GPU utilization: 67% p50, 82% p95, 90% max over 2,675 one-second samples;
|
||||
- process CUDA peak: 2,230.8 MiB allocated and 2,872 MiB reserved;
|
||||
- total GPU memory observed, including the worker's shared resident services:
|
||||
13,373 MiB p50 and 13,388 MiB max;
|
||||
- GPU power/temperature: 182.46 W p50, 190.10 W p95 and 49 C p50, 54 C max;
|
||||
- process peak RSS: 2,375.9 MiB;
|
||||
- publication: 31.229 s decode, 3.397 s NVENC, 81,109,627-byte H.264 MP4,
|
||||
60,326,719-byte lossless mask archive.
|
||||
|
||||
The factory-calibrated full fusion generation
|
||||
`fusion-0b1be23128ebd3d230562cffd96491169e99f0e839e56b812661c974e4fdc00b`
|
||||
matched LiDAR and pose within the admitted 250 ms host-arrival window for 4,323
|
||||
frames and declared 166 frames `depth-unavailable`. It produced 6,124,145
|
||||
semantic points and 13,496 support-gated diagnostic boxes in 77.708 s. The
|
||||
compact fusion payload is 43 MiB.
|
||||
|
||||
Native browser QA opened `RAVNOVES00`, played the raw and panoptic 800x600
|
||||
videos together at ready-state 4, and measured approximately 12 ms between
|
||||
their media clocks. The Rerun scene showed the synchronized semantic points and
|
||||
distance-labeled diagnostic boxes. The current baseline is deliberately not an
|
||||
accuracy or safety acceptance: generic perspective-trained models produce
|
||||
large fisheye false positives in 916 frames, and timing/distance have not been
|
||||
ground-truthed. The next A/B should compare an admitted undistort/ROI transform
|
||||
before inference rather than silently hiding these observations.
|
||||
|
||||
## E1 valid-FOV preprocessing qualification · 2026-07-20
|
||||
|
||||
The first post-baseline A/B uses two immutable inputs derived from the same
|
||||
RAVNOVES00 job and factory calibration:
|
||||
|
||||
- valid-FOV generation
|
||||
`valid-fov-mask-b4dd8ddf2b87c1d520ee8a0868c4fea062d7c14d1bae73ccabd3abe1f3acbac2`;
|
||||
- qualification-slice generation
|
||||
`qualification-slice-2394070b4f3e38f1b8c483e878fcc11fd3c29f751f3d4cd7e3a2553304c5c142`.
|
||||
|
||||
The mask is not estimated from each image. It is bound to the exact calibration
|
||||
SHA, `sensor.camera.right`, `camera_1`, the admitted 800x600 linear-resize
|
||||
profile and the KB4 principal point `(396.319, 301.496)`. A four-pixel inner
|
||||
margin produces a 293.504-pixel radius, 270,606 valid pixels (56.37625%) and an
|
||||
exclusive crop rectangle `[103, 8, 690, 595]`. Repeated preparation reuses the
|
||||
same content-addressed PNG and manifest.
|
||||
|
||||
The slice selects 256 exact frame indices uniformly across all 4,489 frames,
|
||||
including both endpoints. The same loaded FP32 Mask R-CNN and BEiT generations
|
||||
were interleaved per frame across three variants: unmodified baseline, fixed
|
||||
valid-FOV fill, and valid-FOV crop remapped into the original pixel coordinates.
|
||||
The sealed result is
|
||||
`qualification-result-98a2fee3d22979f3e18847719667cc76bdeacf25904c0fd1da4c5202253b3940`.
|
||||
|
||||
The run completed in 318.969 s and emitted 12 preview frames per variant. GPU
|
||||
telemetry recorded 319 one-second samples: utilization was 74% p50 and 82% p95,
|
||||
power was 199.34 W p50 and 206.96 W p95, and temperature was 50 C p50 and 55 C
|
||||
max. The qualification process peaked at 1,849.9 MiB CUDA allocated, 2,256 MiB
|
||||
reserved and 2,298.2 MiB RSS.
|
||||
|
||||
Measured mean model paths, excluding the frame decode shared by all variants:
|
||||
|
||||
| Variant | Mask R-CNN path | BEiT path | Combined |
|
||||
|---|---:|---:|---:|
|
||||
| baseline | 106.292 ms | 278.064 ms | 384.356 ms |
|
||||
| valid-FOV fill | 107.027 ms | 280.762 ms | 387.789 ms |
|
||||
| valid-FOV crop | 104.055 ms | 282.840 ms | 386.895 ms |
|
||||
|
||||
The crop reduced Mask R-CNN forward time by 6.38%, but BEiT still receives its
|
||||
fixed 640x640 tensor and became 1.18% slower. With mask/crop preprocessing
|
||||
included, neither variant improved the combined path; fill was 0.89% slower and
|
||||
crop was 0.66% slower than baseline. A binary mask improves admission quality,
|
||||
but multiplying an unchanged tensor by it does not remove dense neural FLOPs.
|
||||
|
||||
The quality proxies are useful but are not ground truth. Baseline produced 58
|
||||
instance masks and 58 boxes larger than half the admitted comparison area; both
|
||||
masked variants produced zero. The fraction of raw predicted instance-mask
|
||||
pixels outside the canonical FOV fell from 41.263% to 0.077% for fill and 0.911%
|
||||
for crop before the final output clamp. Inside the valid circle, mean BEiT
|
||||
disagreement with baseline was 8.713% for fill and 11.547% for crop. This is a
|
||||
measure of change, not accuracy.
|
||||
|
||||
E1 therefore accepts the immutable valid-FOV artifact and the 256-frame gate.
|
||||
Fixed fill is the conservative next accuracy baseline because it preserves the
|
||||
800x600 geometry, removes the exterior lens region and changes the semantic
|
||||
result less than crop. Crop remains an experimental model-specific option, not
|
||||
a general speed optimization. The next run needs human labels/ground truth and
|
||||
must compare native KB4 input, calibrated virtual views and fisheye-trained
|
||||
models before promoting any preprocessing profile to a full-epoch result.
|
||||
|
||||
## E2 evaluation pack and annotation gate · 2026-07-20
|
||||
|
||||
LAB E2 starts from the same immutable RAVNOVES00 compute job, E1 qualification
|
||||
slice and factory-calibrated valid-FOV generation. All eight contact sheets,
|
||||
covering the 256 uniformly distributed E1 candidates, were reviewed before
|
||||
selection. The sealed evaluation generation is
|
||||
`evaluation-pack-7a983bba75d46c7c260252cb2d461e1384dcb92cda9e164397e841e6ebb37789`.
|
||||
|
||||
The pack contains 64 exact 800x600 images: 48 reviewed full-epoch anchors from
|
||||
the E1 slice and four four-frame consecutive clips for temporal measurements.
|
||||
The clips cover a person with a stroller, a close moving car, vehicle
|
||||
occlusion/relative motion and a near building/terrace scene with a partially
|
||||
visible carried laptop. The anchors retain the recording's road, sidewalk,
|
||||
ground, grass, woody vegetation, buildings, sky, people, cars, trucks, lens
|
||||
boundary and hard-negative diversity.
|
||||
|
||||
Every image is stored both as the raw decoded RGB frame and as the accepted E1
|
||||
fixed-valid-FOV-fill input. The identity binds the job/input SHA, source, codec
|
||||
epoch, selected segment SHA, decoded session timestamp, E1 qualification,
|
||||
valid-FOV generation, calibration SHA, camera slot, FFmpeg 7.1.1 generation and
|
||||
the raw/fill RGB pixel hashes. It also binds the reviewed selection-document
|
||||
SHA and both producer-code hashes. The pack has 130 hashed payload artifacts
|
||||
plus its manifest and occupies approximately 67 MiB locally.
|
||||
|
||||
One earlier local preparation generation, `evaluation-pack-b6d9215a…`, was not
|
||||
promoted because its identity omitted the producer-code and selection-document
|
||||
hashes. It remains a superseded diagnostic artifact and is not an accepted E2
|
||||
input.
|
||||
|
||||
The immutable pack is deliberately `unannotated`. Its annotation contract
|
||||
defines 15 robotics-oriented thing/stuff classes, label 0 for the excluded lens
|
||||
exterior, label 255 for genuinely unresolved pixels, two-pass human review and
|
||||
required semantic, instance, safety-proxy and temporal metrics. The empty
|
||||
annotation template must be copied to a review workspace; it must never be
|
||||
edited inside the sealed pack. Model-generated prelabels may accelerate review
|
||||
but are not accepted as ground truth without a human pass.
|
||||
|
||||
No AP, mIoU or model-ranking claim is attached to E2 yet. The next gate is to
|
||||
complete and seal the reviewed annotations. Only then may candidate models be
|
||||
ranked on this pack; a full 4,489-frame run remains prohibited until one
|
||||
configuration passes both the accuracy and throughput gates.
|
||||
|
||||
The first model-assisted draft is sealed separately as
|
||||
`evaluation-prelabels-4ba26bbf6eb8a49631f5caf984267e0445958540aeda2b5b0d82ca6440835cf1`.
|
||||
It reuses the exact E0 Mask R-CNN and BEiT weights and maps their COCO/ADE
|
||||
classes into the E2 taxonomy. It is explicitly marked
|
||||
`unreviewed-model-draft`; it never mutates the evaluation pack or annotation
|
||||
template.
|
||||
|
||||
The isolated RTX 4090 run processed 64/64 frames in 31.551 s. Mean forward time
|
||||
was 57.539 ms for Mask R-CNN, 215.164 ms for BEiT and 272.703 ms combined. The
|
||||
process peaked at 1,842.8 MiB CUDA allocated, 2,768 MiB reserved and 2,239.9 MiB
|
||||
RSS. Across 32 one-second samples, GPU utilization was 51% p50 / 71% p95, power
|
||||
167.73 W p50 / 186.89 W p95 and temperature 42 C p50 / 47 C max. Shared Triton,
|
||||
Frigate and Ollama services remained running and healthy.
|
||||
|
||||
The draft emitted 775 mapped instances: 640 car, 58 static obstacle, 45 person,
|
||||
25 heavy vehicle, five bicycle and one each motorcycle/animal. Sixteen previews
|
||||
were reviewed. They confirm that the fixed-FOV exterior stays clean and that
|
||||
the draft is useful for annotation assistance, but also expose the expected E0
|
||||
domain errors: duplicated/distant car boxes, unstable small instances, coarse
|
||||
fisheye boundaries and excessive static-obstacle proposals on planters. These
|
||||
counts are workload indicators for review, not precision or recall.
|
||||
|
||||
The first prelabel attempt stopped before model loading because the container
|
||||
mountpoint `/evaluation-pack` was incorrectly required to equal the
|
||||
content-addressed generation basename. The path-name check was removed while
|
||||
all manifest, artifact and identity hashes remained mandatory. No failed result
|
||||
was published; the second attempt completed and 147 payload artifacts were
|
||||
reverified locally with zero digest/length mismatches.
|
||||
|
||||
The review handoff is sealed separately as
|
||||
`annotation-workspace-9a950d1c37d56dc12cc285b13c5addd7795285879cbcb1fbb2d5811c3c69821a`.
|
||||
It contains a deterministic 64-image upload, a 775-instance COCO RLE draft, a
|
||||
dense CVAT Segmentation Mask archive, an exact frame/timestamp map, the fixed
|
||||
valid-FOV mask, the 15-class label specification and an unreviewed two-pass
|
||||
checklist. The three ZIP archives passed both the workspace validator and
|
||||
independent ZIP integrity checks. The 11 payload artifacts occupy 31,861,798
|
||||
bytes. This workspace remains `ground_truth=false`; the two synchronized CVAT
|
||||
tasks must be reviewed and their accepted exports sealed as a separate
|
||||
generation before any AP or mIoU claim is allowed.
|
||||
|
||||
The real prelabel generation also exposed one identity-serialization defect in
|
||||
its producer: `target_categories` used integer dictionary keys while hashing,
|
||||
but JSON reloads them as strings and changes their sorted order. The stored
|
||||
artifact files and all 147 recorded payload hashes are unchanged. The workspace
|
||||
validator admits only this exact reversible legacy representation and binds the
|
||||
serialized `result.json` SHA separately. The worker producer now emits string
|
||||
keys before hashing, so subsequent prelabel identities are stable across a JSON
|
||||
round trip. The existing result was neither rewritten nor renamed.
|
||||
|
||||
Prepare or reproduce the review inputs with:
|
||||
|
||||
```console
|
||||
.venv/bin/python experiments/perception/prepare_e2_evaluation_pack.py candidates \
|
||||
--job-root .runtime/compute-jobs/<job-id> \
|
||||
--qualification-root .runtime/compute-experiments/e1/qualification-slices/<generation> \
|
||||
--output-root .runtime/compute-experiments/e2/<candidate-review>
|
||||
|
||||
.venv/bin/python experiments/perception/prepare_e2_evaluation_pack.py seal \
|
||||
--job-root .runtime/compute-jobs/<job-id> \
|
||||
--qualification-root .runtime/compute-experiments/e1/qualification-slices/<generation> \
|
||||
--valid-fov-root .runtime/compute-experiments/e1/valid-fov/<generation> \
|
||||
--selection .runtime/compute-experiments/e2/selection-e2.json \
|
||||
--output-root .runtime/compute-experiments/e2/evaluation-packs
|
||||
|
||||
.venv/bin/python experiments/perception/prepare_e2_annotation_workspace.py prepare \
|
||||
--evaluation-pack .runtime/compute-experiments/e2/evaluation-packs/<generation> \
|
||||
--prelabels .runtime/compute-experiments/e2/prelabels/<generation> \
|
||||
--valid-fov-root .runtime/compute-experiments/e1/valid-fov/<generation> \
|
||||
--output-root .runtime/compute-experiments/e2/annotation-workspaces
|
||||
```
|
||||
|
||||
## E4 full-session semantic playback · 2026-07-21
|
||||
|
||||
LAB E4 promotes the plain EoMT valid-FOV control from LAB E3 into the first
|
||||
complete saved-session semantic playback. It consumed all 4,489 frames of
|
||||
RAVNOVES00 (`20260720T065719Z_viewer_live`) from
|
||||
`sensor.camera.right`, using factory calibration slot `camera_1`, FP16
|
||||
autocast, batch size one and no sampling. CLAHE, five-view rectification and the
|
||||
instance branch were deliberately disabled.
|
||||
|
||||
The immutable published result is
|
||||
`result-793785170472c519486ccd666be102fb04d169d92383acda3fcc29eecf045d30`.
|
||||
It contains an 800x600 H.264 semantic-overlay video, 4,489 semantic masks,
|
||||
4,489 timestamp rows, one-second GPU telemetry and a run report. FFprobe and the
|
||||
recorded-perception validator independently confirmed the exact frame count,
|
||||
448.723-second timeline, artifact hashes and input/job/calibration binding.
|
||||
|
||||
The inference loop ran for 1,447.565 seconds at 3.101 FPS. Full extraction,
|
||||
inference, publication, hashing and validation took 1,668.259 seconds at 2.691
|
||||
FPS. GPU utilization was 73.05% mean / 89% p95, E4 process CUDA allocation
|
||||
peaked at 2,099.8 MiB, process RSS at 2,009.3 MiB, power at 253.23 W and
|
||||
temperature at 58 C. The exact configuration is about 3.72 times slower than
|
||||
the source recording rate and is therefore an offline baseline, not a live
|
||||
configuration.
|
||||
|
||||
All task-controlled worker paths remained under `D:\NDC_MISSIONCORE`. The
|
||||
orchestrator enforced a 360 GiB free-space floor and a 17.195 GiB conservative
|
||||
working-set reserve. Final free space after exact task-temporary cleanup was
|
||||
379.395 GiB; C: was not used or mounted by the task.
|
||||
|
||||
Mission Core exposes the result in **Сохранённые сессии → RAVNOVES00 →
|
||||
Источники данных сцены → Сегментация · камера right**. Browser acceptance
|
||||
confirmed the exact result source, 800x600 dimensions, full duration, no media
|
||||
error and advancing playback time. The detailed configuration, timing tables,
|
||||
artifact hashes, disk checkpoints, limitations and next gates are recorded in
|
||||
`experiments/perception/LAB_E4_REPORT_2026-07-21.md` and Ops card MISSIONCOR-18.
|
||||
|
||||
E4 remains `ground_truth=false` and semantic-only. It makes no claim about live
|
||||
latency, instances, tracking, 3D cuboids, LiDAR association, distance accuracy,
|
||||
point-cloud labels or safety fitness.
|
||||
|
||||
## Recorded Rerun projection
|
||||
|
||||
Mission Core discovers only results whose validated job names the opened
|
||||
@@ -105,3 +405,84 @@ accepted for obstacle avoidance, free-space estimation or safety decisions.
|
||||
tests.
|
||||
4. Introduce tracking, segmentation/free-space, calibration and point-cloud
|
||||
models as separate versioned pipelines.
|
||||
|
||||
## E5 recorded instance tracking qualification · 2026-07-21
|
||||
|
||||
LAB E5 establishes the first measured temporal object-identity baseline on a
|
||||
preselected 601-frame, 60.069-second RAVNOVES00 interval. It uses the official
|
||||
Apache-2.0 YOLOX-S ONNX release through the existing Triton service, the
|
||||
immutable `camera_1`-bound valid-FOV mask, and a ByteTrack-style two-stage IoU
|
||||
tracker. The accepted profile, runner, model and configuration are pinned by
|
||||
SHA-256; output remains `ground_truth=false` and qualification-only.
|
||||
|
||||
The immutable result is
|
||||
`e5-tracking-88aace13ef9963f8dc07f85228e530f9d28c2b49aca9192409f7975512b058f6`.
|
||||
It contains an 800x600 H.264 ID-overlay video, exactly 601 timestamped detection
|
||||
and track rows, one-second GPU telemetry, a contact sheet and the complete run
|
||||
report. The result validator rehashed all artifacts and verified the exact job,
|
||||
input, session, source, clip and timeline binding. FFprobe independently
|
||||
confirmed 601 declared/read frames and 60.068948 seconds.
|
||||
|
||||
The frame loop ran for 88.093 seconds at 6.822 FPS; the complete worker run took
|
||||
166.336 seconds at 3.613 FPS. Mean per-frame time was 12.359 ms in Triton,
|
||||
0.247 ms in tracking, 30.132 ms decoding and 87.363 ms writing overlays. The
|
||||
detector and tracker are therefore not the main live-rate bottleneck; artifact
|
||||
I/O must be decoupled before a live path is admitted. GPU utilization was
|
||||
51.65% mean / 56% max, power 144.78 W mean / 148.40 W max, temperature 43 C max
|
||||
and process RSS 126.199 MiB.
|
||||
|
||||
The run admitted 4,049 detections and emitted 3,320 observations across 167
|
||||
confirmed IDs. Useful clear-view persistence is proven, including vehicle
|
||||
tracks lasting 100–212 frames. The result also exposes real limitations: an ID
|
||||
fragments during the close woman/stroller occlusion, the stroller can be called
|
||||
`motorcycle`, and parked vehicles can flicker between `car` and `truck`. There
|
||||
is no identity ground truth, so IDF1, HOTA, MOTA and true ID-switch counts are
|
||||
not claimed.
|
||||
|
||||
All task-controlled worker paths remained under `D:\NDC_MISSIONCORE`; the
|
||||
orchestrator enforced the 360 GiB floor and a 4.402 GiB working-set reserve.
|
||||
Free space after exact temporary cleanup was 380.595 GiB. The YOLOX model was
|
||||
loaded only for the run and restored to its prior unloaded state. Detailed
|
||||
provenance, pilot history, thresholds, timing tables, artifacts, hashes,
|
||||
quality findings and the LAB E6 gate are in
|
||||
`experiments/perception/LAB_E5_REPORT_2026-07-21.md` and Ops card
|
||||
MISSIONCOR-19.
|
||||
|
||||
The next bounded gate is calibrated 2D-track/LiDAR association on the same
|
||||
601-frame interval: robust point support, metric range, coarse 3D cuboids and a
|
||||
qualification-only Rerun recording. Full-session and live promotion remain
|
||||
blocked on measured identity quality and a bounded queue/drop design.
|
||||
|
||||
## E6 factory-calibrated tracked LiDAR fusion · 2026-07-21
|
||||
|
||||
LAB E6 closes the recorded 2D-track/LiDAR association gate on the exact E5
|
||||
601-frame interval. It reuses the immutable E4 semantic masks, E5 track IDs,
|
||||
raw K1 point/pose capture and the XGRIDS `camera_1` factory KB4 calibration.
|
||||
Fused observations must satisfy 100 ms camera/point and pose/point gates.
|
||||
Nearest-depth buffering, semantic support, depth splitting, 3D connected
|
||||
components, robust range history and plausible-size gates prevent unsupported
|
||||
image rectangles from becoming fabricated 3D boxes.
|
||||
|
||||
The immutable result is
|
||||
`e6-fusion-b4e4226674a66f6196c033785eb307c255a7bdd8493ef9809dfb1d6e5bd68eaa`.
|
||||
It processed 601/601 frames, fused 526, emitted 918 point-supported oriented
|
||||
cuboids across 56 track IDs and failed closed for depth on 75 frames outside
|
||||
the strict timing gate. LiDAR/camera absolute delta was 29.389 ms mean,
|
||||
70.794 ms p95 and 96.107 ms maximum. Accepted range spans 1.239–37.749 m with a
|
||||
10.189 m median.
|
||||
|
||||
The single-process local geometry/artifact path took 14.774 seconds, peaked at
|
||||
240.469 MiB RSS and is faster than the source rate. This is not an end-to-end
|
||||
live result because E4 and E5 were precomputed. The external worker and both
|
||||
worker disks were untouched. The output includes an 800x600 H.264 overlay,
|
||||
timestamped JSONL/NPZ data, a contact sheet and a standalone 60 MiB Rerun
|
||||
recording with camera, map-frame cloud, support points and translucent
|
||||
`Boxes3D`. Visual QA confirmed that these are real oriented Rerun primitives;
|
||||
they remain visible-surface envelopes, not ground-truthed complete object
|
||||
volumes.
|
||||
|
||||
Detailed provenance, profile freeze, pilot failures, thresholds, timing,
|
||||
rejection counts, artifact hashes, limitations and the LAB E7 gate are in
|
||||
`experiments/perception/LAB_E6_REPORT_2026-07-21.md`. Ops synchronization is
|
||||
pending restoration of the direct `nodedc-ops-agent` tasker tools; the legacy
|
||||
Ops API was not used.
|
||||
|
||||
@@ -0,0 +1,453 @@
|
||||
# K1 calibrated perception roadmap
|
||||
|
||||
Status date: 2026-07-20.
|
||||
|
||||
## Outcome
|
||||
|
||||
Mission Core will use the K1 factory camera/LiDAR calibration instead of
|
||||
building a new calibration workflow for the assembled rig. The first product
|
||||
vertical is recorded, deterministic and fail-closed:
|
||||
|
||||
```text
|
||||
canonical camera epoch + canonical LiDAR epoch
|
||||
+ device-bound factory calibration snapshot
|
||||
+ versioned segmentation/detection result
|
||||
-> pixel masks
|
||||
-> labeled LiDAR points and object distances
|
||||
-> evidence-backed 3D boxes
|
||||
-> optional derived Rerun layer
|
||||
```
|
||||
|
||||
Only after this vertical passes on `RAVNOVES00` does the same contract move to
|
||||
bounded live processing. Rerun remains the viewer and recording projection;
|
||||
inference, calibration validation and fusion remain Mission Core concerns.
|
||||
|
||||
## Facts already established
|
||||
|
||||
### Camera identity is already canonical
|
||||
|
||||
The K1 plugin does not need to infer left versus right from image content. It
|
||||
owns the exact RTSP selection:
|
||||
|
||||
| Mission Core source | K1 RTSP endpoint |
|
||||
|---|---|
|
||||
| `sensor.camera.left` | `/live/chn_left_main` |
|
||||
| `sensor.camera.right` | `/live/chn_right_main` |
|
||||
|
||||
The selected source ID is retained by the camera gateway, the durable archive
|
||||
summary and `missioncore.compute-job/v1`. A source switch creates another codec
|
||||
epoch rather than silently changing the meaning of an existing epoch.
|
||||
|
||||
The accepted session `20260720T065719Z_viewer_live`, displayed as
|
||||
`RAVNOVES00`, contains one recorded video source:
|
||||
|
||||
```text
|
||||
source_id: sensor.camera.right
|
||||
codec_epoch: 1
|
||||
decoded video: H.264, 800x600
|
||||
```
|
||||
|
||||
Consequently camera selection for perception must be a lookup from the job's
|
||||
canonical `source_id`, never a UI default and never a computer-vision guess.
|
||||
|
||||
### Factory calibration exists and is used by K1
|
||||
|
||||
Read-only firmware analysis of K1 firmware `3.0.2` established:
|
||||
|
||||
- factory camera parameters are read from
|
||||
`/mnt/system/factory-data/config/camera.yaml`;
|
||||
- camera/LiDAR extrinsics are read from
|
||||
`/mnt/system/factory-data/config/extrinsic_camera_lidar.yaml`;
|
||||
- the internal frontend consumes camera intrinsics, distortion and
|
||||
`T_rgb_lidar`;
|
||||
- `libxcolor` consumes the calibration and produces the colorized point cloud;
|
||||
- K1 enables PTP, synchronized left/right main cameras and real-time xcolor;
|
||||
- the main camera calibration model is KB4 fisheye at `4000x3000`;
|
||||
- the exposed file protocol has a distinct read action, `CacFileRead = 5`, and
|
||||
a distinct write action, `CacFileWrite = 6`.
|
||||
|
||||
The OTA image contains model defaults. The exact values for one physical K1
|
||||
live in that unit's `factory-data`; Mission Core must snapshot those exact
|
||||
files before it claims calibrated fusion.
|
||||
|
||||
### Geometric calibration is now normalized; timing remains separate
|
||||
|
||||
The physical A4/FW 3.0.2 unit was read on 2026-07-20. Firmware declarations,
|
||||
the xcolor loader and the unit's exact native resolutions jointly establish:
|
||||
|
||||
| Mission Core source | firmware camera | factory slot | native | admitted |
|
||||
|---|---|---|---:|---:|
|
||||
| `sensor.camera.left` | `camera_left_main` | `camera_0` | 4000x3000 | 800x600 |
|
||||
| `sensor.camera.right` | `camera_right_main` | `camera_1` | 4000x3000 | 800x600 |
|
||||
|
||||
`camera_2` and `camera_3` are the 1280x800 left/right secondary pair and are
|
||||
not silently substituted for a main RTSP source. The main H.264 substream is a
|
||||
firmware-configured 800x600 linear resize with scale `(0.2, 0.2)` and no crop or
|
||||
warp stage in the admitted profile. KB4 distortion is unchanged; `fx`, `fy`,
|
||||
`cx` and `cy` are scaled on their respective axes.
|
||||
|
||||
The normalized matrix notation is `T_destination_from_source`, row-major
|
||||
homogeneous 4x4, with translation in metres. The file-level `transform` is
|
||||
`T_camera_0_from_lidar`. A serialized `camera_N.camera_pose` is
|
||||
`T_camera_0_from_camera_N`; the same inverse-and-compose operation used by
|
||||
xcolor produces:
|
||||
|
||||
```text
|
||||
T_camera_N_from_lidar = inverse(T_camera_0_from_camera_N)
|
||||
* T_camera_0_from_lidar
|
||||
```
|
||||
|
||||
The remaining uncertainty is temporal: exact camera exposure time versus the
|
||||
host-arrival timestamps currently retained by the external archive. This is a
|
||||
separate temporal-calibration gate and is not hidden inside accepted geometry.
|
||||
|
||||
## Calibration product boundary
|
||||
|
||||
### What the UI should expose
|
||||
|
||||
The normal device panel should show a small calibration status card:
|
||||
|
||||
- `Ready`, `Missing`, `Mismatch` or `Unverified`;
|
||||
- device model and firmware profile;
|
||||
- captured-at time and immutable snapshot digest;
|
||||
- canonical left/right source to calibration-slot mapping;
|
||||
- native calibrated resolution and admitted stream resolution;
|
||||
- geometry verification status;
|
||||
- timing status separately from geometry status.
|
||||
|
||||
It may expose one explicit **Read snapshot from connected K1** operation. That
|
||||
operation is read-only at the product level and must show the exact two admitted
|
||||
files and the resulting digest.
|
||||
|
||||
### What the UI should not expose
|
||||
|
||||
Mission Core must not accept or upload a firmware archive merely to obtain
|
||||
calibration. A general firmware uploader would add OTA, integrity, rollback and
|
||||
device-bricking responsibilities without helping the perception path.
|
||||
|
||||
An advanced offline import is useful only for replay, recovery or a device that
|
||||
cannot currently be reached. It must accept a small Mission Core calibration
|
||||
bundle containing only the two admitted YAML documents plus identity metadata.
|
||||
It must not accept a firmware TAR, arbitrary filesystem path or device write.
|
||||
|
||||
### Read-only device snapshot rules
|
||||
|
||||
The existing plugin action `calibration.device-snapshot.read` becomes the only
|
||||
live entry point. Its implementation must:
|
||||
|
||||
1. require an already verified, owner-controlled K1 session;
|
||||
2. publish only the reviewed `CacFileRead` request;
|
||||
3. use an exact path allowlist for the two factory YAML files;
|
||||
4. reject redirects, relative paths, extra response paths and write commands;
|
||||
5. bound each response before YAML parsing;
|
||||
6. parse with a safe loader and an exact schema/finite-number validation;
|
||||
7. record original byte length and SHA-256 without rewriting the source bytes;
|
||||
8. bind the snapshot to device identity, model, firmware and compatibility
|
||||
profile;
|
||||
9. publish the complete snapshot atomically in private storage;
|
||||
10. leave `CacFileWrite` unavailable.
|
||||
|
||||
The snapshot contract must name transform direction and coordinate convention
|
||||
explicitly. A matrix called only `extrinsic` or `T` is not admissible at the
|
||||
Mission Core boundary.
|
||||
|
||||
### Implementation status — 2026-07-20
|
||||
|
||||
The first read-only boundary is now implemented:
|
||||
|
||||
- `protocol/calibration_file.py` encodes only command `5` and has no API for
|
||||
command `6`;
|
||||
- its request path is a closed two-value type at runtime: `camera.yaml` or
|
||||
`extrinsic_camera_lidar.yaml` at their exact factory-data locations;
|
||||
- response identity, session, authority, command, path, result code, UTF-8,
|
||||
duplicates and byte bounds fail closed;
|
||||
- `protocol/calibration_mqtt.py` performs one `DeviceInfo` read followed by the
|
||||
two sequential file reads on one clean MQTT connection, with no reconnect or
|
||||
automatic retry;
|
||||
- `calibration.device-snapshot.read` now invokes that physical read instead of
|
||||
returning the generic plugin state;
|
||||
- before that read, Bridge/Direct Connect refresh the selected K1's DHCP lease
|
||||
from the read-only BLE status characteristic; the IP is session state, while
|
||||
the correlated MQTT `DeviceInfo` is the identity barrier;
|
||||
- each successful read seals a new private `0700` directory with `0600` source
|
||||
files, a manifest and SHA-256 identities; no earlier snapshot is replaced;
|
||||
- `calibration_schema.py` rejects duplicate keys, anchors, aliases, explicit
|
||||
tags, unknown fields, non-finite values, non-K1 dimensions and invalid rigid
|
||||
transforms before a snapshot can become available;
|
||||
- the manifest contains explicit left/right bindings, the 800x600 image
|
||||
transform, KB4 parameters and `T_camera_N_from_lidar` matrices;
|
||||
- the physical normalized snapshot captured at `2026-07-20T10:54:32.613Z`
|
||||
has content identity
|
||||
`05f3ad9b38b3a4fc95388a8ec83da83c745e217709e51787b3d5aad0969f6fa9`;
|
||||
- the complete Python suite passes with the boundary installed.
|
||||
|
||||
The P0 geometric-input subgate is accepted. The recorded Rerun diagnostic is
|
||||
also generated and opens in the native viewer. P0 as a whole still requires
|
||||
measured reprojection agreement across the image and a temporal-offset budget;
|
||||
parsing a valid matrix or visually plausible overlay is not a substitute for
|
||||
those measurements.
|
||||
|
||||
The first reproducible recorded diagnostic was generated on 2026-07-20 by the
|
||||
new `k1link analyze calibrated-overlay` path. Experiment
|
||||
`20260720T112515Z_k1_calibrated_overlay_2655c5c7c38e` is bound to the immutable
|
||||
RAVNOVES00 MQTT, camera and calibration generations. It produced four
|
||||
depth-coloured PNG overlays plus a 4,016,830-byte Rerun diagnostic with SHA-256
|
||||
`83bc5c1134563987c3be5734d6c069d07ad8a9e5b6806682169c89f4bd5354d9`.
|
||||
|
||||
The experiment established one previously implicit frame operation: current
|
||||
`lio_pcl` coordinates are in the K1 map frame, so projection uses
|
||||
`inverse(T_map_from_lidar)` before `T_camera_1_from_lidar` and KB4. The four
|
||||
selected camera frames projected 1,613/2,617, 983/1,813, 1,543/2,744 and
|
||||
1,730/1,880 source points respectively. Visual inspection shows coherent
|
||||
facade, vehicle, vegetation and ground structure across the fisheye image.
|
||||
This is diagnostic evidence, not a measured pixel-error acceptance: explicit
|
||||
static landmark correspondences and the temporal-offset sweep remain open.
|
||||
|
||||
## Recorded segmentation and calibrated fusion probe
|
||||
|
||||
A four-frame P1/P2/P3 probe now exists on the same immutable RAVNOVES00 camera
|
||||
anchors. The RTX worker received the raw camera pixels, not the LiDAR-coloured
|
||||
overlay, and the transferred PNG SHA-256 values were verified on both hosts.
|
||||
|
||||
The admitted research profiles are:
|
||||
|
||||
- TorchVision Mask R-CNN ResNet50-FPN v2 / COCO_V1 for instance masks, with
|
||||
weight SHA-256
|
||||
`73cbd0190fcbe3ba339921fbce2c3a0b6bb9126c9a133c85e43a2a8e060a109e`;
|
||||
- Microsoft BEiT base / ADE20K-150 for semantic masks, revision
|
||||
`a8b6f5ef4acb2ea55d882989deaa02d39401e2b2`, with weight SHA-256
|
||||
`e0747360d190bd7c0f53d2fe3b2ed560c304d3eefef94574af9c7e93aaf8e7a9`.
|
||||
|
||||
BEiT was published only after an exact checkpoint load with no missing,
|
||||
unexpected or mismatched keys. An earlier Intel DPT/ADE probe was rejected:
|
||||
its checkpoint left twelve fusion-layer parameters newly initialized. The
|
||||
strict repeat failed before publication, so that output is diagnostic only and
|
||||
cannot enter fusion.
|
||||
|
||||
The accepted segmentation generation is
|
||||
`1ef80a6df60830d8ac37f09db679696325adb65ef61094b666165f561b992a08`.
|
||||
On the three warm frames, sequential Mask R-CNN inference took 100–124 ms and
|
||||
BEiT took 244–312 ms. The combined 365–412 ms is only about 2.4–2.7 FPS before
|
||||
decode, transfer and fusion; this is not a live real-time acceptance.
|
||||
|
||||
Mission Core sampled both masks at factory-calibrated LiDAR projections and
|
||||
published fusion experiment
|
||||
`20260720T121000Z_k1_segmentation_fusion_d09020d0cb13`, generation
|
||||
`3d150012cf88ad477c602aa072d0b6c2675ca472204b61d9377eb8b83c128842`.
|
||||
Distance is Euclidean range from the current LiDAR origin. A diagnostic box is
|
||||
published only after the instance mask contains at least four points in one
|
||||
contiguous depth cluster; its current bounds are map-frame axis-aligned p05–p95
|
||||
bounds with a 12 m maximum span gate.
|
||||
|
||||
| camera session | projected points | diagnostic Boxes3D |
|
||||
|---:|---:|---:|
|
||||
| 95.471 s | 1,613 | 2 |
|
||||
| 215.408 s | 983 | 5 |
|
||||
| 335.424 s | 1,543 | 3 |
|
||||
| 455.450 s | 1,730 | 4 |
|
||||
|
||||
The span gate rejected a large false `car` mask even though it contained 854
|
||||
clustered points. Sparse objects remain 2D observations with an explicit
|
||||
insufficient-support status. The 11,582,442-byte Rerun RRD has SHA-256
|
||||
`1c190e6dc64b8c1e187c053cd950dabc4167d1d7fe3c8ec5e2499c0d5d3fa471`.
|
||||
Native headless viewer QA confirmed synchronized raw, semantic and fusion image
|
||||
views, semantic `Points3D`, and translucent `Boxes3D` with distance/support
|
||||
labels. Distances and boxes are not ground-truthed, tracked or safety accepted.
|
||||
|
||||
## Automatic camera/calibration binding
|
||||
|
||||
The binding is performed when a compute job is prepared:
|
||||
|
||||
```text
|
||||
camera archive summary.source_id
|
||||
-> compatibility-profile source mapping
|
||||
-> exact camera slot in device calibration snapshot
|
||||
-> image-transform profile for the admitted codec epoch
|
||||
-> calibration generation SHA-256 in the compute job
|
||||
```
|
||||
|
||||
Preparation fails closed when any link is absent or ambiguous. The worker must
|
||||
not choose a default camera. The result repeats the calibration generation and
|
||||
camera source; Mission Core revalidates both before accepting a derived layer.
|
||||
|
||||
The left/right mapping is now device-snapshot data backed by the exact FW 3.0.2
|
||||
profile. The compute-job binding is still pending; no worker may infer a slot
|
||||
from list order or use a default camera.
|
||||
|
||||
## Minimal recorded vertical
|
||||
|
||||
### Gate P0 — calibration snapshot and camera mapping
|
||||
|
||||
Deliverables:
|
||||
|
||||
- bounded protobuf codec for `CalibFileRequest` and `CalibFileResponse`;
|
||||
- whitelisted read-only snapshot action and tests;
|
||||
- immutable private snapshot with source digests;
|
||||
- verified mapping for both canonical camera source IDs;
|
||||
- validated 4000x3000-to-800x600 image transform;
|
||||
- a Rerun diagnostic layer showing projected LiDAR samples over the image.
|
||||
|
||||
Acceptance requires visible and measured agreement on several static regions
|
||||
across the image, not one hand-picked object at the center.
|
||||
|
||||
### Gate P1 — full-timeline 2D perception
|
||||
|
||||
Run the complete `RAVNOVES00` camera epoch, not one still image. Preserve every
|
||||
decoded frame's admitted session timestamp and produce two independent
|
||||
versioned outputs:
|
||||
|
||||
- instance masks for countable objects such as people and vehicles;
|
||||
- semantic classes for background/stuff such as ground, building and
|
||||
vegetation.
|
||||
|
||||
Together these form the requested panoptic view. The existing YOLOX-S result is
|
||||
a detector smoke test and remains useful as a baseline, but it cannot satisfy
|
||||
this gate. Model choice remains replaceable behind the result contract and is
|
||||
accepted only after measured accuracy, latency, VRAM and license review.
|
||||
|
||||
Operator playback uses a generation-bound H.264 panoptic MP4 beside the native
|
||||
Rerun canvas. Embedding every 800x600 `SegmentationImage` row in RRD would make
|
||||
multi-hour raster playback depend on browser memory. Lossless masks remain
|
||||
content-addressed derived evidence for fusion, while the MP4 is read through
|
||||
native HTTP Range and follows the same `session_time` controller as the source
|
||||
camera and point cloud. Small diagnostic RRDs may still use
|
||||
`SegmentationImage`, `AnnotationContext` and `Boxes2D`; that is not the scalable
|
||||
full-epoch transport.
|
||||
|
||||
### Gate P2 — 2D-to-3D fusion and distance
|
||||
|
||||
For each admitted camera frame:
|
||||
|
||||
1. select a temporally compatible LiDAR frame/window;
|
||||
2. transform LiDAR points into the selected camera frame;
|
||||
3. project with the K1 KB4 model and the validated stream transform;
|
||||
4. reject points behind the camera and resolve occlusion with a depth buffer;
|
||||
5. sample the panoptic mask at each visible projected point;
|
||||
6. retain labeled points in LiDAR coordinates;
|
||||
7. compute per-instance nearest robust distance, centroid and distance spread;
|
||||
8. cluster instance points and fit an oriented 3D box only when support is
|
||||
sufficient.
|
||||
|
||||
A 2D rectangle must never be blindly extruded into a fake 3D box. An object
|
||||
with insufficient or stale LiDAR support remains a 2D observation with an
|
||||
explicit `depth unavailable` reason.
|
||||
|
||||
Distance v1 should be displayed directly on each object label. Click-to-query
|
||||
is a later interaction enhancement, not a dependency of correct distance.
|
||||
|
||||
### Gate P3 — Rerun 3D presentation
|
||||
|
||||
The derived layer logs:
|
||||
|
||||
- semantic/instance masks on the camera image;
|
||||
- labeled points as `Points3D` using the same class ontology;
|
||||
- supported objects as oriented `Boxes3D`;
|
||||
- object ID, class, confidence, distance and support count;
|
||||
- calibration/result generation metadata and degraded-state reasons.
|
||||
|
||||
Rerun's native camera projection is pinhole-only. K1 uses KB4 fisheye, so
|
||||
Mission Core must perform the calibrated KB4 projection itself or log a proven
|
||||
undistorted image. It must not present an uncorrected pinhole frustum as exact
|
||||
K1 geometry.
|
||||
|
||||
### Gate P4 — recorded qualification
|
||||
|
||||
Qualify the entire 8–9 minute session with:
|
||||
|
||||
- no frame or segment ceiling;
|
||||
- deterministic repeat identity;
|
||||
- end-to-end throughput and wall time;
|
||||
- CPU, RAM, GPU, VRAM and disk telemetry;
|
||||
- calibration reprojection statistics;
|
||||
- temporal-offset sweep and moving-object error report;
|
||||
- explicit failure/degraded reasons;
|
||||
- immutable raw inputs and separately replaceable derived results.
|
||||
|
||||
## Bounded live vertical
|
||||
|
||||
Only after P0–P4 pass does live mode reuse the same model and fusion contracts.
|
||||
|
||||
The live path has two different policies:
|
||||
|
||||
- archival inputs are never dropped by the viewer or inference queue;
|
||||
- derived preview is latest-wins with a small bounded queue and explicit
|
||||
dropped/stale counters.
|
||||
|
||||
The first live target is stable 5–10 Hz derived perception, not an unsupported
|
||||
claim of matching every camera or LiDAR message. It must expose:
|
||||
|
||||
- capture, queue, decode, inference, fusion and render latency;
|
||||
- queue depth and dropped derived frames;
|
||||
- calibration generation in use;
|
||||
- worker disconnect/recovery state;
|
||||
- `healthy`, `degraded`, `stale` and `unavailable` states;
|
||||
- raw recording continuity when the worker is slow or absent.
|
||||
|
||||
The external RTX worker remains an executor. It receives bounded observations
|
||||
and calibration references; it gains no K1 command authority.
|
||||
|
||||
## Deferred intentionally
|
||||
|
||||
The following are not prerequisites for the first correct vertical:
|
||||
|
||||
- uploading full firmware through Mission Core;
|
||||
- calibrating the already factory-calibrated assembled K1 rig again;
|
||||
- native LiDAR-only neural segmentation;
|
||||
- multi-camera stitching;
|
||||
- multi-object tracking across long occlusions;
|
||||
- HD maps, ROS 2, vehicle control or safety decisions;
|
||||
- a universal model marketplace or scheduler.
|
||||
|
||||
Native point-cloud segmentation and tracking may be added later as independent
|
||||
pipelines and compared against the camera-fused labels. They must not block the
|
||||
first evidence-backed 3D boxes and distances.
|
||||
|
||||
## Immediate implementation order
|
||||
|
||||
1. Keep the accepted Windows reboot path healthy and reproducible.
|
||||
2. ~~Implement and offline-test the bounded calibration file protobuf codec.~~
|
||||
3. ~~Implement `calibration.device-snapshot.read` with the two-path allowlist.~~
|
||||
4. ~~Capture the physical K1 snapshot and prove left/right slot mapping.~~
|
||||
5. ~~Generate a reproducible calibrated LiDAR-over-video diagnostic on
|
||||
`RAVNOVES00`.~~ Record measured static-landmark reprojection error and the
|
||||
temporal-offset budget for the accepted 800x600 transform.
|
||||
6. Extend compute job/result contracts with camera source and calibration
|
||||
generation binding.
|
||||
7. ~~Prove instance and semantic masks on four physical frames.~~ Produce the
|
||||
complete recorded epoch with immutable result identity and exact-repeat
|
||||
reuse.
|
||||
8. ~~Prove mask-to-point fusion, diagnostic distances and support-gated 3D
|
||||
boxes on four frames.~~ Add ground truth, tracking and accepted oriented-box
|
||||
fitting.
|
||||
9. ~~Open the four-frame fused result in native Rerun.~~ Qualify the full
|
||||
session with resource and timing telemetry.
|
||||
10. ~~Qualify the bounded latest-wins scheduler and machine world-state contract
|
||||
with source-paced replay.~~ Move the same contract onto the real worker
|
||||
inference path, then connect the live K1.
|
||||
|
||||
## LAB E7 replay-real-time checkpoint · 2026-07-21
|
||||
|
||||
LAB E7 accepted the first source-paced downstream perception runtime on the
|
||||
same 601-frame E6 interval. The result
|
||||
`e7-live-replay-e339aaed75fff05ed893ae48770bd127cc0c764f3124fc4b6be94b5fd9f8389c`
|
||||
published 601/601 machine world states at 10.021845 Hz with zero drops, a
|
||||
capacity-two queue and 5.927 ms p95 scheduled-tick-to-publication latency. The
|
||||
526 fused frames were healthy; all 75 E6 sync-gated frames were explicitly
|
||||
degraded, with no stale or unavailable states.
|
||||
|
||||
The world state carries object identity, class, map and K1-LiDAR position,
|
||||
visible-surface 3D size, range, support, guarded diagnostic velocity and a
|
||||
72-sector diagnostic clearance observation. Vehicle-body coordinates remain
|
||||
unavailable until a real sensor-to-vehicle transform is supplied. Rerun is a
|
||||
subscriber showing point cloud, `Boxes3D`, latency, queue depth and health; it
|
||||
is not the perception authority.
|
||||
|
||||
An intentional 250 ms consumer-delay control processed 33/80 frames, discarded
|
||||
47 obsolete derived frames, never exceeded queue depth two and marked 32
|
||||
published states stale. Raw evidence remained outside the derived queue. This
|
||||
proves bounded overload behavior, not live inference. E4, E5 and E6 inputs were
|
||||
precomputed and the AI worker was untouched.
|
||||
|
||||
Full provenance, pilot corrections, profile hashes, latency tables, velocity
|
||||
guards, clearance limits, artifacts and the LAB E8 gate are recorded in
|
||||
`experiments/perception/LAB_E7_REPORT_2026-07-21.md`.
|
||||
@@ -1,6 +1,6 @@
|
||||
# ADR 0013: explicit K1 local connection matrix
|
||||
|
||||
- Status: accepted for implementation; physical acceptance is mode-specific
|
||||
- Status: amended 2026-07-20; Bridge is the product path, Quick Connect retained as a prepared-host laboratory path
|
||||
- Date: 2026-07-19
|
||||
- Extends: ADR 0004, ADR 0005 and ADR 0012
|
||||
|
||||
@@ -28,7 +28,7 @@ firmware `3.0.2` compatibility profile:
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Bridge | `direct-lan` | one reviewed BLE provisioning write | none | physically accepted in Mission Core |
|
||||
| Direct Connect | `controller-hotspot` | the same reviewed BLE provisioning write | operator prepares the hotspot and route | implementation complete; physical run pending |
|
||||
| Quick Connect | `device-ap` | none | one CoreWLAN scan and association | LixelGO data plane observed; Mission Core host run pending |
|
||||
| Quick Connect | `device-ap` | one fixed reviewed 100-byte AP-enable write | preinstalled exact-firmware credential provider, bounded exact-SSID discovery and one association | physically accepted on one prepared Mac; not portable bootstrap |
|
||||
|
||||
Bridge remains the default. Every API request carries both `connection_mode`
|
||||
and its exact topology attestation; mismatched pairs are rejected before any
|
||||
@@ -36,36 +36,121 @@ network action. Acquisition and camera admission must match the active mode.
|
||||
The fixed K1 AP address is admitted only after a successful Quick Connect host
|
||||
association.
|
||||
|
||||
Bridge and Direct Connect do not have a fixed product IP. The address reported
|
||||
by BLE characteristic `7f02` is a DHCP lease observation scoped to the current
|
||||
connection, never device identity and never a durable configuration value.
|
||||
Before a new application-control session, an implicit-host acquisition, or a
|
||||
factory-calibration read, Mission Core performs one read-only `7f02` read for
|
||||
the selected CoreBluetooth device and replaces the previous target. An address
|
||||
change creates a new `device_session_id` and invalidates calibration captured
|
||||
for the previous session. An active acquisition is never retargeted in place.
|
||||
The later correlated MQTT `DeviceInfo` response supplies model, firmware,
|
||||
serial and vendor identity; IP equality alone cannot identify a K1.
|
||||
|
||||
Product decision on 2026-07-20: Bridge/direct-LAN is the continuing route.
|
||||
Quick Connect remains visible and executable on an already prepared host, but
|
||||
is not a deployment dependency or portability claim.
|
||||
|
||||
Direct Connect does not introduce a new vendor payload. The operator first
|
||||
starts a hotspot on the controlling device and enters that hotspot's SSID and
|
||||
password. Mission Core performs the same single, physically reviewed BLE write
|
||||
used by Bridge and accepts only the non-AP private IPv4 returned by K1 status.
|
||||
|
||||
Quick Connect does not write GATT. A short-lived macOS Swift/CoreWLAN helper
|
||||
receives the operator-entered AP SSID and password as bounded JSON on stdin.
|
||||
The credential never appears in argv, environment, stdout, stderr, manifests or
|
||||
browser persistence. The helper performs at most one scan and one association;
|
||||
Mission Core does not retry. The implementation intentionally does not infer or
|
||||
read the K1 AP password from an undocumented BLE structure. Until that read has
|
||||
its own captured characteristic, bounded decoder and review, the operator must
|
||||
enter the AP credentials shown for the owner-controlled scanner.
|
||||
Quick Connect does not accept a credential from the browser/API. The first
|
||||
implementation incorrectly jumped from BLE discovery directly to host Wi-Fi
|
||||
association. A physical negative run showed that the selected K1 was still on
|
||||
the existing LAN and the expected AP was not visible. Re-review of the exact
|
||||
LixelGO branch recovered the missing state transition: after BLE connection it
|
||||
writes one 100-byte `7f01` frame, zero except for `0x01` at offset 99, and treats
|
||||
the callback as the AP-launch result before invoking the OS Wi-Fi connector.
|
||||
|
||||
No connection-verification button emits a probe. It validates only the admitted
|
||||
private address; the later canonical MQTT session supplies the real data-plane
|
||||
connection attempt. A failed or ambiguous network action remains terminal until
|
||||
the operator checks physical state and explicitly starts a new operation.
|
||||
Mission Core now performs that bounded AP-enable write at most once. The first
|
||||
physical run reached `WIFI_AP` at the reviewed AP address, and a targeted
|
||||
CoreWLAN scan found the SSID matching the selected BLE advertised name. It also
|
||||
disproved the earlier assumption that LixelGO carried one global Quick Connect
|
||||
profile: retained client analysis exposes `WiFiAP_SSID` and `WiFiAP_Password` as
|
||||
fields of each device record.
|
||||
|
||||
A subsequent run found that `7f02` may retain `WIFI_AP / 192.168.56.1` after the
|
||||
SSID stops beaconing. Static review then recovered the missing discriminator:
|
||||
LixelGO maps response byte 51 to its AP-ready flag and waits up to 15 seconds for
|
||||
that flag. Mission Core therefore mirrors LixelGO: every new operator Quick
|
||||
Connect action emits exactly one reviewed enable frame, including from a
|
||||
`WIFI_AP` baseline, and admits host discovery only after byte 51 becomes
|
||||
non-zero. This is not an automatic retry.
|
||||
|
||||
The same review proved that LixelGO does not close its BLE manager between the
|
||||
AP-ready callback and native Wi-Fi connect. A failed Mission Core run had done
|
||||
exactly that: byte 51 changed from zero to one, the Python BLE context exited,
|
||||
and the following cold Swift/CoreWLAN process missed the beacon. The corrected
|
||||
implementation holds the selected `BleakClient` open through bounded native
|
||||
SSID discovery and the single association call.
|
||||
|
||||
BLE discovery and the selected device action form one host session. A physical
|
||||
run proved that immediately rediscovering the same K1 by its CoreBluetooth UUID
|
||||
can fail even though the preceding scan exposed it. Mission Core retains the
|
||||
non-serializable `BLEDevice` handle process-locally and uses that exact handle
|
||||
for the next selected network action; it never exposes the handle through API
|
||||
state or treats the macOS UUID as durable device identity.
|
||||
|
||||
The corrected host boundary derives a non-secret, device-scoped profile ID from
|
||||
the selected SSID. The reviewed client contains per-device `WiFiAP_SSID` and
|
||||
`WiFiAP_Password` fields, but the 2026-07-20 review of the exact official K1
|
||||
`3.0.2` firmware recovered their upstream source: the scanner's bundled
|
||||
NetworkManager AP script assigns one firmware-constant WPA2 material, while
|
||||
`lixel_nman` constructs `XGR-` plus six device-identity characters with a MAC
|
||||
fallback. It is neither an iPhone credential nor a per-device secret.
|
||||
|
||||
The laboratory implementation can install a firmware-scoped credential source from the
|
||||
authenticated official archive. The offline importer validates the exact
|
||||
SHA-256, streams the bounded application-partition range, requires one valid AP
|
||||
declaration and writes the value to the OS secure store through helper stdin.
|
||||
On macOS, the Keychain helper materializes the selected device profile from
|
||||
that opaque source before any BLE write. A missing provider fails closed. The
|
||||
browser, API, argv, logs, manifests and evidence never receive the secret; the
|
||||
importer's short-lived mutable buffer is zeroized after the Keychain handoff.
|
||||
|
||||
The host-network boundary, rather than the XGRIDS frontend, owns platform
|
||||
association. Browsers expose no Wi-Fi join API, and Apple's iOS
|
||||
`NEHotspotConfiguration` consent flow is unavailable on macOS. The current
|
||||
implementation therefore uses a short-lived Swift/CoreWLAN + macOS Keychain
|
||||
helper; Windows Credential Manager and Linux Secret Service adapters remain
|
||||
separate platform work. The helper performs repeated read-only exact-SSID scans
|
||||
inside one 15-second discovery window and at most one association. It never
|
||||
repeats the BLE command, guesses a password or treats `7f01` as a credential-read
|
||||
command. The credential-bearing 99-byte station-provisioning frame and fixed
|
||||
100-byte AP-enable frame are separate reviewed payloads.
|
||||
|
||||
No reviewed BLE characteristic or response supplies the AP credential. That
|
||||
does not prove a universal negative for every vendor build, but it means the
|
||||
current plugin has no evidence-backed device-side credential acquisition path.
|
||||
The owner also observed no explicit device/account pairing in the normal
|
||||
LixelGo onboarding flow; this is consistent with a firmware-defined AP secret,
|
||||
but does not establish account-wide authorization for arbitrary scanners.
|
||||
|
||||
Connection verification refreshes the session-scoped lease with the same
|
||||
read-only BLE status operation. It does not write a characteristic, re-provision
|
||||
Wi-Fi, scan the subnet, change a host route, or touch VPN configuration. The
|
||||
later canonical MQTT session supplies the real data-plane connection and live
|
||||
`DeviceInfo` identity check. A BLE lease observation is therefore not by itself
|
||||
a claim that MQTT/RTSP is reachable.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The UI now represents all three intended directions instead of disabled
|
||||
placeholders.
|
||||
- Quick Connect can temporarily remove the Mac from its previous Wi-Fi network.
|
||||
macOS may require Wi-Fi/location permission for the process running Mission
|
||||
Core.
|
||||
- Quick Connect can temporarily remove the controlling host from its previous
|
||||
Wi-Fi network. The operating system may require Wi-Fi/location permission.
|
||||
- A new host needs a separate exact-firmware provider installation. The current
|
||||
application does not obtain it from BLE and does not bootstrap it by itself.
|
||||
- Automatic firmware download, iPhone extraction and hard-coded credential
|
||||
delivery are explicitly rejected product routes. Windows/Linux adapters are
|
||||
therefore not scheduled for this Quick Connect path.
|
||||
- Direct Connect requires an already-running hotspot and a controller route;
|
||||
Mission Core does not create or manage that hotspot.
|
||||
- The application-control, START/STOP and raw-first acquisition protocol is
|
||||
unchanged after a target address is admitted.
|
||||
- Direct Connect and Mission Core Quick Connect remain explicitly pending one
|
||||
owner-operated physical acceptance cycle each. Offline tests cannot promote
|
||||
those claims.
|
||||
- Direct Connect remains explicitly pending one owner-operated physical
|
||||
acceptance cycle. Quick Connect AP activation and host association are
|
||||
physically accepted only on the prepared K1/FW 3.0.2 Mac stand. Bridge is the
|
||||
only accepted portable product path in this matrix.
|
||||
|
||||
@@ -0,0 +1,627 @@
|
||||
# Mission Core handoff: AI worker, external perception and K1 Quick Connect
|
||||
|
||||
Date of factual refresh: 2026-07-19 21:15 MSK.
|
||||
|
||||
> 2026-07-20 superseding update: official firmware analysis proved that the
|
||||
> exact K1 `3.0.2` AP credential is firmware-constant and that the SSID follows
|
||||
> an identity/MAC rule. A prepared Mac completed AP-ready, CoreWLAN association
|
||||
> and the normal control lifecycle. This did **not** solve clean-host bootstrap:
|
||||
> the provider had been separately imported from the firmware archive. The
|
||||
> owner closed this product branch, rejected automatic firmware download,
|
||||
> iPhone extraction and hard-coding, retained the working UI/Keychain state and
|
||||
> selected Bridge/direct-LAN as the continuing route. Canonical details:
|
||||
> `docs/lab/004_K1_FW302_AP_CREDENTIAL_PROVIDER_20260720.redacted.md`.
|
||||
|
||||
This document is a transition context for a new engineering chat. It separates
|
||||
committed/accepted work from current uncommitted K1 work and from future plans.
|
||||
It contains operational addresses, ports, repository paths and public
|
||||
fingerprints, but no password, private key, token, device secret, raw capture or
|
||||
camera image.
|
||||
|
||||
## Executive state
|
||||
|
||||
Mission Core currently has two independently meaningful physical results:
|
||||
|
||||
1. The Mac/K1 control and archive path is accepted for one owner-controlled
|
||||
XGRIDS LixelKity K1, firmware 3.0.2, Bridge/direct-LAN, handheld, GNSS without
|
||||
RTK. Mission Core can run the reviewed MQTT bootstrap, START acquisition,
|
||||
display live points, send explicit STOP, observe final READY/unbound and open
|
||||
the durable Rerun/camera archive.
|
||||
2. A replaceable Windows RTX 4090 worker is accepted for one recorded,
|
||||
camera-only perception job. The Mac publishes a bounded immutable
|
||||
`missioncore.compute-job/v1`; Windows verifies it, runs pinned YOLOX-S through
|
||||
pinned Triton, publishes `missioncore.compute-result/v1`; Mission Core
|
||||
revalidates and projects the optional result into the matching saved Rerun
|
||||
recording.
|
||||
|
||||
This is not yet a live autonomous-vehicle stack. The worker has no K1 authority,
|
||||
Triton is not exposed to the LAN, the current transfer is SSH/SCP laboratory
|
||||
bootstrap, Tailscale is not installed, and live fan-out/fusion/tracking/free
|
||||
space/control are not accepted.
|
||||
|
||||
The current K1 Quick Connect implementation is a separate uncommitted worktree.
|
||||
It proved BLE AP activation, exact AP-ready observation and prepared-host native
|
||||
macOS association/control. It remains laboratory-only because a clean host has
|
||||
no autonomous evidence-backed credential source. The implementation and current
|
||||
machine state are retained, but Bridge/direct-LAN is the product route.
|
||||
|
||||
## Canonical topology and authority
|
||||
|
||||
```text
|
||||
XGRIDS K1
|
||||
| BLE / MQTT / RTSP
|
||||
v
|
||||
Mission Core Edge on Mac
|
||||
- sole K1 command authority
|
||||
- sole acquisition lifecycle owner
|
||||
- authoritative raw .k1mqtt + camera fMP4 archive
|
||||
- durable session catalog and Rerun projection
|
||||
|
|
||||
| bounded immutable missioncore.compute-job/v1
|
||||
| current lab transport: SSH/SCP
|
||||
v
|
||||
Mission Core AI Server Worker on Windows / RTX 4090
|
||||
- verifies the complete job and every digest
|
||||
- reconstructs and decodes only the admitted camera epoch
|
||||
- calls local pinned Triton / pinned model
|
||||
- atomically publishes missioncore.compute-result/v1
|
||||
|
|
||||
v
|
||||
Mission Core Edge validates result and creates optional derived Rerun layer
|
||||
```
|
||||
|
||||
The Windows machine is an executor, not a second Mission Core. It does not know
|
||||
K1 credentials, IP, MQTT topics or RTSP endpoints and cannot discover,
|
||||
provision, START or STOP the scanner. Derived inference never replaces or
|
||||
rewrites the Mac source archive.
|
||||
|
||||
## Why the original architecture proposal was narrowed
|
||||
|
||||
The supplied architecture review was accepted as a boundary, not as a mandate
|
||||
to install every named technology immediately. The following principles were
|
||||
kept:
|
||||
|
||||
- one vendor owner for K1 control and source streams;
|
||||
- immutable raw-first evidence and separately versioned derived data;
|
||||
- replaceable external compute;
|
||||
- local mission/safety authority rather than a remote GPU dependency;
|
||||
- explicit separation of command/state, real-time flow and archive transport;
|
||||
- declarative, reproducible deployment built mostly from mature components.
|
||||
|
||||
The following were deliberately deferred because they would precede the first
|
||||
vertical evidence:
|
||||
|
||||
- custom universal Mission Core Node Runtime;
|
||||
- custom cross-platform installer, node console, OTA, model package format and
|
||||
generic scheduler;
|
||||
- ROS 2 before a real onboard computer, robot state and actuator/autopilot
|
||||
contract exist;
|
||||
- BehaviorTree.CPP before a local mission executor is needed;
|
||||
- Zenoh until direct/routed transport can be compared on identical data;
|
||||
- MCAP as a replacement for the accepted K1 raw source;
|
||||
- dora-rs as a control/safety foundation;
|
||||
- LM Studio for the camera/LiDAR detector vertical.
|
||||
|
||||
Triton was selected for the first executor because it already provides pinned
|
||||
model repositories, HTTP/gRPC, health, metrics and replaceable inference
|
||||
backends. Mission Core continues to own its northern job/result contracts.
|
||||
|
||||
## Windows host identity and hardware
|
||||
|
||||
Live read-only inventory at the refresh time:
|
||||
|
||||
- host: `<worker-host>`;
|
||||
- interactive/SSH account: `<worker-host>\<worker-user>`;
|
||||
- OS: Windows 11 Pro x64, version 10.0.26200, build 26200;
|
||||
- last boot: 2026-07-19 15:38:18 MSK;
|
||||
- PowerShell: 5.1.26100.7705;
|
||||
- CPU: Intel Core i9-13900KF, 24 cores / 32 logical processors;
|
||||
- RAM: 95.85 GiB;
|
||||
- GPU: NVIDIA GeForce RTX 4090, 24,564 MiB VRAM, compute capability 8.9;
|
||||
- NVIDIA driver: Studio 610.47 WHQL;
|
||||
- live GPU snapshot: about 10,229 MiB used, 13,910 MiB free, 41 C and 68.68 W;
|
||||
- disk `C:`: NTFS, 1,861.99 GiB total, 1,700.86 GiB free;
|
||||
- disk `D:`: NTFS label `DC`, 1,863.00 GiB total, 411.44 GiB free;
|
||||
- Git: 2.53.0.windows.1;
|
||||
- Codex CLI: 0.142.1;
|
||||
- FFmpeg: 8.0.1 essentials build;
|
||||
- native host Python: not installed; Windows Store aliases exist but do not
|
||||
resolve to a Python runtime;
|
||||
- Tailscale: not installed.
|
||||
|
||||
The driver was upgraded from 591.86 to 610.47 after the first Triton startup
|
||||
showed CUDA Minor Version Compatibility mode. The official NVIDIA installer was
|
||||
978,481,008 bytes, SHA-256
|
||||
`59AC4A1659664AAD0A6FC525E5DF99B3FA76887BDE663F9E36E0E7EBB5DBA937`,
|
||||
had a valid NVIDIA Corporation Authenticode signature and returned exit code 0.
|
||||
After reboot, the compatibility warning disappeared and the full compute smoke
|
||||
passed.
|
||||
|
||||
## WSL and Docker substrate
|
||||
|
||||
- WSL: 2.7.8.0;
|
||||
- default distribution: Ubuntu 24.04, WSL version 2;
|
||||
- kernel: 6.18.33.1-microsoft-standard-WSL2;
|
||||
- Docker Desktop distribution: WSL2 and currently running;
|
||||
- Docker Desktop: 4.78.0;
|
||||
- Docker Engine/client: 29.5.3;
|
||||
- Docker Compose: 5.1.4;
|
||||
- Docker Linux VM: 32 CPUs and approximately 50.43 GB memory;
|
||||
- storage driver: overlayfs;
|
||||
- NVIDIA container runtime is registered; default runtime remains `runc` and
|
||||
the Compose service explicitly requests all GPUs.
|
||||
|
||||
Docker Desktop's engine-owned image/layer VHDX remains on `C:`. Mission Core
|
||||
application state is on `D:`. Moving Docker's VHDX was intentionally not made a
|
||||
pilot prerequisite.
|
||||
|
||||
## Isolated Windows directory layout
|
||||
|
||||
Root: `D:\NDC_MISSIONCORE`.
|
||||
|
||||
```text
|
||||
D:\NDC_MISSIONCORE\
|
||||
README.md
|
||||
workspace\
|
||||
mission-core-compute\ versioned deployment and worker repository
|
||||
runtime\
|
||||
cache\ disposable downloads/build cache
|
||||
derived\ decoded intermediates and immutable results
|
||||
docker-cli\ isolated Docker CLI state for SSH automation
|
||||
jobs\ bounded transferred compute jobs
|
||||
logs\ service/task transcripts
|
||||
models\ Triton model repository and weights
|
||||
tmp\ disposable temporary data
|
||||
secrets\ machine-local credentials, never committed
|
||||
```
|
||||
|
||||
The root itself is not a Git repository. Only
|
||||
`D:\NDC_MISSIONCORE\workspace\mission-core-compute` is versioned. Runtime
|
||||
weights, jobs, results, caches, logs and secrets are outside Git.
|
||||
|
||||
## Windows worker repository
|
||||
|
||||
Repository:
|
||||
`D:\NDC_MISSIONCORE\workspace\mission-core-compute`.
|
||||
|
||||
Current state:
|
||||
|
||||
- branch: `main`;
|
||||
- HEAD: `a3c36c3 feat(perception): prove recorded Triton vertical`;
|
||||
- previous commits:
|
||||
- `3c62815 guard native CUDA runtime compatibility`;
|
||||
- `d1043d0 qualify CUDA 13.3 driver path`;
|
||||
- `8edd003 bootstrap Windows GPU compute node`;
|
||||
- working tree: clean;
|
||||
- Git remote: none configured.
|
||||
|
||||
Versioned content includes `compose.yaml`, `.env.example`, model config,
|
||||
baseline/decision/acceptance docs, bounded PowerShell start/stop/test/handoff
|
||||
scripts and `worker/run_yolox_recorded.py`.
|
||||
|
||||
No custom Windows service, host Python environment, LM Studio integration,
|
||||
universal model loader or second Mission Core instance was installed.
|
||||
|
||||
## Active Triton deployment
|
||||
|
||||
Container: `mission-core-triton`, Compose project `mission-core-compute`.
|
||||
|
||||
Pinned image:
|
||||
|
||||
`nvcr.io/nvidia/tritonserver:26.06-py3@sha256:58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794`
|
||||
|
||||
The local image reports Triton 2.70.0 and a roughly 22.7 GB image size.
|
||||
|
||||
Effective deployment properties:
|
||||
|
||||
- `gpus: all`;
|
||||
- shared memory: 2 GiB;
|
||||
- model control: explicit;
|
||||
- automatic model config completion: disabled;
|
||||
- strict readiness: enabled;
|
||||
- server does not exit for one model error;
|
||||
- HTTP 8000, gRPC 8001 and metrics 8002 enabled;
|
||||
- every host binding is loopback-only: `127.0.0.1:8000-8002`;
|
||||
- `D:\NDC_MISSIONCORE\runtime\models` is mounted read-only at `/models`;
|
||||
- `no-new-privileges:true`;
|
||||
- container restart policy: `no`;
|
||||
- health check: HTTP `/v2/health/ready` every 5 seconds;
|
||||
- current state: running and healthy;
|
||||
- live, ready and metrics checks: HTTP 200;
|
||||
- GPU metrics present;
|
||||
- CUDA compatibility warning absent;
|
||||
- deprecated model-config warning absent.
|
||||
|
||||
The committed `.env` contains only the loopback bind and pinned Triton image.
|
||||
No credential is required for the current loopback-only service.
|
||||
|
||||
## Startup, shutdown and task bridge
|
||||
|
||||
The normal operator scripts are:
|
||||
|
||||
```powershell
|
||||
Set-Location D:\NDC_MISSIONCORE\workspace\mission-core-compute
|
||||
.\scripts\Start-MissionCoreCompute.ps1
|
||||
.\scripts\Test-MissionCoreCompute.ps1
|
||||
.\scripts\Stop-MissionCoreCompute.ps1
|
||||
```
|
||||
|
||||
`Start-MissionCoreCompute.ps1` uses the node-local Docker CLI directory,
|
||||
targets Docker Desktop's Linux engine pipe, creates loopback-only `.env` from
|
||||
the example when absent, starts Docker Desktop when needed, performs Compose
|
||||
pull/up and waits for Triton readiness.
|
||||
|
||||
Docker Desktop's Windows credential helper rejects the OpenSSH network-logon
|
||||
token even for public image pulls. The reviewed workaround is not a second
|
||||
deployment path: `Invoke-StartAsInteractiveUser.ps1` creates/starts the
|
||||
on-demand `MissionCore-StartCompute` task in the logged-on user's limited
|
||||
interactive token. It executes the same committed start script and writes
|
||||
`D:\NDC_MISSIONCORE\runtime\logs\start-compute-latest.log`.
|
||||
|
||||
Scheduled task state:
|
||||
|
||||
- `MissionCore-DockerDesktop`: enabled logon trigger for the interactive user,
|
||||
limited privilege, currently Running;
|
||||
- `MissionCore-StartCompute`: no trigger, on-demand only, last result 0,
|
||||
currently Ready;
|
||||
- Triton Compose restart policy is `no`.
|
||||
|
||||
Therefore Docker Desktop starts at user logon, but Triton is not a fully
|
||||
autonomous reboot-surviving service. It is started explicitly/on demand.
|
||||
|
||||
## Model repository
|
||||
|
||||
Accepted model: official YOLOX-S ONNX release 0.1.1rc0, Apache-2.0.
|
||||
|
||||
- model path: `runtime\models\yolox_s\1\model.onnx`;
|
||||
- byte length: 35,858,002;
|
||||
- SHA-256:
|
||||
`C5C2D13E59AE883E6AF3B45DAEA64AF4833A4951C92D116EC270D9DDBE998063`;
|
||||
- Triton platform: ONNX Runtime GPU;
|
||||
- model version: 1 only;
|
||||
- input: FP32 `[1,3,640,640]`, name `images`;
|
||||
- output: FP32 `[1,8400,85]`, name `output`;
|
||||
- one GPU instance;
|
||||
- preprocessing: bilinear resize, top-left letterbox, BGR, pad 114;
|
||||
- postprocessing: official YOLOX grid/stride decode, score 0.25, NMS 0.45,
|
||||
COCO-80.
|
||||
|
||||
The model is useful only as a contract/timing smoke. It is not accepted for
|
||||
navigation, obstacle avoidance, free-space or safety decisions.
|
||||
|
||||
## Accepted recorded job and result
|
||||
|
||||
Source Mission Core session:
|
||||
`20260718T201659Z_viewer_live` / display name `TEST007`.
|
||||
|
||||
Accepted input:
|
||||
|
||||
- source: `sensor.camera.left`, physical codec epoch 1;
|
||||
- job: `recorded-camera-fae25b92ecf645c2c9765dd4`;
|
||||
- schema: `missioncore.compute-job/v1`;
|
||||
- full input SHA-256:
|
||||
`fae25b92ecf645c2c9765dd4b4963f23cf8c101f22fd5a2e14a104f0b447140d`;
|
||||
- 59 digest-bound files, 4,567,569 package bytes;
|
||||
- reconstructed H.264 stream: 4,549,458 bytes;
|
||||
- stream SHA-256:
|
||||
`bceca577f762fdb79c4e8901e5c2a2330fd07d24dc091b1b703c5af4010d8a56`;
|
||||
- decode: H.264 High, 800x600, 56 frames, 5.497 seconds;
|
||||
- synchronization: `host-arrival-best-effort`;
|
||||
- frame timestamps are made strictly increasing from best-effort decode time;
|
||||
this is not calibrated camera/LiDAR sensor time.
|
||||
|
||||
Accepted result:
|
||||
|
||||
- result:
|
||||
`result-5484a72e81192b19f4e1da2a2dcfd10c876c277ff3e96c6d60cbc9d917b9f604`;
|
||||
- schema: `missioncore.compute-result/v1`;
|
||||
- detection schema: `missioncore.object-detections/v1`;
|
||||
- 56/56 frames processed;
|
||||
- 54 frames with detections;
|
||||
- 56 generic COCO `person` detections;
|
||||
- detection artifact: 23,802 bytes;
|
||||
- detection SHA-256:
|
||||
`71b291616e87bbdd2b7a295b1e00dac2ff3e60c627e63b72a27ba802c32a3ae0`;
|
||||
- client-observed inference latency: mean 15.611 ms, p50 15.001 ms,
|
||||
p95 23.728 ms, max 31.099 ms.
|
||||
|
||||
Triton currently reports 168 successful inference requests, 0 failed. Three
|
||||
56-frame executions account for that count. The final exact repeated command
|
||||
reused the already published content-addressed result and did not increase the
|
||||
counter, proving idempotent reuse.
|
||||
|
||||
The first runner attempt completed inference but failed its post-inference EOF
|
||||
guard. No partial result was published. The runner was corrected before the
|
||||
accepted immutable result was produced.
|
||||
|
||||
## Rerun result projection on the Mac
|
||||
|
||||
Mission Core revalidates exact session/job/result binding, all digests,
|
||||
timestamps, dimensions and frame count before projection. It builds one complete
|
||||
RRF2 derived overlay, approximately 62.55 MB, cached privately by
|
||||
result/recording identity.
|
||||
|
||||
The browser accepts the overlay on an isolated Rerun channel. Missing or invalid
|
||||
perception returns no optional layer and never replaces the base point-cloud
|
||||
recording. In TEST007 the `Распознавание` switch showed the real recorded left
|
||||
camera frame with `person · 34%` Boxes2D; `Облако точек` returned to the base 3D
|
||||
view.
|
||||
|
||||
Committed Mac work:
|
||||
|
||||
- `648d5bc feat(compute): add bounded camera job contract`;
|
||||
- `31fc4f6 docs(perception): record external worker acceptance`;
|
||||
- `2b53168 feat(perception): project recorded results into Rerun`;
|
||||
- `ada2a55 docs(perception): record Rerun projection acceptance`.
|
||||
|
||||
Mac `main` is currently at `ada2a55`; `origin/main` remains at `75d2e5d`, so the
|
||||
four perception commits are local and not pushed.
|
||||
|
||||
## Other active workloads on the RTX host
|
||||
|
||||
The GPU workstation is shared. These containers are not part of Mission Core:
|
||||
|
||||
- `sentinel-frigate`, image `ghcr.io/blakeblackshear/frigate:0.17.2-tensorrt`,
|
||||
healthy, publishes host ports 5000, 8554, 8555 TCP/UDP and 8971;
|
||||
- `sentinel-ollama`, image `ollama/ollama:latest`, publishes host port 11434 and
|
||||
has no configured container health check.
|
||||
|
||||
Their current resource use contributes to the roughly 10 GiB observed GPU
|
||||
allocation. Mission Core currently has no resource reservation, scheduler or
|
||||
admission policy against these workloads. Long-epoch and live performance tests
|
||||
must record this co-tenancy or isolate it deliberately.
|
||||
|
||||
## SSH access from the Mac
|
||||
|
||||
Windows OpenSSH was installed through official winget package
|
||||
`Microsoft.OpenSSH.Preview` 10.0.0.0 because Windows Feature-on-Demand failed:
|
||||
|
||||
- `Add-WindowsCapability`: Access denied;
|
||||
- DISM with `/LimitAccess`: `0x800f0912`, source files not found;
|
||||
- `wuauserv` startup/ACL changes were denied by host policy.
|
||||
|
||||
Current Windows SSH facts:
|
||||
|
||||
- service: `sshd`, Running, Automatic;
|
||||
- binary: `C:\Program Files\OpenSSH\sshd.exe`, version 10.0.0.0;
|
||||
- listen: `0.0.0.0:22` and `[::]:22`;
|
||||
- ED25519 host fingerprint:
|
||||
`SHA256:LgvblT9h+5KJFtkDq6JWGUyvgpiFyeL6cztVVMY0ZQM`;
|
||||
- public-key authentication: enabled;
|
||||
- password authentication: also enabled;
|
||||
- strict modes: enabled;
|
||||
- max authentication attempts: 6.
|
||||
|
||||
The Mac connection uses a key and strict pinning, but the server itself is not
|
||||
yet key-only. Disabling server password authentication is an explicit future
|
||||
hardening action, not a completed fact.
|
||||
|
||||
Mac SSH alias in `~/.ssh/config`:
|
||||
|
||||
```sshconfig
|
||||
Host mission-gpu
|
||||
HostName <worker-host>.local
|
||||
User <worker-user>
|
||||
IdentityFile ~/.ssh/id_ed25519
|
||||
IdentitiesOnly yes
|
||||
HostKeyAlias mission-gpu
|
||||
UserKnownHostsFile ~/.ssh/known_hosts_mission_core
|
||||
StrictHostKeyChecking yes
|
||||
ServerAliveInterval 15
|
||||
ServerAliveCountMax 3
|
||||
```
|
||||
|
||||
Connection and safe read-only smoke:
|
||||
|
||||
```bash
|
||||
ssh -o BatchMode=yes mission-gpu whoami
|
||||
ssh -o BatchMode=yes mission-gpu \
|
||||
'powershell.exe -NoProfile -NonInteractive -Command "$env:COMPUTERNAME"'
|
||||
```
|
||||
|
||||
The dedicated known-hosts entry matches the Windows ED25519 fingerprint above.
|
||||
No private key or password is stored in this repository or Ops.
|
||||
|
||||
## Windows network and firewall
|
||||
|
||||
Current physical Wi-Fi:
|
||||
|
||||
- SSID/profile: `<owner-lan-ssid>`;
|
||||
- interface: `Беспроводная сеть`;
|
||||
- category: Private;
|
||||
- IPv4: `<worker-lan-ip>/<owner-lan-prefix>`;
|
||||
- IPv4 connectivity: Internet.
|
||||
|
||||
VPN profile:
|
||||
|
||||
- name: `Сеть 5`;
|
||||
- interface: `hidemy.name VPN OpenVPN Adapter`;
|
||||
- category: Public;
|
||||
- IPv4: `<vpn-assigned-ip>/<vpn-prefix>`.
|
||||
|
||||
Windows Firewall is enabled for Private and Public profiles. The active custom
|
||||
SSH rule is:
|
||||
|
||||
- name: `MissionCore-SSH-From-Mac`;
|
||||
- display name: `MISSION CORE SSH from Mac`;
|
||||
- enabled, inbound allow, Private only;
|
||||
- interface: `Беспроводная сеть` only;
|
||||
- protocol/local port: TCP/22;
|
||||
- remote address: `LocalSubnet`;
|
||||
- local address: Any.
|
||||
|
||||
The broad MSI-created `OpenSSH SSH Server Preview (sshd)` inbound rule is
|
||||
disabled. The current custom rule is broader than the original single Mac IP
|
||||
because it admits the local subnet, but it remains confined to the Private Wi-Fi
|
||||
interface and does not apply to the Public VPN profile.
|
||||
|
||||
Triton ports 8000-8002 listen only on 127.0.0.1. No Windows firewall rule exposes
|
||||
them to the LAN. Consequently the Mac cannot yet call Triton directly; the
|
||||
accepted recorded path transfers bounded artifacts through SSH/SCP and executes
|
||||
the runner on Windows.
|
||||
|
||||
The current worker IPv4 `<worker-lan-ip>` previously appeared as a K1 target in
|
||||
historical TEST007 evidence. Before concurrent K1/worker LAN exposure, reserve
|
||||
non-conflicting addresses or prove topology separation. Do not expose Triton on
|
||||
this address until that conflict and the source-restricted firewall contract are
|
||||
reviewed.
|
||||
|
||||
## Current K1 Quick Connect state
|
||||
|
||||
The K1 plugin exposes three explicit local connection directions:
|
||||
|
||||
- Bridge/direct-LAN: K1 joins an existing shared network; physically accepted;
|
||||
- Direct Connect/controller-hotspot: K1 joins the controller's network;
|
||||
implemented/offline-verified, not physically accepted;
|
||||
- Quick Connect/device-AP: K1 becomes the AP and a prepared Mac joins it;
|
||||
physically accepted on the current host, retained as laboratory-only.
|
||||
|
||||
The reviewed LixelGO flow is:
|
||||
|
||||
1. keep one BLE connection open;
|
||||
2. write one reviewed 100-byte AP-enable frame (99 zero bytes plus final 1);
|
||||
3. poll `7f02` until the live status reports `WIFI_AP`, baseline address
|
||||
`192.168.56.1` and the AP-ready byte changes from 0 to nonzero;
|
||||
4. while BLE remains alive, use the native OS Wi-Fi API to scan exact SSID and
|
||||
associate;
|
||||
5. continue to K1 network/control only after association.
|
||||
|
||||
The earlier evidence session
|
||||
`.runtime/mission-core/evidence/sessions/20260719T173132Z_viewer_k1_ap_association`
|
||||
proved AP activation, AP-ready and native SSID discovery but stopped at the
|
||||
secure prompt. A later prepared-host session
|
||||
`.runtime/mission-core/evidence/sessions/20260719T220850Z_viewer_k1_ap_association`
|
||||
completed one CoreWLAN association and admitted `192.168.56.1`; the normal UI
|
||||
then completed control/acquisition. The operator disconnected afterward only to
|
||||
restore the external chat route.
|
||||
|
||||
Final credential findings:
|
||||
|
||||
- LixelGO persists `WiFiAP_SSID` and `WiFiAP_Password` in a per-device profile;
|
||||
- the Unity flow later passes those profile values to the native join path;
|
||||
- no password derivation from DeviceInfo, serial, BLE UUID or AP SSID was found;
|
||||
- official K1 `3.0.2` firmware contains one firmware-constant AP credential and
|
||||
constructs the SSID from device identity with a MAC fallback;
|
||||
- the reviewed BLE exchange enables the AP and reports readiness but exposes no
|
||||
observed credential response;
|
||||
- LixelGo login and the scanner AP are separate layers. The owner performed no
|
||||
explicit hardware-to-account pairing, which is consistent with the local
|
||||
firmware-defined credential, but does not prove universal account access;
|
||||
- the successful Mission Core run depended on a separate firmware import into
|
||||
this Mac's Keychain. A copied build on a clean Mac would fail before BLE.
|
||||
|
||||
The owner closed this branch. Do not download firmware during connection, seek
|
||||
the value from iPhone, hard-code it, or present machine-local Keychain state as
|
||||
portable automation. Keep the existing UI, implementation, Keychain/provider
|
||||
state and evidence intact. Continue through Bridge/direct-LAN.
|
||||
|
||||
## Current Mac repository and runtime state
|
||||
|
||||
Repository:
|
||||
`<mission-core-repository>`.
|
||||
|
||||
- branch: `main`;
|
||||
- HEAD: `ada2a55`;
|
||||
- `origin/main`: `75d2e5d`;
|
||||
- local Mission Core HTTP service: `127.0.0.1:8000`;
|
||||
- current health: service OK, one of one plugin runtimes ready;
|
||||
- current local server PID at 2026-07-20 closure refresh: 97887;
|
||||
- worker/perception commits are clean and local;
|
||||
- K1 Quick Connect changes are uncommitted and make the worktree dirty.
|
||||
|
||||
The dirty set spans K1 docs/profile/frontend, native CoreWLAN helper,
|
||||
BLE AP activation, host-network adapter and tests. It must not be reset or
|
||||
cleaned because it contains the current physical Quick Connect implementation
|
||||
and evidence-aligned fixes.
|
||||
|
||||
Latest validation of the current dirty tree:
|
||||
|
||||
- complete backend suite: passed;
|
||||
- Ruff: clean;
|
||||
- mypy: clean across 75 source files;
|
||||
- frontend: 140 unit tests passed;
|
||||
- TypeScript typecheck: clean;
|
||||
- production Vite build: clean;
|
||||
- Swift helper parse: clean;
|
||||
- `git diff --check`: clean.
|
||||
|
||||
## What is accepted, partial and not started
|
||||
|
||||
Accepted:
|
||||
|
||||
- physical K1 Bridge control lifecycle START/live/STOP/READY;
|
||||
- durable session catalog, point cloud and camera playback;
|
||||
- bounded content-addressed recorded camera job;
|
||||
- Windows digest verification and deterministic 56-frame decode;
|
||||
- pinned Triton/YOLOX-S inference on RTX 4090;
|
||||
- immutable content-addressed result and exact-repeat reuse;
|
||||
- validated optional Rerun camera/Boxes2D projection;
|
||||
- strict SSH host-key pinning and local-lab access path;
|
||||
- reproducible Windows worker repository and operator scripts.
|
||||
|
||||
Partial/laboratory-only:
|
||||
|
||||
- Quick Connect is physically accepted on one prepared Mac but has no clean-host
|
||||
credential bootstrap and is closed as a product route;
|
||||
- Windows is a reproducible lab worker but Triton is loopback-only and manually
|
||||
started;
|
||||
- SSH is source-restricted by firewall and the Mac uses a key, but sshd still
|
||||
permits passwords;
|
||||
- the worker result is recorded-only and camera-only;
|
||||
- GPU resource use is shared with unrelated Frigate/Ollama workloads.
|
||||
|
||||
Not accepted/not implemented:
|
||||
|
||||
- Direct Connect physical test;
|
||||
- second K1 or firmware portability matrix;
|
||||
- RTK, UGV, UAV, calibrated sensor time or camera/LiDAR extrinsics;
|
||||
- long TEST007 epoch throughput/resource qualification;
|
||||
- bounded live inference, queue/drop policy and recovery testing;
|
||||
- direct authenticated LAN worker transport;
|
||||
- Tailscale/routed worker transport and deny-by-default grants;
|
||||
- point-cloud inference, camera/LiDAR fusion, tracking, segmentation or free
|
||||
space;
|
||||
- actuator/autopilot integration, mission executor or safety authority;
|
||||
- production process supervision, operation journal, retention, encryption,
|
||||
replication and resource scheduler;
|
||||
- custom installer/node console/model marketplace, intentionally deferred.
|
||||
|
||||
## Recommended next gates in exact order
|
||||
|
||||
1. Continue K1 operation through the accepted Bridge/direct-LAN path. Preserve
|
||||
the prepared Quick Connect implementation and evidence without extending it.
|
||||
2. Commit the retained K1 mechanism/evidence/docs in logical commits when the
|
||||
owner chooses; do not claim clean-host portability.
|
||||
3. Qualify the 206-second TEST007 camera epoch on the same immutable model
|
||||
profile, recording transfer, decode, inference, GPU memory, queue depth and
|
||||
co-tenant effects.
|
||||
4. Define a direct authenticated worker endpoint that preserves the current
|
||||
`compute-job/result` schemas; reserve a non-conflicting worker address and add
|
||||
a source-restricted firewall rule before any LAN port exposure.
|
||||
5. Add bounded live fan-out from the sole Mac RTSP owner with explicit sampling,
|
||||
latest-wins/drop counters, deadlines, stale state and failure isolation.
|
||||
6. Kill/restart Triton, power off the worker and break transport while proving
|
||||
K1 control/raw archive continue and the UI reports degraded perception.
|
||||
7. Repeat the same endpoint contract through Tailscale; do not expose public
|
||||
Triton ports.
|
||||
8. Only after this evaluate tracking, segmentation/free-space and a LiDAR CPU
|
||||
processor. Keep every result versioned and non-safety until calibrated and
|
||||
separately accepted.
|
||||
9. Evaluate ROS 2/BehaviorTree only when an actual onboard computer,
|
||||
robot/autopilot and actuator/safety contract exist. Evaluate Zenoh only
|
||||
against the measured direct transport.
|
||||
|
||||
## Canonical local sources for the next chat
|
||||
|
||||
- `docs/10_EXTERNAL_PERCEPTION_WORKER.md` — job/result and Rerun contract;
|
||||
- `docs/adr/0014-bounded-external-perception-worker.md` — accepted architecture;
|
||||
- `docs/lab/005_FIRST_RECORDED_PERCEPTION_20260719.redacted.md` — physical
|
||||
recorded evidence;
|
||||
- `src/k1link/compute/jobs.py` — compute job creation/validation;
|
||||
- `src/k1link/compute/results.py` — result validation/Rerun projection inputs;
|
||||
- `docs/adr/0013-k1-local-connection-matrix.md` — K1 connection directions;
|
||||
- `src/k1link/device_plugins/xgrids_k1/ble/ap_activation.py` — reviewed AP
|
||||
activation session;
|
||||
- `src/k1link/host_network/wifi.py` — OS Wi-Fi profile boundary;
|
||||
- `plugins/xgrids-k1/macos/associate_wifi.swift` — CoreWLAN and Keychain helper;
|
||||
- this handoff — exact current machine/runtime/SSH/partial-acceptance snapshot.
|
||||
@@ -0,0 +1,123 @@
|
||||
# Lab 004 — K1 FW 3.0.2 Quick Connect mechanism and closure
|
||||
|
||||
- Date: 2026-07-20
|
||||
- Device scope: one owner-controlled LixelKity K1
|
||||
- Firmware scope: exact `3.0.2`
|
||||
- Host: owner-controlled Apple-silicon Mac
|
||||
- Safety: offline firmware analysis followed by one explicit BLE/AP/host-association cycle
|
||||
- Secret policy: no AP credential value or digest appears in this report, Git, argv,
|
||||
logs, manifests or fixtures
|
||||
|
||||
## Official artifact
|
||||
|
||||
The full K1 `3.0.2` archive was downloaded from the XGRIDS international
|
||||
[K1 support page](https://www.xgrids.com/intl/support/download?page=K1). The
|
||||
local private artifact was `1,252,252,754` bytes with SHA-256
|
||||
`e5830feae54d586cdeda2824495d08598920dc9cf4541059d01f0efeb858a750`.
|
||||
It remains under the ignored `sessions/firmware-analysis/` tree with mode
|
||||
`0600`.
|
||||
|
||||
The archive contains a Rockchip `RKFW`/`RKAF` image. The reviewed partitions
|
||||
were extracted read-only as sparse ext4 images:
|
||||
|
||||
- `rootfs.img`: 4,294,967,296 bytes, SHA-256
|
||||
`b6e565fa1dd37d539a34b6fe92457bba6e793ab8db0ca216e1fe73a6602b975e`;
|
||||
- `apps.img`: 230,801,408 bytes, SHA-256
|
||||
`c4acb8d60b2e84d56487e5a110b41806fb2f4aa2f4b3cf6f1bc4d8b704b7e59a`.
|
||||
|
||||
No firmware was uploaded to the device and no filesystem was mounted
|
||||
read-write.
|
||||
|
||||
## Recovered mechanism
|
||||
|
||||
The application partition contains
|
||||
`/system/scripts/wifi_ap/wifi_ap.sh`. The script deletes prior Wi-Fi profiles,
|
||||
creates NetworkManager connection `WIFI_AP`, configures WPA2/RSN/CCMP, assigns
|
||||
`192.168.56.1/24`, installs one firmware-constant PSK and raises the AP.
|
||||
|
||||
The stripped AArch64 `lixel_nman` service invokes that script for AP mode. Its
|
||||
reviewed control flow constructs the SSID as `XGR-` plus six device-identity
|
||||
characters; if the expected ten-character identity is unavailable it falls
|
||||
back to the final three MAC bytes formatted as six hexadecimal characters. The
|
||||
owner-controlled scanner's observed BLE name and AP SSID match this rule.
|
||||
|
||||
Therefore, for exact K1 firmware `3.0.2`:
|
||||
|
||||
- the AP credential is not supplied by the AP-enable BLE frame;
|
||||
- it is not recovered from an iPhone or synchronized Wi-Fi history;
|
||||
- it is not per-device material;
|
||||
- it is an exact-firmware credential profile defined by the scanner itself.
|
||||
|
||||
This does not authorize extrapolation to another K1 firmware or XGRIDS model.
|
||||
|
||||
The owner workflow is consistent with this separation. LixelGo required an
|
||||
application account, but the operator performed no explicit scanner-to-account
|
||||
pairing, ownership confirmation or per-device credential enrollment. The
|
||||
available evidence therefore supports treating login as application access and
|
||||
the AP credential as local firmware behavior. It does not prove that one
|
||||
account is authorized for every XGRIDS device, and no such broader claim is
|
||||
made.
|
||||
|
||||
## Provider implementation
|
||||
|
||||
Mission Core now identifies the source as
|
||||
`xgrids.lixelkity-k1.quick-connect.fw-3.0.2.official-firmware.v1`.
|
||||
The offline importer:
|
||||
|
||||
1. requires the exact reviewed archive SHA-256;
|
||||
2. streams the nested Rockchip image without extracting the 4.57-GB container;
|
||||
3. scans only the bounded apps-partition range;
|
||||
4. requires exactly one syntactically valid NetworkManager PSK declaration;
|
||||
5. writes the short-lived value to the host credential store through stdin;
|
||||
6. zeroizes the mutable Python buffer and emits only redacted provider metadata.
|
||||
|
||||
On macOS the firmware-scoped material lives in Keychain. Before any device
|
||||
write, the CoreWLAN helper materializes the selected SSID's opaque device
|
||||
profile entirely inside Keychain. The browser/API receives neither the source
|
||||
material nor a password. A missing source fails before AP activation.
|
||||
|
||||
This is a working laboratory provider, not a portable product bootstrap. A new
|
||||
host needs the provider material installed before Quick Connect. Windows and
|
||||
Linux would additionally need their own secure-store and Wi-Fi adapters.
|
||||
|
||||
## Physical acceptance
|
||||
|
||||
After the firmware-scoped provider was installed, one six-second BLE scan found
|
||||
exactly one expected K1 candidate. Mission Core then performed:
|
||||
|
||||
1. one reviewed 100-byte AP-enable write;
|
||||
2. one bounded wait for the canonical byte-51 AP-ready transition;
|
||||
3. one exact-SSID CoreWLAN association using the Keychain-only profile.
|
||||
|
||||
The operation succeeded and admitted the reviewed K1 AP address
|
||||
`192.168.56.1`. No credential was entered or displayed. The operator then
|
||||
manually disconnected the Mac from the scanner AP to preserve the external
|
||||
chat connection; that later host action does not invalidate the completed
|
||||
association acceptance.
|
||||
|
||||
## Result and closure decision
|
||||
|
||||
The device-side mechanism and the prepared-host transport are physically
|
||||
accepted: Mission Core can enable the K1 AP, observe canonical readiness,
|
||||
associate one configured Mac and continue into the normal local control path.
|
||||
The result does **not** establish a self-contained, transferable plugin. The
|
||||
successful Mac had first received the firmware-scoped material through a
|
||||
separate administrative import; copying the current application to a clean Mac
|
||||
would fail closed with `credential-source-unavailable` before the BLE write.
|
||||
|
||||
On 2026-07-20 the owner rejected all remaining bootstrap variants for the
|
||||
product path:
|
||||
|
||||
- downloading the 1.25-GB firmware archive during first connection;
|
||||
- extracting or enrolling the value manually from an iPhone;
|
||||
- embedding or deriving an unversioned password in application source;
|
||||
- presenting the machine-local Keychain setup as cross-host automation.
|
||||
|
||||
Quick Connect remains in the interface and its current Mac Keychain/provider
|
||||
state is retained. No evidence, credential material or private firmware files
|
||||
were deleted. Development of credential acquisition is closed without claiming
|
||||
that the password can be read from BLE: the reviewed BLE exchange contains AP
|
||||
activation and status, but no observed credential response. The preferred and
|
||||
accepted product topology is now Bridge/direct-LAN, where Mission Core sends
|
||||
operator-selected LAN credentials to K1 through the already reviewed 99-byte
|
||||
provisioning frame.
|
||||
Reference in New Issue
Block a user