Files
NODEDC_MISSION_CORE/docs/audits/2026-09-19-stationary-bootstrap.md
T
DCCONSTRUCTIONS e515ab1b8c feat(planning): consolidate recorded-route localization and spatial scene
Preserve the completed teach-and-repeat laboratory stage: reference preparation, cascaded acquisition, local tracking and recovery, recording lifecycle, replay qualification, and persistent Rerun scene controls. Document the open grid-picking regression and Rerun upgrade contract. No autonomous driving or loop-closure optimization is claimed.
2026-09-21 08:47:19 +03:00

9.3 KiB
Raw Blame History

Stationary prior → fresh validation → temporal tracking

Objective and frozen protocol

Connect the previously qualified stationary snapshot initializer to current-data validation. The owner accepts a startup wait. This increment checks the complete causal chain on the existing independent A/B recordings, without another physical scan, vehicle commands, product UI changes or activation in the live profile.

The immutable pre-execution manifest is in private data_dir/missions/causal-replays/20260919-stationary-bootstrap-002. Preparation -001 was not executed: a formatting-only script correction preceded preparation -002. No numerical attempt is omitted.

Inputs reuse the preceding recovery experiment's A forward 39.926109 m / 52,965 points, B's raw transport and actual receipt clock, and the frozen negative A 130155 m geometry. A is 20260911T085226Z_viewer_live; B is the independent 20260911T134352Z_viewer_live. Input hashes are verified before and after each run. No previous fitted B matrix, overlap mask or later travel heading seeds the search. Metadata's one pending event supplies only its due time until delivery.

Policy stationary-fresh-bootstrap/v1:

  1. Collect the first 10 s incrementally. Recorded motion must be ≤0.10 m; require continuity and ≥300 retained points. Each event is checked, including poses that the spatial buffer would otherwise thin. Prefix provenance is bounded.
  2. Freeze only when every due prefix event has arrived. Run the existing stationary-entry/v1 search: 108 hypotheses, complete-search/support/ambiguity gates, 25 s soft / 30 s process deadline, no change to local GICP thresholds.
  3. A successful old fit is only a provisional seed. It contributes zero temporal confirmations, no live matrix and no green/tracking authority. Its source timestamp remains unchanged. Maximum search wall time is 30 s; maximum prior source age 40 s; there is one initialization attempt and one seed trial.
  4. Start a new empty buffer after the search actually completes. Exclude every receipt at or before completion, including backlog delivered late. Require at least 2 s of new cloud observations. Trial must complete within the prior's 10 s lifetime. Input continues at original 1× pace during calculation.
  5. Fit current cloud using the provisional seed, then apply unchanged causal-consistency/v1: source age ≤8 s, three consistent candidates, ≤0.5 m position change and ≤5° rotation change. Subsequent fits are at least 5 s apart. Observation sequence IDs in successive fit windows are disjoint; the buffer resets at each submitted sample, while new receipts continue accumulating.
  6. Reject bad/partial/expired initialization, failed fresh fit, session/generation change, source-order regression, fresh-phase receipt gap, silence and input end. Never retry a failed provisional seed or fall back to future travel heading. A late worker result cannot reactivate an ended run.

The original B receipt gap occurs while initialization is running. One gap before readiness may retain an old same-session transform as a hypothesis only, subject to the separate fresh checks above. It cannot bypass CausalTracking's old-segment rejection. Any gap after readiness discards the one-shot prior and tracking. Session/generation identity is enforced; subtle unreported SLAM frame resets are not verified (slam_reset_verified=false). This distinction is an experimental assumption, not a deployment claim.

Implementation

  • missions/stationary_entry.py: shared incremental bounded prefix collector; old snapshot entry point wraps the same collector.
  • missions/stationary_bootstrap.py: provisional state, source/freshness fences, one-shot trial, disjoint fresh windows and existing temporal gate.
  • missions/stationary_replay.py: bounded 1× orchestration, one isolated numerical worker, concurrent input delivery, stage provenance, historical-only late jobs.
  • scripts/check_stationary_bootstrap.py: frozen sources/code/expected outcomes, sequential positive and wrong-region controls, immutable exact source copies.
  • tests/test_stationary_bootstrap.py: authority, identity, timeout, gap, partial-search and observation-fence cases.

No change to the running travel-entry product profile, frontend, capture ownership, device protocols or old saved experiments.

Results

Both complete 1× probes passed their frozen expectations. Darwin arm64, Python 3.12.13, small_gicp 1.0.1; single isolated CPU worker, sequential runs.

