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

128 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# K1 stationary start: runtime scheduling correction
Date: 2026-09-19. Mission Core Ops: MISSIONCOR-81; camera baseline: MISSIONCOR-3.
Follow-up to `2026-09-19-physical-start-005.md`. The owner confirmed K1 was off
before the canonical local service was restarted. No scanner command was issued.
## Finding and correction
The canonical8000 LaunchAgent declared `ProcessType=Background`; launchctl also
reported `spawn type = background (5)` and the Python service had priority4.
The localization child inherits this resource class. Apple's launchd manual
describes Background as applying CPU and I/O resource limits. This is unsuitable
for the application's operator-requested camera ingestion and bounded initial
localization. An HTTP request does not provide the XPC activity needed to promote
an Adaptive job. Source: installed `launchd.plist(5)` and
[Apple's launchd manual](https://github.com/apple-oss-distributions/launchd/blob/main/man/launchd.plist.5).
Reproducing the *same frozen005 input* under `/usr/sbin/taskpolicy -b`, with no
camera or generated load, again exhausted the unchanged deadline. This identifies
an independently reproducible scheduling cause of the slowdown. It does not prove
the origin of the corrupt H.264 already present in the physical005 archive.
The versioned `src/k1link/local_service_launchd.py` now declares Interactive, the
ordinary app resource class. It does not set realtime priority, alter system
resource limits, or change algorithms. The pre-apply plist comparison found
exactly one changed key, `ProcessType`; environment, arguments, repository,
watchdog, process-group ownership, data and camera/map configuration are identical.
`scripts/manage_mission_core_launch_agent.py` applied the hash-gated plan, made a
private backup, reloaded the exact label and accepted `/api/health`. Its automatic
rollback remained available. Previous plist SHA-256:
`6b651aedb54236f76bf062a2319d9223f0b00f7d264451b3bbaccbee0896e065`;
new SHA-256:
`5d7a58122c016f8021fede27d1b21891ee20238fc38c281e5b33574ff8204e3f`.
Post-apply launchctl: `spawn type = interactive (4)`; one Python listener on8000,
none on8765; health operational. UI entry asset: `/assets/app-DKxsidxk.js`.
## Evidence and bounded combined replay
Private evidence root, outside Git:
`NODEDC_MISSION_CORE/.runtime/mission-core/missions/diagnostics/20260919-runtime-scheduling-fix`.
It retains the background reproduction, applied plan, runtime acceptance,
test/build logs, UI fixture acceptance and `combined-replay-02`.
The prior005 sealed capture is unchanged. Input identity:
`b72e1f202a04c5455aa10d2907a3912bfb3fbf76b84a079746b23aaa0cc0f9eb`.
| Execution | Entry seeds | Search wall time | Decision |
| --- | ---: | ---: | --- |
| Physical005, before correction | 54/108 | 25.4795 s | reject incomplete search |
| Exact saved input, Background, no camera | 38/108 | 25.8272 s | reject incomplete search |
| Prior ordinary isolated child | 108/108 | 16.0428 s | complete candidate search |
| Ordinary combined archive replay | 108/108 | 14.1715 s | complete candidate search |
The combined run replays the first65seconds of physical005 MQTT at original
receipt intervals through `LivePerceptionIngress`, the production K1 planning
decoder, `PlanningLiveTests`, bounded entry child, three disjoint fresh validation
windows and Rerun scene generation every2seconds. Search process CPU time was
14.1691seconds, close to wall time. Full108-seed coverage, five supporting seeds,
ambiguity rejection, original25second search/30second child deadlines and fresh
validation thresholds remain unchanged. Overlap96.3758% and inlier RMSE0.151095m
match the previously observed candidate; these are not measured position accuracy.
In parallel, the helper `scripts/planning_archive_camera.py` feeds the clean
canonical camera baseline A, session `20260822T105904Z_viewer_live`, through the
real fMP4 parser, per-segment durable archive, bounded preview queue and a local
FFmpeg decoder. The helper has no RTSP or hardware producer. All70 retained media
fragments keep their recorded intervals and exact bytes; no generated load or
accelerated playback is used. The baseline's legacy index does not contain an
init receipt timestamp: init is delivered with the first media receipt, so no
initialization-latency claim is made.
Camera commits span0.182–24.601seconds and overlap the entry search. All70 media
fragments and init were archived and delivered byte-for-byte;70 frames decoded;
decoder warning/error log empty; no slow-reader retirement. Producer/decoder
children, parser/preview threads and planning leases were released. The helper
adds a camera acceptance report to the existing replay manifest and source seal.
Fresh validation reached tracking at37.591seconds after archive playback started.
Further fresh results stayed tracking until the65second retained prefix ended;
the service then correctly revoked live authority. No prior, stale sample or
completed run was promoted to live tracking. All combined acceptance checks passed.
This is stronger than the earlier cloud-only replay, but is **not** full physical
acceptance: the ordinary acquisition authority/publisher, K1 RTSP encoder/network
and browser MSE are not exercised by the replay. Clean baseline video cannot
retroactively repair or certify physical005's corrupt archive.
## Operator presentation
Initial unsuccessful binding now says «Поиск остановлен» and explicitly instructs
the operator to stop the device/recording and start a new study for another attempt.
It has no continuing busy indicator. The production K1 status component wraps
the instruction, uses the canonical11px token and keeps it visible below960px.
Device authority, stop precedence, lost-after-established tracking, stale-data
rejection and session identity fences remain unchanged.
Changed owners: `stationary_live.py`, `planningPresentation.ts`,
`K1SpatialSession.tsx/.css`, the duplicate responsive rule in plugin `styles.css`.
Entry diagnostics now also retain process CPU time in `entry_acquisition.py`;
the decision still uses wall time.
## Validation and limitations
- 48 focused backend tests passed: LaunchAgent plan/apply, entry acquisition,
stationary bootstrap and live planning.
- 55 existing camera gateway/archive regression tests passed.
- Architecture4/4, full TypeScript check, frontend853/853 and production build
passed sequentially. Build retains the existing large-chunk warning.
- Ruff passed for changed Python owners and replay helpers.
- Actual8000 UI opened a retained aligned project and its inspector; ordinary
and expanded window states work. Close-button behavior works. The existing
floating inspector did not close on Escape; that unrelated behavior is retained
as a follow-up, not represented as a passed check.
- The terminal status was rendered from the production React component and built
stylesheet in an explicitly labelled offline fixture at1280px and800px. Full
instruction visible; no ellipsis or overflow; desktop scroll height equals
client height45px. This is presentation QA, not a fabricated live session.
The temporary fixture route/tab was removed and viewport override reset.
- No Docker VM or stress test was started. Memory pressure remained healthy
(48–49% reported free), swap did not grow during qualification. Temporary
children exited. The canonical8000 service remains running.
Next gate: qualify the remaining acquisition/MSE boundaries without changing
scanner state, then perform a short physical stationary start with continuous
camera and fresh tracking. A long field walk and autonomous vehicle authority
are not accepted by this result. Preserve physical005's unresolved STOP evidence;
the owner's report that the scanner is off is not a fabricated READY receipt.