docs(perception): record bounded binary ingress evidence and remaining bridge
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Observatory: четыре этапа создания полного real-time Perception-профиля
|
||||
|
||||
Дата: 2026-09-01; обновлено 2026-09-02 12:00 МСК. **Этап 1 закрыт; этап 2 в работе: общие scheduler/per-cell expiry дополнены subprocess lifecycle и Worker-local cooperative lease/fencing. Real-time qualification НЕ выдана.** Полный normal pilot: 128/128 без drops, p95/p99 124.98/136.12 ms, fresh 76/128; 52 source gaps остаются NO_GO. Два намеренно аварийных прогона подтвердили lease-loss, полное освобождение и точный terminal accounting. Межконтейнерные contention/clean succession/crash quarantine проверены. Постоянный product controller, binary live ingress и standalone image ещё не готовы; этапы 3–4 не начаты. Default PyTorch, TensorRT parity не принята.
|
||||
Дата: 2026-09-01; обновлено 2026-09-02 12:35 МСК. **Этап 1 закрыт; этап 2 в работе. Третий инкремент: bounded binary IPC ingress с неизвестной длиной источника подключён к общему lifecycle/byte budget и проверен на Worker.** 103/103 исходных события доставлены без изменения bytes/metadata; камера, LiDAR и pose поступают до End. Это raw-digest consumer, **не** подключённый к этому ingress полный модельный граф. Real-time qualification НЕ выдана: последнее полное измерение остаётся 128/128, p95/p99 124.98/136.12 ms, fresh 76/128. Далее decoder→full graph bridge, network/controller и standalone image; этапы 3–4 не начаты. Default PyTorch, TensorRT parity не принята.
|
||||
|
||||
Последние изменения: `6acf468` — lifecycle и Worker-local lease; `ac69e3b` — подключение к полному пилоту и negative probes. Final expiry trace: stop через 45.74 ms после deadline, retirement через 4109.82 ms, receipts at/after deadline=0. Проверены все 229 опубликованных receipts и точная raw parity с соответствующими prefix reference. Модели/thresholds/clocks/quotas не менялись; auto latency deltas не являются доказанным ускорением. Следующий шаг — bounded binary ingress с неизвестной длиной источника, постоянная controller integration/recovery и standalone package. Локальный cooperative fence не заменяет backend claims, external GPU inventory или network authentication; эти gates остаются открытыми.
|
||||
Последние изменения: `da60fef` — binary v2 mapping существующих LiveIngressEvent, sender/receiver и общий byte budget; `a937400` — корректная фиксация End в probe; `79ce55d` — regression старого raw-first ingress. 276 focused tests PASS. CPU-only Worker probe: 32 camera frames + init + 34 LiDAR + 36 pose, 4,061,693 wire bytes, peak input 553,991 bytes, residue 0. Межпроцессная доставка до raw callback: p95/p99 0.419/0.601 ms; это не model/network latency. Обрыв между фрагментами не выдал payload и завершил lease. Модели/clocks/старые GPU-сервисы не менялись. Прежние lifecycle/lease/full-graph доказательства сохранены; 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 с полным потоковым вычислением
|
||||
|
||||
**Текущий статус, 12:00 МСК:** в работе. Общие mailbox/serial GPU stage, per-cell expiry, subprocess lifecycle и Worker-local cooperative lease подключены к полному пилоту. Межконтейнерное владение, crash quarantine и две реальные lease-expiry остановки проверены. Production admission/recovery, continuous GPU inventory/envelope monitoring, binary network ingress и standalone image ещё не закрыты. GO на этап 3 пока нет.
|
||||
**Текущий статус, 12:35 МСК:** в работе. Lifecycle/scheduler/per-cell expiry проверены полным пилотом; новый raw binary ingress — отдельным CPU-only межпроцессным probe. Их decoder/full-graph соединение ещё требуется: новый вход пока принимает и проверяет raw события, не рассчитывает модели. Production admission/recovery, continuous GPU inventory/envelope monitoring, binary network ingress и standalone image ещё не закрыты. GO на этап 3 пока нет.
|
||||
|
||||
**Цель:** один самостоятельный контейнер принимает поток и реально рассчитывает DDRNet, детекции, расстояния, motion, TGS/costmap и policy-shadow; ничего не дорисовывается из старых LAB.
|
||||
|
||||
@@ -260,8 +260,12 @@ EoMT — семейство ViT-моделей сегментации изобр
|
||||
- Normal pilot 128/128 без drops, p95/p99 124.98/136.12 ms, fresh 76/128. Intentional expiry A: 52 released = 51 complete + 1 GPU terminal drop; expiry trace B: 50 released = 50 complete. Оба `execution_complete=false`, reason=`lease-lost`, unaccounted=0, все процессы/входы освобождены. Final trace: stop-request deadline +45.74 ms, retirement +4109.82 ms, receipts at/after deadline=0. Все 229 опубликованных raw outputs exact к reference prefix; clocks/quotas/models не менялись.
|
||||
- Evidence: `.runtime/perception-stage2-lifecycle-worker-20260902T1146MSK/manifest.json`, 259 artifacts, SHA-256 `00bd091a80845e50489a34ce4df2cbf3d2cd60d9ecb13d1d97accd03d44fdba4`. Временные probe containers и два test volumes удалены после сохранения owner records. Четыре сервиса восстановлены; Triton ready=200, Ollama/Frigate exited/restart=no, Mac 8000=200, 8765 закрыт. Этап 2 остаётся в работе; дальше binary ingress, постоянная controller/recovery integration и standalone package.
|
||||
|
||||
- 2026-09-02 12:35 МСК: третий инкремент (`da60fef`, `a937400`, `79ce55d`), 276 focused tests PASS. Worker raw IPC: 103/103 exact, каждый data channel до End, peak 553,991 bytes; negative EOF: incomplete=1, delivered=0, release=true. Evidence `.runtime/perception-stage2-binary-ingress-worker-20260902T1232MSK/manifest.json`, 42 artifacts, SHA-256 `2a5492080027a86de9f176f051c9265e29f377d1d9207c86ac93cdff7632505a`. Попытки 1230 (неполный diagnostic code pack) и 1231 (гонка финального timestamp journal) сохранены как rejected; их manifests связаны из принятого. Никакой повторной GPU-квалификации этим probe не выдано.
|
||||
|
||||
## Surprises / открытые вопросы
|
||||
|
||||
- IPC probe отделил работоспособность raw ingress от работоспособности decoder/full graph. Наличие codec-init gate не проверяет NAL/IDR, access-unit framing или соответствие fisheye calibration. Оригинальные fMP4 segments не превращаются автоматически в model-ready frames; следующий bounded шаг — persistent incremental decoder и causal sensor adapter с allocation bounds, затем тот же полный граф. Старые model inputs/prepared paths не подмешивать в доказательство нового ingress.
|
||||
|
||||
- 2026-09-02 12:00 МСК: истечение lease и освобождение GPU разделены. После crash OS lock свободен, но durable `active` не допускает новый запуск. Recovery намеренно отсутствует до trusted resource-release proof; нельзя удалять production marker ради продолжения. В пробах удалены только два заведомо временных experiment-owned volume после сохранения записей и остановки всех probe containers.
|
||||
|
||||
- Свежая 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-ускорением.
|
||||
@@ -303,6 +307,6 @@ EoMT — семейство ViT-моделей сегментации изобр
|
||||
|
||||
## Outcomes / retrospective
|
||||
|
||||
Этап 1 остаётся завершённым engineering baseline. В этапе 2 общий lifecycle теперь действительно управляет subprocess-backed пилотом: тёплые модели, admission, serial GPU/CPU lanes, result binding, watchdog и проверенный release. Cooperative lease проверен между контейнерами на общем томе; crash не превращается в разрешение новому владельцу. Normal run 128/128, 76 fresh envelopes, raw parity exact; p99 136.12 ms — всё ещё FAIL 125 ms. Expiry runs завершились намеренным FAIL с закрытым учётом и без остаточных владельцев/bytes, а не ложным successful completion. Следующий этап работы — binary unknown-duration ingress и постоянная controller/ownership/recovery integration, затем самостоятельная упаковка. Новый код не переключает старый batch/registry/UI; GO на этап 3 нет. Clocks/quotas/models не менялись, временные ресурсы убраны с сохранением evidence, четыре сервиса восстановлены, Ollama/Frigate выключены. Full suite и новый image build не запускались; исторические baseline-symlink и NVCR403 вопросы не объявлены исправленными.
|
||||
Этап 1 остаётся завершённым engineering baseline. Этап 2 теперь имеет общий scheduler, per-cell expiry, subprocess lifecycle/lease и bounded raw binary IPC. Новый ingress прошёл 103 реальных source events без потерь/изменений и отдельный incomplete-fragment отказ. Общий byte budget удерживает raw/reassembly до выхода callback; старые input owners не освобождаются при cancel. Но raw-digest probe не равен полному графу: следующий шаг соединяет incremental decoder/causal sensor adapter с моделями и повторяет full-profile timing/parity на новом входе. Прежний полный p99 136.12 ms остаётся FAIL 125 ms. Network/gRPC/authentication, production controller/recovery/inventory и standalone image не приняты; старый batch/registry/UI не переключены. Четыре сервиса не останавливались в новом CPU-only probe, Ollama/Frigate остаются выключены. Full suite/image build не запускались; исторические baseline-symlink и NVCR403 вопросы не объявлены исправленными.
|
||||
|
||||
После этапа 4 здесь будут перечислены digest самостоятельного полного образа, измеренные статусы и ошибки по recordings, реально проверенные source/hardware/config комбинации, состояние сохранённого EoMT-варианта и оставшиеся physical-live/quality/vehicle-integration ограничения. Готовый Docker и готовая автономия не отождествляются.
|
||||
|
||||
@@ -99,6 +99,47 @@ explicit byte bound is required. No duplicate new scanner feed is introduced.
|
||||
|
||||
## Time and lifecycle
|
||||
|
||||
Stage-2 raw IPC increment, 2026-09-02 (`da60fef`, `a937400`, `79ce55d`):
|
||||
`streaming_wire.py` maps existing `LiveIngressEvent` fields into
|
||||
`missioncore.live-perception-wire/v2`. The v1 producer hooks, class and legacy
|
||||
serialization remain unchanged. A bounded length-prefixed JSON header carries
|
||||
decimal uint64 projections; payloads remain binary. This is a controller-supplied
|
||||
IPC socket candidate, not a selection/replacement of the intended gRPC network
|
||||
transport. No listener, arbitrary endpoint, scanner feed or command path is added.
|
||||
|
||||
Open compares the entire expected StreamStart and acquisition session binding;
|
||||
every fragment/control carries a digest of that full binding. A hash is integrity,
|
||||
not authentication. Fragment size is at most 1 MiB, event caps reuse the existing
|
||||
1 MiB camera / 2 MiB LiDAR/pose limits. Headers are capped at 64 KiB. One
|
||||
observation assembles at a time with exact offsets, fragment and whole-event
|
||||
SHA-256, per-channel source identity/sequence/clock checks. End, Cancel and
|
||||
gap/unavailable notices are explicit. EOF without End, timeout, malformed,
|
||||
cross-binding or incomplete input fails the bound stream; an unbound wrong Open
|
||||
is rejected without stopping the current owner. Camera frames require init;
|
||||
camera gap invalidates init. Actual codec/keyframe/IDR validation is NOT yet here.
|
||||
|
||||
`StreamingSender` owns no queue and fails on its bounded write deadline rather
|
||||
than stretching replay time. `StreamingIngress` is a lifecycle-tracked thread;
|
||||
idle reads poll the lease and cannot keep accepting an expired owner. Raw/header
|
||||
and reassembly reservations charge the SAME StreamMailbox 16 MiB input budget as
|
||||
queued/active bundles. They survive cancellation until the borrowing callback
|
||||
returns and buffers are dropped. Reservations are count-bounded too. Trusted
|
||||
decoder adapters must reserve scratch BEFORE allocation and must not retain raw
|
||||
callback bytes outside that ownership contract. Python metadata object overhead,
|
||||
socket/kernel buffers, source adapter memory and model tensors additionally need
|
||||
RSS/OS resource bounds; this application counter alone is not a total-RSS claim.
|
||||
|
||||
Worker evidence uses a separate source process, original camera init/fMP4 segments
|
||||
and existing normalized point/pose increments paced at original 1x times. All
|
||||
103 events (32 camera + init + 34 LiDAR + 36 pose) match exact bytes/metadata, each
|
||||
data modality reaches the hash-only consumer before End, and incomplete EOF
|
||||
delivers no observation. Normal peak input is 553,991 bytes. This validates raw
|
||||
IPC, NOT decoder output, the full graph on this ingress, model performance,
|
||||
authenticated network behavior or a standalone image. The next adapter must
|
||||
feed incremental decode and causal sensors into the same graph without using
|
||||
the old concatenated camera file or precomputed geometry. Product source queues,
|
||||
backend routes and the browser are not switched by this increment.
|
||||
|
||||
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
|
||||
|
||||
@@ -8,6 +8,9 @@ GO на инженерную реализацию этапа 2, не полны
|
||||
Продолжение на 2026-09-02 11:00 МСК: начат этап 2, вынесен общий scheduler
|
||||
и реализован per-cell expiry. Два новых Worker-прогона и точная parity приведены
|
||||
в последнем разделе этого же журнала. Этап 2 целиком ещё не закрыт.
|
||||
Продолжение на 12:35 МСК: третий инкремент — общий bounded binary raw IPC,
|
||||
103/103 исходных событий до End и negative EOF на Worker. Это raw-digest probe,
|
||||
не новый полный model run. Decoder/full-graph bridge ещё требуется.
|
||||
Продолжение на 12:00 МСК: добавлены subprocess lifecycle, Worker-local
|
||||
cooperative ownership и fencing; normal/две expiry пробы и межконтейнерное
|
||||
владение проверены. Последний раздел фиксирует этот второй инкремент этапа 2.
|
||||
@@ -1341,3 +1344,113 @@ trusted recovery/inventory enforcement и standalone image без code/model mou
|
||||
Stage 3 UI/registry/batch cutover не начинался. Все real-time/network/full-session/
|
||||
quality/vehicle gates и actuation=false сохраняются; новый image build и
|
||||
исторический NVCR403 blocker в этом шаге не проверялись.
|
||||
|
||||
## Этап 2, третий инкремент — bounded binary raw IPC, 2026-09-02 12:35 МСК
|
||||
|
||||
Коммиты: `da60fef` — общий wire/sender/receiver и raw byte reservations;
|
||||
`a937400` — End-marker до закрытия probe, unique run/epoch по experiment;
|
||||
`79ce55d` — reuse существующего raw-first ingress без изменения wire v1.
|
||||
Ни одного нового model run, изменения весов/thresholds/clocks или переключения
|
||||
product LAB path в этом инкременте нет.
|
||||
|
||||
### Что реально реализовано
|
||||
|
||||
`missioncore.live-perception-wire/v2` сохраняет поля `LiveIngressEvent`:
|
||||
session/generation, ingress и source sequences, modality/source, original capture
|
||||
и source-host arrival stamps. JSON metadata использует decimal uint64 strings;
|
||||
payload бинарный, без base64, PNG-конверсии или целого архива. Header ≤64 KiB,
|
||||
fragment ≤1 MiB, raw camera event ≤1 MiB, LiDAR/pose ≤2 MiB — прежние modality
|
||||
bounds, не новый источник/протокол K1. Full StreamStart и acquisition mapping
|
||||
сверяются на Open; binding SHA повторяется на каждом fragment/control.
|
||||
Это integrity/fencing, не сетевая authentication.
|
||||
|
||||
Один receiver собирает одно событие; проверяет offsets, размер, SHA каждого
|
||||
fragment и целого observation, source identity/sequence/clock. Camera без init
|
||||
отклоняется; gap требует нового init. Парсинг NAL/IDR/codec и превращение fMP4
|
||||
в кадры пока не реализованы этим слоем. End — явное событие, не prerequisite
|
||||
для доставки; Cancel и modality gap/unavailable отдельны. Неожиданный EOF,
|
||||
timeout, порча и переполнение завершают bound stream, не растягивают source time.
|
||||
Неверный Open ещё не bound peer и не может отменить текущего владельца.
|
||||
|
||||
Sender синхронный, без фоновой очереди; source adapter отвечает за pacing и
|
||||
владение исходным payload. Receiver thread tracked общим lifecycle, idle read
|
||||
перепроверяет lease. Reassembly и raw/header copies резервируются **до**
|
||||
аллокации в том же 16-MiB бюджете, что queued/active bundles. Cancel не освобождает
|
||||
live reservations. Callback получает borrowed raw bytes только на время вызова;
|
||||
будущий decoder обязан отдельно резервировать scratch до выделения памяти и
|
||||
не удерживать raw вне этого контракта. Counter не заменяет RSS: Python object,
|
||||
kernel/socket, source cache и model tensor budgets проверяются отдельно.
|
||||
|
||||
### Worker 006: фактический inter-process input
|
||||
|
||||
Принятый experiment: `perception-stage2-binary-ingress-worker-20260902T1232MSK`.
|
||||
Один временный CPU-only контейнер, network none, без GPU request, 2 CPU / 768 MiB,
|
||||
read-only image, ограниченный tmpfs; новый image не строился. Источник и receiver
|
||||
разделены процессом/socket. Source adapter читает существующие camera init/media
|
||||
по одному chunk с проверкой index SHA и incrementally — прежний normalized
|
||||
sensor NPZ. Точки сохраняют xyz f64 + intensity u8, pose — position/quaternion;
|
||||
это normalized archive inputs, не выданные за исходный vendor packet/K1 live feed.
|
||||
Отсутствующий у этих sensor rows UTC не придумывается (0), original host stamps
|
||||
сохранены. Calibration в hash-only probe не используется и явно имеет synthetic
|
||||
identity; model scene по этому probe не допускается.
|
||||
|
||||
Источник ограничен 32 camera events для canary, но receiver не получает ни
|
||||
frame count, ни duration, ни inventory. Prefix и bounded prerelease sensor rows
|
||||
не скрываются: считано 146/4598 pose rows, 139/4570 point batches,
|
||||
333168/10751258 xyz rows. Это не полный pass, не full-file hash и не полный decode.
|
||||
|
||||
| Метрика | Принятый raw IPC probe |
|
||||
| --- | --- |
|
||||
| Sent / received | 103 / 103, exact bytes/metadata |
|
||||
| Состав | init 1, camera 32, LiDAR 34, pose 36 |
|
||||
| Доставка каждого data channel до End | PASS |
|
||||
| Wire bytes | 4,061,693 |
|
||||
| Пик input byte budget / остаток | 553,991 / 0 bytes |
|
||||
| Cgroup memory peak normal | 51,773,440 bytes |
|
||||
| Source release lag max | 3.717 ms |
|
||||
| Межпроцессный send-start → hash callback p50/p95/p99/max | 0.292 / 0.419 / 0.601 / 0.669 ms |
|
||||
| Sender write p95/p99 | 0.190 / 0.316 ms |
|
||||
|
||||
Интервалы измерены на одной Linux kernel monotonic timeline, не вычитанием
|
||||
несогласованных source/remote clocks. Эти sub-ms значения не включают decode,
|
||||
модели, TGS, scene delivery, сетевой маршрут или browser. Их нельзя прибавить
|
||||
к прошлому p99 и объявить новую real-time квалификацию без полного замера.
|
||||
|
||||
Отдельная synthetic negative проба оборвала LiDAR observation 1,048,593 bytes
|
||||
после первого 1-MiB fragment: started=1, completed=0, incomplete=1,
|
||||
terminal=failed, никакого payload callback. Peak bytes 2,293,803 (включая
|
||||
консервативный copy reserve), после cleanup 0. Обе пробы: lease released,
|
||||
owned children=0 live, active GPU/CPU calls=0. Временный source process и
|
||||
контейнер убраны; никаких постоянных volumes/leases этим probe не создано.
|
||||
|
||||
### Неуспешные попытки и финальная фиксация
|
||||
|
||||
Попытка `1230MSK` отклонена до observations: в diagnostic code pack не хватило
|
||||
`k1link.data_plane` (и зависимого perception contracts); точный import failure
|
||||
подтверждён отдельным CPU-only check. Исправлен только состав snapshot.
|
||||
PowerShell stderr redirection также исправлена для сохранения traceback.
|
||||
Попытка `1231MSK` передала 103/103 и корректно обработала negative EOF, но
|
||||
финальный source timestamp мог не сохраниться: source закрывал socket до записи
|
||||
marker, а supervisor уже останавливал child. Acceptance остановлена на missing
|
||||
evidence. Marker перенесён до End; следующий отдельный experiment повторил обе
|
||||
пробы. Старые folders/logs/owner results не перезаписывались.
|
||||
|
||||
276 focused tests PASS (включая 40 новых ingress cases и legacy live-perception
|
||||
regressions); Ruff, mypy четырёх core modules, diff-check PASS. Full suite не
|
||||
запускался; прежние baseline-symlink/NVCR403 вопросы не пересматривались.
|
||||
|
||||
Manifest: `.runtime/perception-stage2-binary-ingress-worker-20260902T1232MSK/manifest.json`,
|
||||
42 artifacts, SHA-256
|
||||
`2a5492080027a86de9f176f051c9265e29f377d1d9207c86ac93cdff7632505a`.
|
||||
Он ссылается на отдельные sealed rejected manifests 1230/1231. Копии evidence
|
||||
находятся в одноимённых папках `D:/NDC_MISSIONCORE/runtime/experiments/`.
|
||||
Model/raw inputs в Git не добавлялись. Четыре Mission Core сервиса продолжали
|
||||
работу, Triton ready=200; Ollama/Frigate exited/restart=no. Probe/import-check
|
||||
containers=0. GPU auto P8, 979 MiB, 450 W; Mac 8000=200, 8765 закрыт.
|
||||
|
||||
**Gate:** принят bounded raw IPC core. Следующий шаг — persistent incremental
|
||||
camera decoder и causal sensor adapter, соединяющие этот ingress с тем же
|
||||
полным DDRNet/RF-DETR/geometry/motion/TGS/policy графом, затем full-graph
|
||||
parity/timing на новом входе. Network/gRPC/authentication, constant controller
|
||||
root/recovery/inventory, standalone image и product cutover остаются открытыми.
|
||||
Этап 2 не закрыт, этапы 3–4 не начаты; actuation=false.
|
||||
|
||||
Reference in New Issue
Block a user