feat(lab): stabilize autonomous TGS playback
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
# ADR 0043: Physical safety shadow and bounded operator visual
|
||||
|
||||
Date: 2026-08-27
|
||||
Status: autonomous transport slice implemented; 0.15 m challenger and measured acceptance incomplete
|
||||
|
||||
## Context
|
||||
|
||||
Mission Core has accepted a source-paced RF-DETR-native plus TRAVEL TGS
|
||||
recorded shadow on RAVNOVES00. The retained TGS result uses a `0.45 m` cell,
|
||||
`12 m` radius and four explicit states. It is useful operator evidence but is
|
||||
not a planner-authoritative terrain provider. The integrated acceptance joins
|
||||
TGS and the reference graph as evidence; TGS does not modify graph state.
|
||||
|
||||
The intended physical rover is not a lightweight laboratory fixture. The
|
||||
operator supplied the following planning facts, not yet independently measured:
|
||||
|
||||
- body `1.0 x 0.8 x 0.4 m`;
|
||||
- ground clearance `0.15 m`;
|
||||
- mass approximately `100 kg`;
|
||||
- one nominal `500 W` motor per side;
|
||||
- nominal speed `0.2778 m/s` (`1 km/h`);
|
||||
- maximum operating speed `0.5556 m/s` (`2 km/h`).
|
||||
|
||||
Controller, remote dead-man, braking behavior, physical E-stop, body/sensor
|
||||
extrinsics, center of gravity and negative-obstacle coverage are unavailable.
|
||||
Commands therefore remain disabled.
|
||||
|
||||
The current full TGS playback pack is about `88 MiB`: approximately `9.6 MiB`
|
||||
states, `77 MiB` z-bounds and `1.1 MiB` frame metadata. Holding the same
|
||||
`12 m` disk for all `4,489` frames would scale to roughly `0.8 GiB` at `0.15 m`
|
||||
and `1.8 GiB` at `0.10 m`, before richer terrain features, video, semantics and
|
||||
renderer allocations. Full-session high-resolution browser preload is not an
|
||||
admitted design for the current 18 GiB MacBook host.
|
||||
|
||||
## Decision
|
||||
|
||||
Recorded LAB and realtime perception are different runtime contours. Worker
|
||||
006 is reserved for realtime perception. A new recorded LAB is built by a
|
||||
bounded sequential offline builder on the MacBook, or admits an already sealed
|
||||
immutable artifact. The offline build may take longer than source duration. It
|
||||
must not become a hidden Worker job. An opened LAB never depends on Worker 006.
|
||||
|
||||
```text
|
||||
recorded LAB publication, Worker 006 absent
|
||||
recorded source -> local sequential offline build
|
||||
-> seal immutable result + binary LOD tracks
|
||||
|
|
||||
v
|
||||
local/CAS artifact store
|
||||
|
|
||||
Worker 006 remains absent
|
||||
|
|
||||
v
|
||||
canonical local backend, read-only
|
||||
|
|
||||
v
|
||||
MacBook LAB CAMERA + 3D + PLAN
|
||||
|
||||
separate future realtime contour
|
||||
K1 -> Worker 006 -> live world-state/planner shadow
|
||||
```
|
||||
|
||||
Opening, seeking, looping and visually inspecting a sealed LAB must perform
|
||||
zero requests to Worker 006. If the worker, its host, Docker or the network path
|
||||
to it is unavailable, a locally present sealed result opens unchanged. If a
|
||||
manifest-declared local object is absent or corrupt, LAB fails with an explicit
|
||||
artifact error; it does not start compute, scan worker results or silently
|
||||
rebuild evidence. This preserves ADR 0033.
|
||||
|
||||
Publishing a new LAB also performs zero Worker requests. Slow local preparation
|
||||
is acceptable, but it is explicit and bounded: build first, seal second, open
|
||||
third. Historical LAB artifacts that were originally computed on Worker 006
|
||||
remain valid after sealing because replay depends only on their immutable
|
||||
artifacts; they do not justify a Worker dependency for new LABs.
|
||||
|
||||
Visual performance may never change a safety state, erase unknown space or
|
||||
reduce the resolution used by the safety consumer. Conversely, the MacBook does
|
||||
not need every cell of every high-resolution frame resident at once in order to
|
||||
provide a complete operator explanation.
|
||||
|
||||
The retained `0.45 m` M49T5 profile and sealed result remain immutable. A new
|
||||
physical-safety challenger may evaluate `0.15 m` and `0.10 m` cells without
|
||||
rewriting that baseline. The first candidate resolution is `0.15 m`; `0.10 m`
|
||||
is admitted only if LiDAR density improves the evidence. Worker compute
|
||||
acceptance and autonomous LAB viewer acceptance are measured separately.
|
||||
|
||||
The operator transport uses binary typed arrays. It must not serialize one JSON
|
||||
object per cell or expand binary frames into nested JavaScript objects before
|
||||
updating GPU instances. Recorded high-resolution inspection reads only sealed
|
||||
local binary chunks and active-frame detail, not a full-session high-resolution
|
||||
preload.
|
||||
|
||||
The proposed spatial chunk is `32` source frames (`3.2 s` at `10 Hz`). Before
|
||||
the spatial scene declares itself ready, it may preload the first two chunks,
|
||||
or `6.4 s`, from the local artifact. The browser retains at most three chunks
|
||||
(`9.6 s`), normally previous/current/next, and prefetches one forward chunk.
|
||||
A backward seek loads the target and next chunk from the same sealed artifact.
|
||||
This bounded startup delay is preferable to either Worker dependency or a
|
||||
multi-gigabyte browser preload.
|
||||
|
||||
## Implemented autonomous transport slice
|
||||
|
||||
The first executable transport slice is now present without creating a new LAB
|
||||
surface or transport clock:
|
||||
|
||||
- `m49_physical_safety_playback.py` is a local, sequential, filesystem-only
|
||||
sealer. It accepts an already sealed source, verifies its declared hashes,
|
||||
and writes immutable binary chunks atomically. It contains no Worker client,
|
||||
job submission or network path.
|
||||
- `m49_physical_safety_playback_api.py` exposes only the configured local
|
||||
artifact root. Manifest, shared centers, frame catalog and every requested
|
||||
chunk are hash-verified. Corruption returns an explicit artifact failure.
|
||||
- `m49PhysicalSafetyPlayback.ts` rejects non-canonical URLs, verifies byte
|
||||
length and SHA-256 in the browser, prebuffers two chunks, retains no more than
|
||||
three and loads target plus next on seek.
|
||||
- the existing M49 evidence composition resolves this transport by exact
|
||||
`source_result_id`. If no chunked derivative has been published, it may still
|
||||
read the old sealed local full pack; neither path uses Worker 006.
|
||||
|
||||
A real transport canary was generated from the accepted immutable `0.45 m`
|
||||
M49T5 result without recomputing TGS or changing that source result. The canary
|
||||
identity is
|
||||
`m49-physical-safety-playback-0d0e41a995a902a4701935a79655d93f2f1898806f8fa82ebbd207129f111d69`.
|
||||
It contains all `4,489` frames and `2,244` cells in `141` chunks. A normal
|
||||
32-frame chunk is `646,300` bytes; two startup chunks are about `1.23 MiB` and
|
||||
three spatial chunks are about `1.85 MiB`, plus the shared centers and frame
|
||||
catalog. This is the transport canary only. It is not a `0.15 m` safety result
|
||||
and no upsampled baseline is presented as new evidence.
|
||||
|
||||
The `0.15 m` shape, fail-closed missing-sample rule, bounded seek behavior and
|
||||
zero-Worker URL policy are covered with synthetic contract fixtures. A real
|
||||
`0.15 m` challenger still requires the local sequential terrain computation
|
||||
and a separately sealed result.
|
||||
|
||||
The visual uses explicit LOD:
|
||||
|
||||
- `0-4 m`: `0.15 m` near-field cells;
|
||||
- `4-8 m`: `0.30 m` explanatory cells;
|
||||
- `8-12 m`: `0.45 m` context cells;
|
||||
- pause/anchor inspection: full available active-frame resolution.
|
||||
|
||||
LOD changes only presentation. The sealed result retains the full candidate
|
||||
evidence needed to reproduce its decisions; a future realtime worker separately
|
||||
retains the full live safety grid across the configured safety radius.
|
||||
|
||||
The metric Three.js scene retains instanced meshes and all evidence layers. It
|
||||
renders on evidence, camera interaction, resize or layer changes. It does not
|
||||
run a permanent animation loop while idle. The scene exposes render-pass time,
|
||||
draw calls, triangles, cell count and pixel ratio in the operator surface.
|
||||
|
||||
## Acceptance budget
|
||||
|
||||
Acceptance is measured on the named 14-inch 2023 MacBook Pro with 18 GiB RAM,
|
||||
with recorded video, semantic overlay and TGS 3D/PLAN evidence available:
|
||||
|
||||
- source pace: `10 Hz` without evidence loss;
|
||||
- main-thread frame preparation p95 at most `10 ms`;
|
||||
- CPU-side WebGL render submission p95 target `16.7 ms`, hard maximum
|
||||
`33.3 ms`; GPU completion requires a separate supported timer query;
|
||||
- evidence-to-visible p95 at most `100 ms`;
|
||||
- incremental visual resident memory at most `256 MiB`;
|
||||
- post-warmup growth at most `32 MiB` over a ten-minute soak;
|
||||
- zero browser long tasks above `50 ms` during source-paced playback;
|
||||
- zero WebGL context losses;
|
||||
- zero Worker 006 requests while opening, seeking or playing a LAB;
|
||||
- zero Worker 006 requests while building a new recorded LAB;
|
||||
- the sealed LAB opens with Worker 006 unavailable;
|
||||
- idle metric scene performs no continuous render loop.
|
||||
|
||||
These are proposed thresholds until a canonical browser run emits a sealed
|
||||
performance ledger. Passing them does not grant navigation, safety or actuation
|
||||
authority.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The operator keeps the full explanatory visual instead of receiving a
|
||||
stripped-down safety UI.
|
||||
- High-resolution terrain work does not turn the MacBook into a second
|
||||
perception worker.
|
||||
- Historical LAB remains usable during Worker maintenance, Docker failure or
|
||||
loss of the Worker network path.
|
||||
- Evidence identity and safety decisions remain independent of display LOD.
|
||||
- The next implementation boundary is a packed, chunked terrain contract plus
|
||||
footprint-aware states; no physical connection or command path is introduced.
|
||||
- Physical authority remains blocked by controller/E-stop, measured braking,
|
||||
vehicle geometry, sensor extrinsics and negative-obstacle coverage.
|
||||
Reference in New Issue
Block a user