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

152 lines
9.2 KiB
Markdown

# 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.