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:
DCCONSTRUCTIONS
2026-07-23 00:23:28 +03:00
parent ada2a55ee6
commit b53d6d5a45
221 changed files with 55923 additions and 1357 deletions
+2 -2
View File
@@ -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 |
+115 -6
View File
@@ -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
+47 -37
View File
@@ -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
+381
View File
@@ -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.421857292484.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 100212 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.23937.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.
+453
View File
@@ -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 100124 ms and
BEiT took 244312 ms. The combined 365412 ms is only about 2.42.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 p05p95
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 89 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 P0P4 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 510 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`.
+105 -20
View File
@@ -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.