docs(perception): record recoverable input policy and decoder continuity proof

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 15:33:53 +03:00
parent c31c46caa5
commit 03a7e730ae
3 changed files with 180 additions and 7 deletions
@@ -1,8 +1,9 @@
# ADR 0049 — Stream-first full perception profiles
Date: 2026-09-01; updated 2026-09-02 14:52 MSK. Status: stage-1 engineering
baseline complete; stage-2 binary graph and controller-readiness primitives,
not a product runtime cutover or a connected production inventory collector.
Date: 2026-09-01; updated 2026-09-02 15:30 MSK. Status: stage-1 engineering
baseline complete; stage-2 binary graph, readiness and resumable-input primitives.
Full-graph recovery adapter, production inventory collector and product cutover
are not implemented by the latest CPU-only continuity proof.
Execution order remains the four stages in
[the ExecPlan](../OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md).
@@ -101,6 +102,77 @@ explicit byte bound is required. No duplicate new scanner feed is introduced.
## Time and lifecycle
Owner clarification and stage-2 continuity increment, 2026-09-02 15:30
(`c31c46c`): temporary input/network loss must not unload the resident models.
Unknown/stale GPU telemetry is not proof of a competing owner. The desired
response is waiting and resynchronization; verified owner conflict, actual
local lease loss, child/model/decoder failure and explicit cancellation remain
terminal. This supersedes the blanket terminal-readiness TARGET below; previous
terminal fault probes are retained as historical evidence of their opt-in mode.
Two lifetimes are explicit. The resident activation keeps its original
`StreamStart`, local Worker lease and lease generation. Reconnecting input gets
a new `StreamStart.epoch_id`, bound by existing wire v2 on every packet/result;
acquisition session/generation remains independently checked. A network/GCS
heartbeat is not the local ownership heartbeat. The trusted resident controller
continues renewing its own lease while the input waits. No second profile may
claim the GPU during that wait, and telemetry alone cannot renew/release a lease.
`StreamingLifecycle(recover_input=True, source_clock_ns=...)` requires a trusted
source-to-local-clock mapping and, if monitoring is configured, a
`WorkerReadinessMonitor(recoverable=True)`. Both choices belong in the sealed
effective config. Their defaults preserve the historical one-shot diagnostic;
the current full PilotController/BinaryGraphBridge has not been switched. This
compatibility default is not the final product's desired outage policy.
The input phases are active, waiting and synchronizing. Resident GraphState may
remain RUNNING while input is waiting; that means the processes remain loaded,
not that results or actuation are ready. EOF without End, an IPC read deadline,
connection loss or a declared/source-sequence gap pauses the enabled adapter.
Pending input is discarded; active borrowed buffers remain owned until their
callback drains, and its old result cannot pass the epoch/phase gate. A new
connection waits for the old receiver, active callbacks and mailbox-owned work
to drain. No unbounded queue, replay catch-up, future evidence or new model
process is introduced. Explicit End terminates the source; Cancel remains a
real cancellation. Malformed data and actual decoder failure are not relabelled
as a recoverable transport outage. External network error handling remains an
unqualified adapter boundary, not proved by the IPC socket tests.
Resume requires a new init and a successfully decoded random-access H.264 frame,
fresh pose/points from the new epoch, and a temporal-state reset. The measured
decoder resets codec references/DTS inside the same child process; sensor-window
reset retains its bounded allocation but clears rolling state. `ResumeEvidence`
must be derived by the trusted profile adapter, not accepted as a client Boolean.
Every timestamp is at/after reconnect cutoff and no later than the camera;
camera age ≤250 ms, pose/newest-points age ≤100 ms, oldest-points age ≤250 ms and
pose/points skew ≤100 ms. The lifecycle rechecks evidence after reset and cannot
resume if another pause arrived meanwhile. Full graph tracking/motion/TGS/costmap
reset and CPU-consumer old-result disposal are required next, not yet proved by
the diagnostic callback. Replay source time must keep advancing at 1× through
the outage; the CPU fixture proves this only with a synthetic tick source.
Recoverable readiness maps expired/missing inventory, incomplete warmup and
strict-envelope performance unavailability to waiting, not process destruction.
Fresh facts permit beginning resynchronization, not automatic reuse of the old
epoch. Confirmed wrong owner/generation/worker/image/config, known competing GPU
clients and invalid trusted clock/snapshot ordering still fence the activation.
Labelled performance experiments keep their recorded violations and remain
unqualified. The runtime does not manipulate GPU clocks, other services or a
vehicle. Eventual onboard stop/hold, stale-command rejection and motion-resume
policy are independent future safety gates; restored inference is not permission
to move, and GCS heartbeat is not proof of fresh perception.
375 focused tests pass, including repeated reconnects, stale input/results,
pause during reset, telemetry recovery and retained hard-fault fencing. Worker
CPU-only proof: three epochs, 150-ms and 2.2-s outages, unchanged decoder/sentinel
PIDs, identical BGR 3/3, peak input 5,275,461 bytes and complete cleanup. It uses
one real H.264 fragment and synthetic timestamps/pose/points; the sentinel is not
a GPU model, and temporal reset is a diagnostic fixture. No full-graph recovery,
new GPU latency, real inventory collector, external network or standalone-image
qualification follows. Evidence: 85 artifacts, 73 verified code hashes;
`.runtime/perception-stage2-continuity-worker-20260902T1518MSK/manifest.json`,
SHA-256 `fbd327d129c88caa13b7183b1ae2c4767e877a6f5472c0f430875cfd7401ed46`.
Stage-2 controller-readiness increment, 2026-09-02 14:52 (`92625bf`):
`WorkerReadinessMonitor` consumes existing `WorkerOperatingEnvelope` and
`WorkerSnapshot` under the same lifecycle lock as admission. No host I/O occurs