Files
NODEDC_MISSION_CORE/docs/audits/2026-09-19-planning-runtime-boundaries.md
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.2 KiB

Planning: startup ownership, mixed ingress and onboard dependency closure

Date: 2026-09-19. Ops: MISSIONCOR-81; related architecture: MISSIONCOR-76/79.

Scope and source identity

Implemented after the owner's approval of the second source-review findings. Checkout: NODEDC_MISSION_CORE_m5_observatory, branch main, HEAD be58d58. The working tree already contained substantial uncommitted implementation; unrelated changes were preserved. HEAD alone does not identify this patch.

No scanner command, new acquisition, vehicle command, network reconfiguration, onboard installation, Docker workload or physical replay was performed. The running canonical8000 process was not restarted for these source tests.

Changes

  • src/k1link/missions/live_tests.py: startup owns a rollback stack until the planning thread actually starts. A busy source, report error, thread creation error or thread-start error cannot strand the shared compute lock. A successfully opened derived consumer is closed on startup failure. The response is prepared before ownership transfer, so response serialization cannot release a live worker's resources. Failed starts remain terminal in memory; report persistence is best-effort during storage failure. Executor construction is now inside the worker's protected lifetime. Shutdown/consumer-close/report failures still pass through compute-lock release and clear accepted live geometry.
  • src/k1link/device_plugins/xgrids_k1/planning_live.py and src/k1link/sessions/live_planning.py: one take returns one receipt. Auxiliary camera modalities become payload-free kind="ignored" events retaining their identity, sequence and receipt timestamps. None is reserved for no receipt. The stationary loop already skips non-geometric kinds, so it cannot interpret a camera receipt as a drained prefix queue. There is no internal draining loop that could delay cancellation or freshness checks under camera traffic.
  • plugins/xgrids-k1/packaging/runtime-files.json: includes the newly required stdlib-only sessions/live_planning.py ABI module. No mission algorithm, local planning adapter or local LAB composition was added to the onboard payload.
  • Tests: new test_planning_failure_boundaries.py, new test_planning_recording_ingress.py, and additional boundary assertions in test_k1_installer.py.

No search radius, point budget, GICP threshold, ambiguity gate, wall deadline, fresh-window rule, camera codec/queue policy or device-authority fence was relaxed.

Regression evidence

The initial ten-case failure suite had nine failing cases against the old code. It now passes; two subsequent cases cover partial report replacement/recovery and the shared recorded ingress, giving twelve new cases in total.

Checks include failed persist, Thread construction/start, source open, executor construction, worker persistence and consumer close; resource release and retry; terminal restoration after a partially committed report; both camera modalities; and the ten-second stationary prefix with two seconds of processing backlog. The backlog fixture uses the production adapter to produce the camera receipt and the production stationary loop, with a fake clock and no native search.

The shared-ingress test uses real MQTT and camera writers, real facade generation checks/observers, the same LivePerceptionIngress, the production decoder and a PlanningLiveTests owner. It proves raw-first MQTT delivery, committed camera fragments before derived delivery, preserved event order, rejection of old MQTT producer/camera epochs, and continued append-only recording after planning cancel. Producer admission is explicitly a fixture, not physical proof; camera box bytes are synthetic and are not a video-quality acceptance.

The isolated onboard test copies only the declared runtime payload/resources, imports NodeBridge outside the Core checkout, reads idle state and closes it. It verifies the ABI is available and the local planning adapter/mission worker are not imported. No .deb release or board installation was made.

Validation

  • 184 focused backend tests passed, 0 failures/errors/skips, 22.615 seconds. Suites: new boundary/shared-ingress tests, planning live, stationary bootstrap, causal replay, entry acquisition, mission registration, LaunchAgent, K1 installer excluding private-release build, camera gateway/archive and MQTT capture. XML: /private/tmp/mission-core-source-review.TfGl1a/implementation-tests.xml.
  • Five additional acquisition-lifecycle tests passed: first authoritative cloud before camera activation, stale published cloud rejection, later-frame retry, STOP priority during initial camera startup, and session-clock sealing order.
  • Ruff check/format passed for changed Python owners/tests; git diff --check passed.
  • Canonical8000 remained operational, plugin runtime1/1. Read-only K1 state had no acquisition, idle camera with recording.active=false, no connection intent or control session. The existing Interactive LaunchAgent plan has identical current/desired SHA256 5d7a58122c016f8021fede27d1b21891ee20238fc38c281e5b33574ff8204e3f.
  • Local tests ran sequentially. Memory-pressure readout was39% free; swap readout was4783.88MiB used, lower than the earlier4831.88MiB snapshot. No Docker workload was started; the existing privileged vmnetd helper is not a running Docker VM.

