diff --git a/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md b/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md index c3e5f8e..b01b1dc 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 09:40 МСК. Цель прежняя: переносимые полные профили и снижение задержек всей цепочки. A/B подтвердил значимый вклад автоматического снижения частот GPU/VRAM. При временно фиксированных штатных частотах полный source-paced граф дал p99 70.46/67.77 ms (TensorRT, два повтора) и 77.02 ms (pinned PyTorch), 128/128 без drops. После возврата auto p99 снова 144.88 ms. Исправлена ничья material votes → unknown/NO_GO. Default остаётся PyTorch; TensorRT numeric/material parity не пройдена. Этап 1 частично выполнен; этапы 2–4 не начаты. Bounded Worker-local latency PASS не равен full-session/network/vehicle qualification; static-obstacle и coarse hard_surface остаются достаточным scope. +Дата: 2026-09-01; обновлено 2026-09-02 10:16 МСК. **Этап 1 закрыт как состав, контракты и технический baseline; GO на инженерную реализацию этапа 2. Real-time qualification НЕ выдана.** Цель прежняя: переносимые полные профили и снижение задержек всей цепочки. Финальный six-layer PyTorch pilot: 128/128 без drops, p95/p99 122.11/141.40 ms в auto clock mode. Полностью свежи 27/128 scenes: 52 source gaps, 49 stale costmaps. Пять сцен истекли между publisher guard и receipt и получили NO_GO. Этапы 2–4 ещё не выполнены; standalone/network/full-session/vehicle proof отсутствуют. Default остаётся PyTorch; TensorRT numeric/material parity не пройдена. -Последнее изменение, 2026-09-02 09:11–09:40 МСК: `c6c42c2` добавляет fail-closed material voting, bounded numerical/cell attribution и read-only clock telemetry. Установлено различие TF32 arithmetic; на спорном пикселе sigmoid округляет scores до ничьей, а старая cell voting ничья давала ALLOW по порядку IDs. Ни arithmetic, ни model/score/freshness thresholds не менялись. A/B выполнен по явному разрешению владельца, частоты восстановлены после каждого запуска, постоянная host policy не установлена. CPU quota не троттлила, лимиты Docker не расширялись; GPU peak 1.82 GiB для TensorRT и 2.30 GiB для PyTorch. Следующий шаг — воспроизводимый Worker operating envelope и layered-freshness ABI, затем общий streaming runtime; не новая модель и не автономия. +Последнее изменение: `097e450` вводит общий six-layer freshness ABI, dependency-age propagation, payload validation и повторную оценку у consumer; все 128 модельных/геометрических/motion/TGS/material результатов точны к прежнему PyTorch-reference. Условия Worker закреплены в read-only readiness evaluator и candidate manifest; evaluator не приобретает lease и не управляет частотами. Предыдущий fixed-clock A/B (p99 PyTorch 77.02 ms) остаётся отдельным evidence, не переносится на auto-mode или новую полную квалификацию. Текущий шаг не менял clocks/quotas/weights/thresholds. Следующий шаг — общий lifecycle/data plane, per-cell expiry и standalone package этапа 2; не новая модель и не автономия. Текущий 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 пока не удалён и продуктовый путь не переключён. @@ -139,6 +139,8 @@ IPC/сети, копирований и оркестрации. Вычислит **Выход / зависимость:** GO на этап 2 после фиксации состава, существенных контрактных границ и воспроизводимого baseline. По уточнению владельца от 2026-09-02 performance FAIL на текущем железе не является запретом на развитие лабораторной платформы/упаковки и не требует выбрасывать профиль. На 2026-09-01 выполнены карта/reuse, executable contract, candidate manifest, component baseline и совместный causal pilot полного графа. Дальше измеряем и уменьшаем задержки, исправляем preroll/layered freshness и сохраняем отрицательные результаты; real-time статус выдаётся отдельно, только по факту прохождения критериев. Network whole-path и самостоятельная упаковка относятся к следующему runtime и не объявляются проверенными по локальному collector. Диагностический контейнер с mounts не является runtime этапа 2. +**Gate на 2026-09-02 10:16 МСК: GO (engineering, not qualification).** Shared output freshness и operating-envelope contract зафиксированы, выполнен bounded полный reference pilot. Обязательная стадия исследования состава/baseline завершена. Не следует бесконечно удерживать упаковку на этапе 1 из-за уже явно измеренных overload/source-gap/quality ограничений. В этап 2 перенесены реализация controller lease/continuous readiness, transport, supervisor, per-cell aging и самостоятельная упаковка; положительный real-time допуск по-прежнему требует отдельных измерений. Cat/dog/close-object качество, mount/clearance, другая и полная запись остаются непройденными gates квалификации, а не новым training scope. + ## Этап 2 — Самостоятельный Docker с полным потоковым вычислением **Цель:** один самостоятельный контейнер принимает поток и реально рассчитывает DDRNet, детекции, расстояния, motion, TGS/costmap и policy-shadow; ничего не дорисовывается из старых LAB. @@ -220,6 +222,8 @@ EoMT — семейство ViT-моделей сегментации изобр ## Progress +- 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-проверки перенесены в этот план. - 2026-09-01 18:15 UTC: прочитаны все пять документов CODEX_V5; уточнение владельца о взаимоисключающих профилях внесено в TARGET. Проверены первичные источники EoMT. Создан план ровно из четырёх этапов. - 2026-09-01, последующий аудит: прочитаны M4.9T5/E47/M4 и integrated artifacts; через SSH выполнены только read-only Docker inventory/inspect, чтение installed manifests и GPU status. Подтверждено расхождение между viewer composition, reusable graph и portable package; выявлены другие GPU-capable сервисы. @@ -250,6 +254,9 @@ EoMT — семейство ViT-моделей сегментации изобр ## Surprises / открытые вопросы +- Свежая camera/cloud/pose пара не равна свежему полному scene. У TGS last-seen разрешающих ячеек может быть старее camera anchor; новый guard сохраняет этот возраст. В финальном C пять scenes истекли за 1–4 ms между publisher guard и приёмом, хотя раньше выглядели бы свежими. Пока одна такая ячейка запрещает весь scene; per-cell expiry — следующий runtime increment без ослабления 250-ms TTL. 52 source gaps нельзя исправить GPU-ускорением. +- New operating-envelope evaluator — проверяемый контракт readiness, не уже подключённый orchestrator и не host clock manager. Power/P-state/limit остаются измеряемыми фактами; continuous monitoring и авторитетный lease должен предоставить общий runtime. Low GPU utilization не доказывает владение, а snapshot PASS не квалифицирует целый run. + - Малое численное расхождение backend не обязательно семантически безвредно. Critical cell flip устранён fail-closed tie rule, но PyTorch vs TensorRT material по-прежнему совпадает 127/128 кадров. Без ground truth и явной numeric acceptance нельзя заменить reference автоматически. - Автоматический downclock GPU/VRAM — подтверждённый A/B источник существенной части tail latency. CUDA Graph capture был реальным; CPU quota не троттлила. Server intervals всё ещё не являются CUDA kernel trace, а остаточные IPC/CPU/network затраты не исчезли. Две fixed-clock пробы пройдут 125-ms gate, возвращённый auto — нет; квалификация должна описывать условия Worker, а не только image digest. - Глобальная блокировка очереди противоречит независимости будущих Worker; нужно перенести ownership scope, а не просто оставить `max_concurrency=1` во всех слоях. @@ -286,6 +293,6 @@ EoMT — семейство ViT-моделей сегментации изобр ## Outcomes / retrospective -Результат этапа 1 на текущий момент: полный causal граф, точный source clock, bounded queues, исправленные preroll/handoff/surface reuse и fail-closed material ties. A/B подтвердил downclock как существенную latency-причину; fixed-clock full graph дважды прошёл короткий 125-ms gate на TensorRT, один раз на pinned PyTorch. Auto-restored контроль снова FAIL. TensorRT arithmetic/material parity не пройдена; default PyTorch не менялся. Operating envelope ещё требуется оформить в управляемый Worker lifecycle, layered output ABI — довести. Network end-to-end, несколько/полная запись и standalone packaging не проверены; cached Triton blob / NVCR403 blocker не перепроверялся. Mounted pilot не заменяет поставляемый образ. Частоты восстановлены, Ollama/Frigate выключены, четыре временно остановленных сервиса возвращены в прежнюю конфигурацию. +Этап 1 завершён как инженерный baseline: полный causal граф, shared six-layer ABI, measured Worker envelope, исходный clock, bounded queues и проверенные conservative freshness/material guards. Условия проверяет чистый evaluator; runtime-controller integration ещё нет. Fixed-clock A/B ранее дал bounded latency PASS, auto C сейчас даёт p99 141.40 ms и только 27 полных свежих scenes. Это честный FAIL квалификации, не запрет на следующий этап экспериментальной платформы. Default PyTorch сохранён, TensorRT parity не принята. Следующий этап 2: общий streaming lifecycle/data plane, lease/clock-condition monitoring, per-cell expiry и самостоятельный image без code/model mounts. Network, несколько/полная запись и standalone proof не получены; NVCR403/image-layer blocker не перепроверялся. В последнем шаге clocks/quotas не менялись, четыре сервиса восстановлены, Ollama/Frigate выключены, Mac 8000 работает. Неисправный исторический test с внешними evidence symlinks учтён отдельно; full suite не объявлен зелёным. После этапа 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 e4a52c9..75009f5 100644 --- a/docs/adr/0049-stream-first-perception-profiles.md +++ b/docs/adr/0049-stream-first-perception-profiles.md @@ -137,6 +137,31 @@ remain the domain vocabulary. `LayerEvidence` adds freshness/completeness checks not a second semantic ontology. In stage 2, layer manifests also carry their full input reference sets; a single anchor does not replace camera/cloud/pose lineage. +Stage-1 implementation update, 2026-09-02 (`097e450`): +`missioncore.perception-scene-freshness/v1` in `realtime_scene.py` extends +`LayerEvidence` with oldest-required-input time and checks the six-layer dependency +graph. A derived result cannot refresh its input age. Decimal int64 JSON strings +preserve timestamps/sequence exactly; transport-neutral Python objects use integers. +The pilot validates payload hashes and assesses freshness again at receipt, and +must reassess at later use. Missing/stale output remains inspectable but cannot +retain permissive advisory policy. This envelope is NOT a replacement for +StreamStart identities, complete input lineage or controller lease fencing. + +The current pilot propagates the oldest last-seen permissive TGS cell into the +costmap/policy age. Expiry currently suppresses the entire scene's permissions; +stage 2 must implement explicit per-cell expiration without granting authority +from retained occupied/unknown history. Existing model/geometry/motion/TGS/material +outputs remain identical to the pinned reference on the measured 128-frame window. +Freshness/completeness is not semantic correctness or physical safety. + +`worker_operating_envelope.py` checks a trusted post-warmup snapshot against +preregistered hardware/driver/resource/clock conditions and StreamStart identities, +ownership and client inventory. Unknown or expired facts fail readiness. The +candidate records the previously measured 4090 fixed-clock envelope; a compatible +auto-clock experiment cannot inherit its latency result. The evaluator performs +no I/O, host clock changes, lease acquisition or qualification; collection and +continuous enforcement belong to the common controller/runtime in stage 2. + DDRNet currently crops the center 600×600 to 512×512; outside that ROI is undefined, not hard_surface/free. RF-DETR accepts the full 800×600 native raster with its pinned valid-FOV handling. Their coordinates must be related explicitly. diff --git a/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md b/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md index cf2ba6c..4a76908 100644 --- a/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md +++ b/experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md @@ -2,7 +2,9 @@ Дата: 2026-09-01. Experiment ID: `perception-stream-stage1-20260901T1930Z`. Worker: RTX 4090, 24564 MiB, NVIDIA driver 610.47. -Статус: **частичный результат этапа 1; не полный runtime и не real-time qualification**. +Статус на 2026-09-02 10:16 МСК: **этап 1 закрыт как контракты и технический baseline; +GO на инженерную реализацию этапа 2, не полный runtime и не real-time qualification**. +Все промежуточные статусы ниже сохранены как история измерений. Обновление 20:51 UTC: совместный source-paced пилот выполнен. После оптимизации 128/128 кадров без drops; p95/p99 174.09/190.62 ms — FAIL исходного latency gate. Подробности и evidence нового experiment `perception-joint-pilot-20260901T2040Z` @@ -30,6 +32,15 @@ NO_GO→ALLOW_candidate. Default остаётся pinned PyTorch; подробн p99 снова 144.88 ms. Исправлена ничья material votes → unknown/NO_GO. Это bounded Worker-local latency PASS, не qualification продукта/сети/автономии. +Последнее дополнение — 2026-09-02 10:16 МСК: общий six-layer freshness ABI +подключён к пилоту и проверяет возраст на стороне consumer. Финальный PyTorch +auto-clock run: 128/128 без drops, p95/p99 122.11/141.40 ms, 27 полноценно +свежих сцен; 52 missing sensor pairs и 49 stale costmaps не получают допуск. +Пять сцен реально истекли между publisher guard и receipt. Численный baseline +моделей/geometry/motion/TGS/material совпал с прежним reference на всех кадрах. +Worker operating envelope зафиксирован как проверяемый контракт, без управления +частотами из контейнера. Детали, ошибки проверок и граница GO — в конце отчёта. + ## Решение и сделанный объём Первый профиль зафиксирован как `K1 Perception — DDRNet-39 + RF-DETR + TGS`: @@ -983,3 +994,115 @@ power limit 450 W; все clock resets успешны. Canonical Mac 8000=200, 8 layered output ABI и reproducible Worker operating envelope ещё нужно закрепить; этапы 2–4 не объявляются завершёнными. Отсутствие full-session/standalone/network proof и TensorRT numeric/material parity не маскируются полученным ускорением. + +## Шесть слоёв, receiver freshness и завершение этапа 1 — 2026-09-02 10:16 МСК + +Commit `097e450`; experiment `perception-freshness-worker-20260902T1006MSK`. +Добавлены shared `realtime_scene.py`, `worker_operating_envelope.py`, тонкий +`pilot_freshness.py` adapter и отрицательные тесты. Это не новая LAB-программа, +не новая модель и не изменение действующего backend/frontend пути. + +### Что изменено + +- `missioncore.perception-scene-freshness/v1` учитывает segmentation, objects, + geometry, motion, costmap и policy. У слоя сохранены собственные epoch, + sequence/time, payload digest, current/held/stale/unavailable и время самого + старого обязательного свежего входа. Derived-layer timestamp не освежает + входы; missing/stale распространяются по dependency graph. Пустые детекции — + валидный результат; missing LiDAR или failed surface — не нулевая дистанция. +- JSON-проекция int64 использует десятичные строки, включая timestamps выше + JavaScript safe integer. Проверяются закрытая схема, future/cross-epoch данные, + mapped clock domain и погрешность часов. Полный StreamStart / lease fencing + остаётся отдельной обязанностью будущего transport/controller, не имитируется + проверкой одного epoch. +- Publisher guard и local collector независимо оценивают возраст. Receiver + проверяет фактические payload hashes и снимает terrain permission при stale + или unavailable. Его диагностический view не переписывает immutable + опубликованный payload. Возраст нужно повторно считать при дальнейшем use; + один сохранённый receipt не является вечным допуском. +- TGS сохраняет oldest last-seen среди разрешающих/high-cost ячеек. Retained + occupied/unknown и история motion могут запрещать, но не самостоятельно + разрешать поверхность. Пока это намеренно консервативный whole-scene guard: + одна устаревшая разрешающая ячейка переводит **всю** advisory policy в NO_GO. + Per-cell expiry и полные dependency references — дальнейшая работа общего + runtime. Корректность temporal reprojection/материалов и vehicle clearance + этим контрактом не доказана. +- Candidate manifest содержит измеренные reference conditions: RTX 4090, + driver 610.47, Docker 8 CPU / 8 GiB, SM ≥2610 / memory ≥10251 MHz. + Read-only evaluator сверяет image/config/worker, известность и возраст + snapshot, ресурсы/частоты, authoritative lease, отсутствие competing clients + и warmup. Unknown не становится PASS. Snapshot PASS — лишь readiness, + не qualification и не доказательство постоянных частот. Его подключение к + controller/continuous monitoring относится к этапу 2; текущая lease acquisition + не реализована. Auto-mode эксперимент разрешён, но не наследует fixed-clock + квалификацию. Power/P-state/limit сохранены в telemetry/host evidence. + +### Проверка на Worker + +Два последовательных 128-frame PyTorch eager reference запуска, original +source pacing 1×, DDRNet→RF-DETR serial GPU, overlap CPU, pending ≤2, +inflight ≤16 MiB, Docker 8 CPU / 8 GiB. Частоты **не менялись**, новый образ +не собирался, использовались прежние pinned assets и code-only overlay. + +| Run | Состав / wire | p95 | p99 | Fresh при receipt | Results / drops | +| --- | --- | --- | --- | --- | --- | +| B | Полный граф, промежуточная JSON integer проекция | 142.07 ms | 181.77 ms | 23/128 | 128/128, 0 | +| C | Полный граф, финальная decimal-int64 ABI | 122.11 ms | 141.40 ms | 27/128 | 128/128, 0 | + +Разница B/C не приписывается JSON: это не controlled clock A/B. В обоих runs +22/27 clock samples ниже reference operating envelope; CPU cgroup throttling=0. +Ни один не проходит совместный gate p95 **и** p99 ≤125 ms (C проходит только p95). + +В C fresh при publisher guard=32, при receipt=27. Sequence 30, 39, 70, 93, 115 +истекли за время кодирования/получения; consumer выставил NO_GO. 52 sensor pairs +отсутствуют по исходному binding, ещё 49 scenes имеют stale costmap/policy. +Ни один stale/unavailable receipt не сохранил ALLOW/HIGH_COST. Эти 27 — полнота +и свежесть ABI, не доказанная perceptual accuracy. Исторические «76 fresh» здесь +означали лишь 76 доступных camera–cloud–pose pairs, не 76 полных свежих scene. + +В B и C все 128 segmentation hashes, proposals, observations, tracks, threats, +range estimators, sensor bindings, costmap states и material arrays точны к +предыдущему pinned PyTorch `reference-locked-128-e`. Изменились только freshness +metadata и консервативный policy guard; thresholds/precision не ослаблялись. + +В C весь участок freshness + JSON encode/receive/validation занимает mean +2.176 / p95 3.267 / p99 3.564 ms. Это **не** измеренная добавочная стоимость +контракта относительно старого кода. VRAM peak 2365 MiB; cgroup memory peak +3370.79 MiB (это не process RSS), inflight peak 5,202,376 bytes, stop 4.066 s, +warmup 9.274 s, backlog growth 1.212 ms. Лимиты не расширялись. + +### Проверки, ошибки и evidence + +142 focused tests PASS; дополнительно 42 adjacent regression tests PASS, +1 historical baseline test FAIL: `.runtime` evidence symlinks разрешаются +в соседний `NODEDC_MISSION_CORE`, а неизменённый root-containment guard +`baseline.py` это запрещает. Baseline/data/symlinks не исправлялись и не +перехешировались ради зелёного теста. Ruff, mypy трёх contract modules, +diff-check PASS. Full suite/build/модельная нагрузка на Mac не выполнялись. + +Первая попытка host inventory остановилась до service stop из-за PowerShell 5 +array wrapping; исправлено. Run A остановился до source release (0 frames): +в code staging отсутствовал pinned preprocessing runner. Для B/C восстановлен +тот же файл с SHA `b18ad60f277eea69a240a28f290611b94627fb9707faf1bb3e6e22102dad67c1`. +Первое восстановление perception-worker потребовало повторного start после +Triton; зависимый порядок исправлен в B/C. Неудачные attempts сохранены. + +Manifest: `.runtime/perception-freshness-worker-20260902T1006MSK/manifest.json`, +140 artifacts; SHA-256 +`3b0a2ad32f6b60d3da48a4bcafdf6e11bc91209abc9d1f65da54b0eb36c52d45`. +Копия в `D:/NDC_MISSIONCORE/runtime/experiments/perception-freshness-worker-20260902T1006MSK`. +Image неизменён; profile candidate SHA теперь +`e1c244e3be8b4880cb4b4d7e96a88feada69773dbb16f5c9a17ef663030138f3`. +Raw records/model outputs — вне Git. Все четыре временно остановленных сервиса +восстановлены; Triton healthy/ready 200. Старые transport/HTTP404 loops не +ремонтировались. Ollama/Frigate exited/restart=no. Pilot containers=0, +GPU P8/210/405 MHz, 979 MiB, power limit 450 W; Mac 8000=200, 8765 закрыт. + +**Gate этапа 1:** состав, shared contracts, зависимости, ограничения и +воспроизводимый bounded baseline зафиксированы — GO на этап 2 как разработку +экспериментального runtime. Это соответствует разрешению владельца продолжать +платформу при честном performance FAIL; stage 1 не переименован в qualification. +Этап 2 ещё не выполнен: нужны общий lifecycle/lease/data plane, per-cell expiry, +streaming без full-source barrier и standalone image без developer mounts. +Auto-clock p99, source gaps, TensorRT parity, full-session/network/quality +приёмка остаются открытыми. Этапы 3–4 не начаты, actuation=false.