diff --git a/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md b/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md index cc5902a..02f6208 100644 --- a/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md +++ b/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md @@ -1,8 +1,8 @@ # Observatory: четыре этапа создания полного real-time Perception-профиля -Дата: 2026-09-01; обновлено 2026-09-02 13:09 МСК. **Этап 1 закрыт; этап 2 в работе. Четвёртый инкремент: persistent H.264 decoder принимает отдельные fMP4-фрагменты без готового MP4, следующих кадров и EOF.** BGR совпадает с прежним декодером на 128/128 кадрах. Бинарный ingress + decoder отдельно проверены на 103 событиях / 32 кадрах. Это ещё **не** полный граф на новом входе. Последнее полное измерение не меняется: 128/128, p95/p99 124.98/136.12 ms, fresh 76/128, real-time qualification НЕ выдана. Далее causal sensor / supervised decoder → full graph bridge, затем controller/network и standalone image; этапы 3–4 не начаты. +Дата: 2026-09-01; обновлено 2026-09-02 13:55 МСК. **Этап 1 закрыт; этап 2 в работе. Пятый инкремент: бинарный вход → supervised H.264 decoder → causal sensors → тот же полный DDRNet/RF-DETR/LiDAR/motion/TGS/costmap/policy граф.** Выполнены 128/128 кадров исходного 1× потока, без drops и готового MP4; 384/384 входных события. Новый полный p95/p99 — 161.974/191.806 ms, fresh 74/128: real-time qualification НЕ выдана. BGR/маски/детекции/треки/raw costmap exact 128/128; strict raw parity остаётся открытой из-за двух последних разрядов float в расстояниях. Далее воспроизводимость/хвост задержек и controller/network/standalone image; этапы 3–4 не начаты. -Последние изменения: `350366b` — общий byte-only MP4 parser и source-neutral decoder; `f102712` — Worker parity/decoded-ingress probes. 246 focused tests PASS, отдельный повтор session/decoder — 55 PASS; Ruff/mypy PASS. В CPU-only 128-frame 1× пробе p95 нового decoder снизился с 19.927 до 11.156 ms после отказа от повторного demux/probing; это сравнение двух новых decoder-вариантов, не ускорение полного профиля. IPC + decode: 103/103 exact raw events, 32/32 exact BGR, peak input 5,727,751 bytes, остаток 0; первый кадр за 3.071 s до End. Модели не запускались, services/clocks не менялись; product batch path пока не переключён. +Последние изменения: `221e429` — bounded decoder RPC, общий causal sensor window, атомарный handoff памяти и полный binary pilot. 271 focused tests PASS, Ruff/format/mypy PASS. CPU oracle до GPU и после review — 32/32 exact sensor bundles; synthetic decoder timeout прекращает поток и освобождает ресурсы. Полный прогон: peak accounted input 8,883,895 bytes, остаток 0; первый результат через 583 ms, 126/128 результатов до End. Один профиль, GPU-модели последовательно; четыре Mission Core сервиса восстановлены, Ollama/Frigate не включались. Auto clocks, quotas/модели не менялись; product batch path пока не переключён. Текущий evidence: [отчёт этапа 1](../experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md), [ADR 0049](adr/0049-stream-first-perception-profiles.md), [candidate manifest](../config/perception/k1-perception-ddrnet39-rfdetr-tgs-prototype-v1.json). Запрет full-source preload закреплён в новом контракте; старый batch materializer пока не удалён и продуктовый путь не переключён. @@ -143,7 +143,7 @@ IPC/сети, копирований и оркестрации. Вычислит ## Этап 2 — Самостоятельный Docker с полным потоковым вычислением -**Текущий статус, 13:09 МСК:** в работе. Lifecycle/scheduler/per-cell expiry проверены полным пилотом; binary ingress и persistent fragment decoder — отдельными CPU-only probes. Новый вход уже выдаёт точные BGR-кадры, но causal cloud/pose binding и передача decoded bundles тому же модельному графу ещё не соединены. Нужны supervised native decoder child, общий ownership/scratch budget при handoff и новый full-graph parity/timing. Production admission/recovery, continuous GPU inventory/envelope monitoring, network ingress и standalone image ещё не закрыты. GO на этап 3 пока нет. +**Текущий статус, 13:55 МСК:** в работе. Binary ingress, supervised native decoder, causal cloud/pose cut и общий ownership/scratch budget соединены с полным графом и измерены на Worker: 128/128 без drops. Результаты выходят до source End; `/source.mp4` не монтируется. Не пройдены p95/p99 125 ms и strict bitwise parity двух geometry floats; допуски задним числом не менялись. Production admission/recovery, continuous GPU inventory/envelope monitoring, network ingress и standalone image ещё не закрыты. GO на этап 3 пока нет. **Цель:** один самостоятельный контейнер принимает поток и реально рассчитывает DDRNet, детекции, расстояния, motion, TGS/costmap и policy-shadow; ничего не дорисовывается из старых LAB. @@ -224,6 +224,8 @@ EoMT — семейство ViT-моделей сегментации изобр ## Progress +- 2026-09-02 13:55 МСК: `221e429` — supervised decoder RPC (250 ms deadline, 1 MiB input / 1,440,000-byte caller-owned BGR), общий causal sensor cache и atomic reservation → mailbox transfer. CPU oracle 32/32 exact до полного запуска и после review; native-hang injection учтён как failed cameras 0/1/2, child/lease/input освобождены. Полный binary 1×: 384/384 событий, 128/128 сцен без drops, BGR/segmentation/proposals/tracks/threats/material/raw costmap exact; два range_m отличаются на 1.388e-17 m, strict parity=false. p95/p99 161.974/191.806 ms; 76 available sensor pairs, 74 fresh scenes, seq106/107 дополнительно stale. 271 focused tests, Ruff/format/mypy PASS. Evidence `.runtime/perception-stage2-binary-graph-worker-20260902T1335MSK/manifest.json`: 161 artifacts, SHA-256 `e224de4e9f2c5fd419fe0fb0b9be6e01ec267628568e104795ae211ec803bce4`. Один GPU-прогон, без изменений clocks/quotas/models; сервисы восстановлены. Standalone/network/product cutover не заявлены. + - 2026-09-02 10:16 МСК: `097e450` — six-layer shared ABI и read-only Worker operating-envelope checker. Два sequential PyTorch auto-clock runs, 128/128 без drops; финальный C p95/p99 122.11/141.40 ms. 27 свежих полных scenes, 52 missing sensor pairs, 49 stale costmaps; пять дополнительных отказов после receipt aging. Функциональные model/geometry/motion/TGS/material outputs точны к reference 128/128. 142 focused tests + 42 adjacent regressions PASS, 1 исторический evidence-root test FAIL из-за существующих symlinks в соседний checkout; данные и guard не менялись. Этап 1 закрыт как engineering baseline; этап 2 допущен, не реализован. Evidence manifest `3b0a2ad32f6b60d3da48a4bcafdf6e11bc91209abc9d1f65da54b0eb36c52d45`. - 2026-09-01 18:15 UTC: локальный обзор backend/frontend/Worker и двух документов выполнен в предыдущей итерации; ограничения и отсутствие свежей Worker-проверки перенесены в этот план. @@ -264,11 +266,14 @@ EoMT — семейство ViT-моделей сегментации изобр ## Surprises / открытые вопросы +- 2026-09-02 13:55 МСК: строгая сверка нового full binary run обнаружила только два raw-расхождения: seq13 observation3 и seq29 observation2, `metric_geometry.range_m`, абсолютная разница 1.3877787807814457e-17 m. Никаких округлений или нового tolerance ради PASS не внесено. Причина численной недетерминированности ещё не воспроизведена; input BGR и 32-frame sensor oracle exact, projection/association algorithm не менялся. Следующий parity check должен объяснить это, а не скрыть в comparator. +- В том же запуске auto memory clocks переходят 10,251 → 405–810 MHz. По последнему 0.5-s sample перед receipt high/low cohorts имеют p95 88.269/172.079 ms (39/89 кадров). Это корреляция внутри одного прогона, не controlled A/B и не отдельная qualification. Общий p95/p99 161.974/191.806 ms остаётся FAIL. Decoder p95/p99 10.871/11.606 ms, RPC+bundle 18.053/38.991 ms, очередь 44.284/84.492 ms, DDRNet RPC 73.068/77.479 ms; CPU throttled delta=0. Нельзя приписать всю разницу с предыдущими 124.98/136.12 ms новому транспорту или сделать вывод об исчерпании 24 GiB VRAM. + - 2026-09-02 13:09 МСК: decoder-инкремент `350366b` / `f102712` принят отдельно от full graph. Evidence `.runtime/perception-stage2-decoded-ingress-worker-20260902T1310MSK/manifest.json`, 43 artifacts, SHA-256 `612295eabbc8f203ad9b037a69ac9cf97b2df3134b087d9e51a9786738423f2f`; связан с отдельными 128-frame demux/direct/reference manifests. Все 128 BGR совпадают; 32-camera binary canary и negative EOF освобождают весь input budget. Четыре Mission Core сервиса не останавливались; модели и GPU clocks не менялись. - Повторный `av.open(init + fragment)` не является полнофайловым барьером, но повторяет stream probing на каждом кадре. Принят узкий проверяемый ISO-BMFF layout → один AVCC sample → persistent codec; NumPy импортируется до readiness. p95 первого потокового варианта 19.927 ms → 11.156 ms. Это bounded CPU A/B без модели; не вычитать выигрыш из старого full-graph p99. Codec/parser не импортируют session store или materializer; archive API сохраняет прежние exception contracts. Иной codec/layout, B-frames, multi-sample, пропуск DTS или не-keyframe start требуют нового явно квалифицированного профиля/epoch, а не скрытого fallback. -- Новый decoder не делает весь bridge готовым. Следом — causal sensor window на момент camera release, supervised CPU child с bounded RPC и передача владения decoded bundle в общий mailbox, затем тот же полный граф. Не подмешивать готовый MP4 или старые masks/geometry. Реальная калибровка в decode/hash probe не используется: совпадение BGR не доказывает calibration admission или field quality. +- Исторический decode-only probe 13:09 не доказывал causal scene/calibration admission. В инкременте 13:55 supervised child, causal cut и full-graph handoff реализованы с прежней реальной калибровкой полного профиля; готовые MP4/masks/geometry не подмешиваются. Multi-recording calibration admission и field quality по-прежнему не проверены. - 2026-09-02 12:00 МСК: истечение lease и освобождение GPU разделены. После crash OS lock свободен, но durable `active` не допускает новый запуск. Recovery намеренно отсутствует до trusted resource-release proof; нельзя удалять production marker ради продолжения. В пробах удалены только два заведомо временных experiment-owned volume после сохранения записей и остановки всех probe containers. @@ -311,6 +316,6 @@ EoMT — семейство ViT-моделей сегментации изобр ## Outcomes / retrospective -Этап 1 остаётся завершённым engineering baseline. Этап 2 имеет общий scheduler, per-cell expiry, subprocess lifecycle/lease, bounded raw binary IPC и persistent fragment decoder. Новый decoder воспроизвёл 128 BGR без отличий и без future-fragment/EOF barrier; combined IPC/decoder — 32 BGR и 103 raw events. Общий byte budget учитывает raw, scratch и retained codec metadata; normal/error cleanup оставляет 0 bytes. Native codec RSS измеряется отдельно, а его изоляция внутри полного GPU runtime ещё нужна. Следующий шаг соединяет causal sensors и supervised decoder с тем же полным графом и повторяет timing/parity. Прежний full-graph p99 136.12 ms остаётся FAIL 125 ms. Network/gRPC/authentication, production controller/recovery/inventory и standalone image не приняты; старый batch/registry/UI не переключены. GPU-прогонов, full suite и image build в этом инкременте не было; сервис 8000 сохранён, Ollama/Frigate выключены. +Этап 1 остаётся завершённым engineering baseline. На этапе 2 общий lifecycle/scheduler и binary input уже питают полный граф через supervised incremental decoder и causal sensor window. Полный MP4 не передаётся, исходный 1× clock сохранён; 128/128 кадров и 384/384 событий учтены, pending ≤2, peak input <16 MiB, normal/failure cleanup освобождает память и lease. Инкремент подтверждает исполнение, а не qualification: p95/p99 161.974/191.806 ms, fresh 74/128, два float-различия strict raw parity остаются открытыми. Далее отдельно воспроизвести численный drift и уменьшать decoder/IPC/queue/CPU-tail latency при измеренном operating envelope. Network/gRPC/authentication, production controller/recovery/inventory и standalone image не приняты; старый batch/registry/UI не переключены. Один полный Worker GPU pilot плюс CPU checks; Mac только focused tests, без full suite/build. Сервис 8000 сохранён, четыре Mission Core сервиса восстановлены, Ollama/Frigate выключены. После этапа 4 здесь будут перечислены digest самостоятельного полного образа, измеренные статусы и ошибки по recordings, реально проверенные source/hardware/config комбинации, состояние сохранённого EoMT-варианта и оставшиеся physical-live/quality/vehicle-integration ограничения. Готовый Docker и готовая автономия не отождествляются. diff --git a/docs/adr/0049-stream-first-perception-profiles.md b/docs/adr/0049-stream-first-perception-profiles.md index 379dc4d..c4acb37 100644 --- a/docs/adr/0049-stream-first-perception-profiles.md +++ b/docs/adr/0049-stream-first-perception-profiles.md @@ -1,6 +1,7 @@ # ADR 0049 — Stream-first full perception profiles -Date: 2026-09-01. Status: stage-1 contract candidate; not a runtime cutover. +Date: 2026-09-01; updated 2026-09-02 13:55 MSK. Status: stage-1 engineering +baseline complete; stage-2 binary full-graph prototype, not a product runtime cutover. Execution order remains the four stages in [the ExecPlan](../OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md). @@ -189,6 +190,59 @@ Next: preserve the existing causal sensor cut at camera release, connect decoded bundles to the same full graph, then repeat full-profile parity/timing. The last full-profile p95/p99 remains 124.98/136.12 ms, not this decoder's timing. +Stage-2 full binary graph increment, 2026-09-02 13:55 MSK (`221e429`): +the preceding decoder-only boundary is now connected to the existing full graph. +The recording adapter alone reads bounded current fMP4 fragments and normalized +map point/pose rows. It emits original timestamps at 1× through the existing +binary socket ABI; the consumer and decoder receive neither source paths nor +recording length. The diagnostic container still mounts source/code/weights and +a private pinned PyAV target: this is not standalone packaging or a network test. + +Native decoding runs in a lifecycle-owned CPU child with a 1-GiB address-space +limit. POSIX pipe RPC reserves header scratch, accepts ≤1 MiB input and writes +exactly 1,440,000 BGR bytes into the caller's pre-reserved buffer. A 250-ms request +deadline, malformed reply or lost lease terminates the stream; no implicit retry +across predictive codec state. Process/native memory remains under container +limits, separately from the 16-MiB application payload budget. + +`streaming_sensors` owns the existing causal selection rules. Its rolling and +fresh caches are each bounded by 64,000 points/64 increments; camera arrival +freezes the original-time cut before decode, never selecting future pose/points. +The legacy pilot delegates to the same selection rules. A separate CPU oracle +compares the old producer's complete points/rolling/times/pose/lineage bundles. +`admit_reserved` transfers the decoded allocation atomically to the common +mailbox; rejection retains caller ownership until buffers are discarded. +The global two-pending limit and active-input protection remain unchanged. + +Worker evidence: 384/384 input events, 128/128 full graph outputs, no drops, +126 outputs before source End; first result 583 ms. BGR, masks, proposals, +tracks, threats, material and raw TGS costmap match the reference on 128/128. +Two `metric_geometry.range_m` values differ by 1.3877787807814457e-17 m +(seq13/observation3 and seq29/observation2): **strict raw parity remains false**. +No rounding/tolerance was added; the numerical cause remains unreproduced. +The geometry distance-estimator definition and all thresholds are unchanged. + +Full p95/p99 161.974/191.806 ms FAIL the unchanged 125-ms target. Available +camera/sensor pairs remain 76/128; 74 scenes are fresh at receipt, with seq106/107 +additionally expiring. Auto GPU memory clocks fall from 10,251 to 405–810 MHz; +this correlates with longer DDRNet/queue times, but is not a controlled transport +A/B. Peak input 8,883,895 bytes; remaining input/children/lease zero after stop. +VRAM peak 2,367 MiB is not GPU utilization or a compute-capacity percentage. +Normal 32-frame CPU oracles and a synthetic hung-decoder cleanup probe pass. + +The full GPU sample preserves its exact measured code snapshot. Subsequent +review bounds finite-check scratch, closes sockets/cache after constructor or +pre-start failure, and removes CPU-harness heartbeat shutdown noise; those three +files pass a separate Worker CPU oracle, not a second GPU performance sample. +271 focused tests, Ruff/format and five-module mypy pass. Four temporarily stopped +Mission Core services are restored; Ollama/Frigate remain exited/restart=no. +Manifest: 161 artifacts, SHA-256 +`e224de4e9f2c5fd419fe0fb0b9be6e01ec267628568e104795ae211ec803bce4`, +`.runtime/perception-stage2-binary-graph-worker-20260902T1335MSK/manifest.json`. +Next: explain numerical reproducibility, measure/tune remaining pipeline tails, +then complete controller/network/standalone boundaries within stage 2. +No quality, physical-live, vehicle-control or real-time qualification is granted. + Open → validate bounded metadata/claim → warm models → Ready → start the replay clock → observations and incremental scenes → stop/drain bounded state → close and asynchronously seal the immutable receipt. A live source already producing diff --git a/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md b/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md index f718b6a..7612aa9 100644 --- a/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md +++ b/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md @@ -1563,3 +1563,158 @@ raw parity / timing на новом binary input, без `/source.mp4`. decoder-выигрыш из этих значений и не объявлять real-time qualification. Network/controller/recovery/inventory, standalone image и product cutover остаются открытыми. Этап 2 продолжается; этапы 3–4 не начаты; actuation=false. + +## 2026-09-02 13:55 МСК — этап 2, инкремент 5: binary input → полный граф + +Код: `221e429`. Эксперимент: +`perception-stage2-binary-graph-worker-20260902T1335MSK`. +Это первый полный pilot на новом бинарном ingress с incremental H.264 decoder, +а не decoder-only timing и не повтор старого producer с готовым MP4. +Источник — тот же ограниченный 128-camera prefix RAVNOVES00, исходный clock 1×. + +### Реализация и неизменные границы + +- Recording adapter читает только текущие fMP4 fragments и инкременты прежнего + normalized map cloud/pose archive. Init ≤64 KiB, fragment ≤1 MiB; проверяются + path confinement, declared size и SHA текущего fragment. Нет полного source + copy/hash/predecode, конкатенации камеры или ожидания EOF перед результатом. + Существующий normalized archive — recording input, не новая реализация + физического vendor adapter. Source adapter пока находится в diagnostic container. +- Binary ABI v2 связывает поток с StreamStart/lease. Синхронный consumer до RPC + фиксирует camera-time causal cut, pose и rolling/fresh increments. Будущие + sensor events не подставляются. Прежние age/skew/preroll правила перенесены + в общий `streaming_sensors`; legacy pilot использует их же. +- Native PyAV18 decoder — отдельный CPU child под существующим supervisor, + address-space limit 1 GiB, CUDA_VISIBLE_DEVICES пуст. Bounded POSIX RPC: + header ≤4 KiB, input ≤1 MiB, ровно 1,440,000 bytes caller-owned BGR, + deadline 250 ms. Timeout/invalid response/lost lease прекращают поток; + повтор через повреждённое codec state запрещён. +- Header scratch 65,536 bytes и bounded sensor cache 3,216,384 bytes резервируются + заранее. Rolling и fresh ограничены каждый 64k points / 64 events. BGR и + concatenated sensor arrays резервируются **до** allocation; atomic handoff + переносит ownership в mailbox без double charge/неучтённого окна. + При rejection ticket остаётся у caller до удаления его buffers. + Raw reassembly, sensor retention, decoded pending/active учитываются совместно; + native allocations дополнительно ограничены контейнером, а не Python счётчиком. +- Полученный bundle идёт в прежний `GpuStage/JointGraph`: DDRNet-39 GOOSE eager + PyTorch reference + RF-DETR native608×800, online geometry/distances, + temporal/motion, TRAVEL TGS, per-cell aging, coarse materials/advisory policy. + Weights/thresholds/preprocess/TTL 250 ms не менялись. GPU inference последовательный, + overlap разрешён только с CPU tail; pending ≤2, input ≤16 MiB. + +Image SHA `664824aa25de1db178f177d67a81b01541a938b479812b9383ddbf03f6b59dbe`, +profile SHA `e1c244e3be8b4880cb4b4d7e96a88feada69773dbb16f5c9a17ef663030138f3`. +8 CPU / 8 GiB, pids 256, shm 256 MiB, read-only/network-none; квоты и GPU clocks/ +power limit не менялись. PyAV и модели — явные read-only mounts, не standalone. +Новый private code snapshot создан копированием прежнего **code-only** пакета +и текущих overrides; старые code/evidence пакеты не изменялись. `/source.mp4` +в команде/mounts нового прогона отсутствует. Measured source hashes сохранены. + +### Проверки и результат полного прогона + +CPU-only oracle до GPU: 32/32 точных bundles против отдельного выполнения +прежнего producer — points, rolling points/times, pose, binding, lineage. +Старый producer в oracle получает synthetic image, модели не запускаются и его +результаты не питают новый граф. Synthetic decoder hang после init превышает +250-ms RPC deadline: ingress failed, cameras 0/1/2 accounted failed, live children=0, +lease/input освобождены, residual=0. Никакой будущий кадр не выдаётся вместо зависшего. + +| Полный binary 1× запуск | Результат | +| --- | --- | +| Camera released / completed / dropped / unaccounted | 128 / 128 / 0 / 0 | +| Input observations | 384/384: init 1 + camera 128 + LiDAR 124 + pose 131 | +| Wire bytes / incomplete observations | 17,194,165 / 0 | +| Первый результат от старта source clock | 583.149 ms | +| Результатов до source End | 126/128; два последних штатно дренируются | +| Full source-due → local receiver p50/p95/p99/max | 91.936 / 161.974 / 191.806 / 209.423 ms | +| Source release lag p95/p99/max | 2.375 / 6.263 / 8.823 ms | +| Warmup / stop | 7.073 s / 4.074 s | +| Peak pending / peak accounted input / residual | 1 / 8,883,895 bytes / 0 | +| GPU direct / buffered handoffs | 127 / 1 | +| Peak VRAM / container RAM | 2,367 MiB / 3,314.648 MiB | +| Backlog growth first 8 → last 8 | 4.494 ms, gate ≤25 ms PASS | +| Available causal sensor pairs / fresh complete at receipt | 76 / 74 из 128 | + +Исходные 52 missing/stale sensor pairs сохранились. Дополнительно seq106/107 +истекли по geometry/motion/costmap/policy к receipt. TTL не увеличен, unknown +не заменён разрешающим состоянием. Source reader прошёл 241/4598 pose rows, +229/4570 point batches, 545,590/10,751,258 xyz rows, включая bounded skipped +prefix/preroll; полного прохода по записи нет. У receiver source duration unknown. +Покадровый `source_release_lag_ms=null`: он неизвестен consumer и не подменяется +временем получения. Реальный source lag измерен отдельно и используется gate. + +### Parity и отдельные отрицательные gates + +BGR к pinned OpenCV reference — **128/128 exact**. К прежнему raw full-graph +reference (`perception-parity-pacing-worker-20260902T0911MSK/reference-locked-128-e`) +совпали 128/128 segmentation SHA, proposals, tracks, threats, range-estimator +metadata, costmap material, sensor binding/lineage и hash raw TGS costmap states. +Effective costmap/policy после TTL оцениваются отдельно, не объявляются raw parity. + +`observations` exact лишь **126/128**. Найдены ровно два leaf-различия: + +- seq13 / observation3 / metric_geometry.range_m: + `0.07335595296280842` против `0.07335595296280843`; +- seq29 / observation2 / metric_geometry.range_m: + `0.05775996681929105` против `0.05775996681929106`. + +В обоих случаях delta = −1.3877787807814457e-17 m. Это не изменение определения +distance estimator, threshold или source point ownership. Причина численного +drift ещё не воспроизведена; не приписывать её SIMD/alignment без отдельного +контрольного опыта. **Strict raw parity=false**: не добавлен post-hoc tolerance, +не округлены результаты и не переписан reference. Execution/complete accounting +приняты как evidence, но полная bitwise parity и real-time gates не закрыты. + +### Где задержка + +| Участок, ms | p95 | p99 | +| --- | ---: | ---: | +| Native decode | 10.871 | 11.606 | +| Decoder RPC + bundle assembly | 18.053 | 38.991 | +| Очередь перед GPU | 44.284 | 84.492 | +| DDRNet RPC | 73.068 | 77.479 | +| RF-DETR | 17.776 | 19.476 | +| Online surface | 26.958 | 39.927 | +| CPU tail → receiver | 53.305 | 72.736 | + +Эти percentiles не складываются: участки пересекаются и хвосты приходятся на +разные кадры. Auto memory clocks снова падают 10,251→405–810 MHz, SM 2610→525–930. +По последнему 0.5-s telemetry sample перед receipt high/low cohorts (39/89 кадров) +имеют p95 full latency 88.269/172.079 ms; это **корреляция**, не controlled A/B. +CPU throttled delta=0. Предыдущий полный auto run 124.98/136.12 ms нельзя считать +контролем чистой цены нового транспорта. Не доказаны ни исчерпание 24 GiB VRAM, +ни «5% вычислительной нагрузки»; измеренный peak VRAM не равен GPU utilization. +Общий p95/p99 нового запуска остаётся FAIL 125 ms, без отбора удобной части прогона. + +### Review, cleanup и evidence + +После полного замера добавлены cleanup при constructor/pre-start failure, +блоки finite-validation по 4096 scalar values для bounded scratch и тихое +завершение CPU-harness heartbeat. Exact reviewed файлы отдельно прошли Worker +CPU-only 32-frame oracle: 32/32 exact, residual 0. Это не второй GPU timing sample; +полный прогон привязан к своему сохранённому code snapshot. Первоначальный +CPU-canary shutdown traceback и ошибочный PowerShell postcheck (array treated +as one object) сохранены; повторные проверки исправлены и PASS. + +271 focused tests PASS; Ruff check/format 13 files и mypy 5 common modules PASS. +Mac без моделей, full suite, image build и вторых web-серверов. Один GPU pilot; +четыре согласованных Mission Core сервиса временно остановлены и восстановлены, +Triton первым и ready 200 перед остальными. Ollama/Frigate exited/restart=no. +Owned children, probe containers и временный experiment lease volume удалены +после сохранения terminal owner record; исходники/модели/recordings не удалены. +Triton 200, Mac 8000=200, 8765 closed; GPU auto P8, 978 MiB, 450 W на финальной проверке. + +Manifest: `.runtime/perception-stage2-binary-graph-worker-20260902T1335MSK/manifest.json`, +**161 artifacts**, SHA-256 +`e224de4e9f2c5fd419fe0fb0b9be6e01ec267628568e104795ae211ec803bce4`. +Включены команды, UTC/monotonic времена, before/quiesced/after inventory, +exact probe snapshot, Worker code inventory, raw scenes/timings, CPU/negative +probes, analysis с leaf diff и final checks. 114 measured probe files verified; +реальные inputs и веса в Git не добавлены. + +**Далее в этапе 2:** отдельно воспроизвести/объяснить два numerical differences, +продолжить измеряемую оптимизацию decoder/IPC/queue/CPU-tail при контролируемом +operating envelope; затем production controller/admission/recovery/inventory, +network ingress/egress и самостоятельный image. Старые product LAB/registry/UI +не переключены. Несколько/полная запись, physical source, field quality и +actuation не проверены. Этапы 3–4 не начаты; real-time qualification=false.