Corrected source fingerprints (SHA256)

File SHA256
src/k1link/missions/live_tests.py 58d44e7d7f0582feb2cdfdd62ed72b6d86f772da25ea3eb7d4a1c196ab9bf6e6
src/k1link/device_plugins/xgrids_k1/planning_live.py 82c5cf912502604479d4e5329a5d20130e37e6243d3f20645a280dd01f598610
src/k1link/sessions/live_planning.py c242d4e6b42e6e59b81deafb5edfd25d9e3f301cba7376d0fa196ec4b3189dd1
plugins/xgrids-k1/packaging/runtime-files.json 39770adc8cdb7ff26cc7780a47024baf528508e8f2624fc98fafb02a4ce375dc

Decision and remaining acceptance

The three source-review defects are corrected and covered. This is not proof that they caused physical005; its damaged H.264 and unresolved STOP evidence remain unchanged. Existing scheduling evidence is separate from this patch.

The owner subsequently confirmed K1 was off and recording had ended. The controlled reload and runtime acceptance below supersede the source-only handoff. This owner confirmation does not fabricate a physical STOP receipt for the earlier005 run.

The tests cover the relevant boundaries compositionally. They do not replace a single full acquisition/publisher/RTSP/browser-MSE acceptance or a physical start with clean video, complete search and three fresh validation windows. A successful synthetic cancellation does not constitute an authoritative physical STOP.

The accepted-entry policy remains5m, not a proven10m capture radius. Arbitrary route-position relocalization, full chassis pose/mount calibration, route following, new obstacles and vehicle control remain separate stages.

Canonical8000 reload and bounded field-test handoff

Before reload: PID83156; K1 phase/source_mode idle, producer_generation0, acquisition null, camera recording false and producer absent. The active planning record remained the completed historical005 run 47dc5323-5d2c-4743-a13f-b4f837cf9fea; no calculation was in progress.

The versioned scripts/manage_mission_core_launch_agent.py applied the freshly reviewed, SHA-gated plan for the same WorkingDirectory. Current and desired plist hashes were identical (5d7a58122c016f8021fede27d1b21891ee20238fc38c281e5b33574ff8204e3f): no configuration, environment, scheduling class or source directory changed. The script retained its private plist backup and accepted health after reload.

New PID91643, runtime start 2026-09-19T17:38:39.562133Z, runtime identity snapshot-runtime-c5019daa9e912b67c31aa28f49453dd2. Health operational, plugin1/1, one listener on8000 and none on8765. K1/camera remained idle with no recording. The four corrected source fingerprints above still matched. This is a fresh interpreter started from the verified corrected working tree, not a hot-patch claim.

Actual browser check: LAB → Планировщик opens the saved «JA-SADOVAYA · проверка 30 м» result, renders the Rerun point clouds and inspector; reference JA-SADOVAYA-001, historical query JA-SADOVAYA-002, reference length30.01m. Opening it did not start capture, fitting or a new planning profile. The historical result is not presented as fresh tracking. No UI/build changes were made.

The owner can now travel to the reference location for a short controlled physical verification, not an accepted autonomous mission. Arm the new planning profile only on arrival, close to the start of the selected reference segment; do not promise10m acquisition or an arbitrary route-position start. Use a new recording identity. First remain stationary until fresh tracking is established and camera video is healthy. Only then make a short manually controlled pass. If initialization stops, tracking is lost or video is corrupt, remain/stop on site, finish recording through the normal controls and retain the evidence; do not wait for an automatic second search or repeatedly restart capture. Full physical camera/localization acceptance and authoritative stop/archive remain uncompleted.