Positive: 2026-09-19 12:26:30.52712:27:33.648 UTC; monotonic start 838468170195291. Delivered 974 events in 63.122767 s, 40.037509 m; maximum delivery lag 0.154619 s. The original 9.972693 s receipt gap and 10.406525 m recorded displacement remain present. No event is replayed early. The selected fit windows lie inside the reference's 39.926109 m extent; the final pose crosses 40 m and ends the probe without another fit.

The initial prefix remains 168 events / 8,227 retained points, maximum recorded motion 0.0051505 m. It is frozen at 10.008045 s without a B travel heading. All 108 hypotheses complete in 20.980390 s (worker wall 21.158549 s), producing the same geometric candidate as the preceding snapshot: overlap 89.8145%, RMSE 0.170424 m. This run's timing is a single measurement, not a guaranteed startup deadline. At completion the newest included cloud is 21.482298 s old: its original time is retained and it is not admitted to the live gate.

Stage Seconds from first receipt Current-data age Temporal streak
Provisional seed ready 31.166594 old prefix; no live admission 0
First fresh fit 33.807565 0.371100 s 1
Second fresh fit 38.757844 0.372068 s 2
Tracking established 43.823601 0.658728 s 3
Further fresh fits 48.835069 / 53.928964 / 59.181734 0.453103 / 0.475792 / 0.308357 s 4 / 5 / 6
Input ends, state cleared 63.122606 0

Six fresh windows use disjoint observation IDs, all strictly after initial search completion; each cloud time is ≤request time≤completion time. Their B distances are 14.624 / 19.049 / 23.296 / 27.295 / 31.905 / 36.019 m. Fit worker wall times are 0.2242750.328083 s including process overhead; overlaps 98.19899.260%, inlier surface RMSE 0.1487570.154952 m. These are geometric consistency metrics, not independent position errors. Disjoint receipt IDs are not independent SLAM maps; overlapping real surfaces are expected.

Negative A 130155 m: 12:27:58.10812:29:01.231 UTC; monotonic start 838555753631833. Same 974 B events / 40.037509 m, maximum delivery lag 0.145273 s. All 108 hypotheses finish in 14.933964 s; no-admissible-entry, rejected at 25.165285 s. No prior, fresh candidate or tracking appears; no automatic travel-heading fallback. One wrong area is not an estimate of false-positive frequency across a location catalogue.

Validation and retained evidence

65 focused tests passed in 3.34 s: stationary bootstrap, preceding stationary prefix and receipt-loss tests, entry acquisition, causal replay, live planning, projects, registration and archived viewer replay. Ruff and git diff --check passed. Existing Starlette/httpx deprecation warning remains.

Verified input hashes before/after runs, frozen executed-source hashes, all 36 positive and 6 negative artifacts, source-time ordering, disjoint fresh windows, zero authority from the old fit and cleared state at end. The private directory contains the protocol manifest, exact code, per-step inputs/results/provenance, receipt delivery logs, test output, summary and seal. Geometry stays outside Git.

SHA-256:

  • Positive report: d9cbd3059531a1c26d7101a11d0d9a73c7234dfe360eae55d19ae27956a72452
  • Negative report: 723d7654d49a326a783fcc81332bb67cfe0dce5323195ca2a286de634e6ba9c9
  • Seal: ffd380e20f46b2c70d195702e86c769b592f2259be01e2aca6806e45cdf293ef

Memory checks before runs showed free-memory percentage 54% then 51%; swap 4522.31 → 4370.31 MB. Docker VM was not started. Temporary worker processes exited between runs. The canonical server was left running; no duplicate backend or product restart was needed.

Decision and next boundary

On this independent recording pair the complete sequence now works causally: stationary prefix → bounded search → non-authoritative prior → current cloud confirmation → temporally consistent tracking. Full readiness is about 44 s from first receipt in this probe, not the 21 s search duration or 31 s prior time. The existing B moved while calculation ran; this is not a new physical test of a rover holding still throughout readiness.

This research protocol remains uninstalled in the product's live planning profile; its default is still travel-entry. Next, connect this same bootstrap state machine to the existing live profile and recording lifecycle, preserve camera/scene controls, expose preparation/confirmation/readiness through existing product states, and test teardown/reconnection without another scan. A separate choice is required for route entry assumptions and trustworthy frame-reset signalling. Then qualify different initial positions/headings and the actual board, and perform a physical validation pass. No unrestricted start, navigation accuracy, obstacle avoidance, permissible speed or autonomous driving is accepted. The 5 s diagnostic cadence and 8 s freshness bound are not a motion-control loop.