docs(perception): record stage-two scheduler and cell freshness proof

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 11:03:26 +03:00
parent 1f8101e4a5
commit d264cbce04
3 changed files with 153 additions and 11 deletions
@@ -5,6 +5,9 @@ Worker: RTX 4090, 24564 MiB, NVIDIA driver 610.47.
Статус на 2026-09-02 10:16 МСК: **этап 1 закрыт как контракты и технический baseline;
GO на инженерную реализацию этапа 2, не полный runtime и не real-time qualification**.
Все промежуточные статусы ниже сохранены как история измерений.
Продолжение на 2026-09-02 11:00 МСК: начат этап 2, вынесен общий scheduler
и реализован per-cell expiry. Два новых Worker-прогона и точная parity приведены
в последнем разделе этого же журнала. Этап 2 целиком ещё не закрыт.
Обновление 20:51 UTC: совместный source-paced пилот выполнен. После оптимизации
128/128 кадров без drops; p95/p99 174.09/190.62 ms — FAIL исходного latency gate.
Подробности и evidence нового experiment `perception-joint-pilot-20260901T2040Z`
@@ -1106,3 +1109,110 @@ GPU P8/210/405 MHz, 979 MiB, power limit 450 W; Mac 8000=200, 8765 закрыт.
streaming без full-source barrier и standalone image без developer mounts.
Auto-clock p99, source gaps, TensorRT parity, full-session/network/quality
приёмка остаются открытыми. Этапы 3–4 не начаты, actuation=false.
## Этап 2, первый инкремент — общий scheduler и per-cell expiry, 2026-09-02 11:00 МСК
Изменения: `bcacb02` и `1f8101e`. Это продолжение исходного ExecPlan, не
отдельная LAB и не новый параллельный runtime domain. Старые graph/provider
контракты, модели, surface/geometry/motion/TGS/material алгоритмы сохранены.
### Выполнено
- Queue и GPU stage перенесены в `k1link.perception.streaming_queue` и
`streaming_scheduler`; пилот использует только compatibility imports.
Один serial GPU callback исполняет DDRNet → RF-DETR, CPU tail может
перекрываться с GPU следующего кадра. Две pending slots общие для ingress
и completed GPU, active inputs остаются в лимите 16 MiB до release владельцем.
- Finish дренирует очередь, cancel отбрасывает pending. При ошибке GPU его
active input освобождается; при stop timeout ресурсы остаются за реально
работающим callback. GPU close не освобождает CPU-owned input. Double/foreign
release и повторный/out-of-order admission отвергаются. Drop-history содержит
максимум 256 записей, totals сохраняются отдельно; это не terminal ledger.
- `CostmapCellEvidence` хранит исходный last-seen timestamp каждой ячейки,
строго ограниченные массивы и lossless int64 wire strings/null. Metadata и
guard mode включены в costmap hash. Нет подстановки времени для unseen cells.
- При publication/receipt старые ground cells становятся rejected/NO_GO.
Occupied/unknown не превращаются в разрешение. Остальные разрешения сохраняют
свой исходный возраст и все mandatory dependencies: stale segmentation или
missing geometry блокируют весь policy. TTL 250 ms не расширен.
- Derived consumer view получает собственные проверяемые hashes, но не меняет
epoch/source identity/timestamps и исходные wire bytes. Повторная проверка
не восстанавливает подавленное действие и не допускает обратного хода clock.
Основной pilot default теперь `per-cell`; `whole-scene` оставлен явным A/B control.
Это низкоуровневые lifecycle primitives, **не** cross-process GPU lease,
authoritative controller или полный supervisor. Бинарный live data plane и
самостоятельный image без code/model mounts в этом инкременте не реализованы.
### Пререгистрированный последовательный A/B на Worker 006
Experiment: `perception-stage2-cells-worker-20260902T1055MSK`. Каждый run —
128 кадров source-paced 1×, исходный host-arrival clock, одинаковые pinned
source/model assets и общий новый scheduler. PyTorch eager, DDRNet и RF-DETR
по 128 inference без held-mask cadence. Docker: прежние 8 CPU / 8 GiB,
network none, read-only assets/root; полный source не передавался и не
хешировался перед первым результатом. Никакого build/скачивания/clock lock.
| Метрика | Whole-scene control | Per-cell |
| --- | --- | --- |
| Completed / drops / unaccounted | 128 / 0 / 0 | 128 / 0 / 0 |
| Latency mean / p95 / p99 | 82.74 / 125.01 / 130.31 ms | 77.52 / 123.91 / 136.17 ms |
| Fresh envelope publication → receipt | 26 → 25 | 76 → 76 |
| Missing sensor pairs | 52 | 52 |
| Whole costmap stale failures | 51 | 0; old cells individually NO_GO |
| First result после stream start | 567.24 ms | 568.13 ms |
| Warmup / stop | 9.333 / 4.066 s | 9.358 / 4.066 s |
| GPU peak / cgroup memory peak | 2362 / 3384.85 MiB | 2365 / 3377.78 MiB |
| Inflight peak / residual | 5,254,336 / 0 bytes | 5,202,376 / 0 bytes |
Оба latency gate FAIL: p99 >125 ms. Auto clocks колебались, поэтому разница
mean/p95/p99 не приписывается новому scheduler или expiry. В обоих runs
SM/VRAM опускались ниже прежнего measured fixed envelope; CPU throttling=0.
Freshness+encode+receive целиком: mean/p95/p99 2.557/3.879/4.412 ms (control)
и 3.204/4.682/4.973 ms (per-cell); это не изолированная стоимость нового кода.
Максимальный scene payload 129,289 bytes, ниже 1 MiB collector cap.
Per-cell: 1994 ground cell×frame appearances истекли при publication и ещё
201 при receipt; 1478 потенциальных разрешений были адресно подавлены.
Это temporal cell appearances, не число уникальных объектов/препятствий.
76 свежих envelopes соответствуют всем 76 доступным sensor pairs в этом
окне. **Внутри свежего envelope остаются rejected/unknown клетки**: это не
полное покрытие свободного пространства и не качество/безопасность движения.
52 missing pairs по прежнему source binding не подменяются новой геометрией.
Оба runs: все 128 segmentation hashes, proposals, observations, tracks,
threats, range estimators, raw TGS state hashes, material arrays и sensor
bindings точны к pinned PyTorch `reference-locked-128-e`. Effective states
и policy намеренно меняются только от expiry/guard. Повторная read-only
проверка 256 сохранённых receipts восстановила derived views, их hashes,
freshness и policy counts. Ни одно разрешение не осталось на stale support,
не-ground, не-hard_surface или при неполном mandatory layer set. Motor authority=false.
### Проверки, evidence и следующий gate
202 focused tests PASS (contracts, freshness, queue/cancel/failure/release,
pilot, Worker envelope, material policy, local surface). Ruff, strict mypy
четырёх изменённых core modules, diff-check PASS. Full suite/build/models на
Mac не запускались. Известный historical baseline failure с внешними evidence
symlinks не ремонтировался и в этом шаге не перезапускался.
Manifest: `.runtime/perception-stage2-cells-worker-20260902T1055MSK/manifest.json`,
125 artifacts; SHA-256
`1a951fd9e807099e500fa66f8a40b1076071f96e4c8e0be4ab3094caaa33bf09`.
Копия: `D:/NDC_MISSIONCORE/runtime/experiments/perception-stage2-cells-worker-20260902T1055MSK`.
Image SHA `664824aa25de1db178f177d67a81b01541a938b479812b9383ddbf03f6b59dbe`
и candidate profile SHA `e1c244e3be8b4880cb4b4d7e96a88feada69773dbb16f5c9a17ef663030138f3`
не изменились; guard mode и code identities записаны отдельно в commands/manifest.
Raw evidence остаётся вне Git.
Все четыре ранее работавших Mission Core сервиса восстановлены в dependency
order, Triton healthy/ready=200. Старые service restart loops не менялись.
Ollama/Frigate exited/restart=no; pilots=0. Final GPU auto P8/210/405 MHz,
980 MiB, power limit 450 W. Mac 8000=200, 8765 закрыт.
**Gate:** первый инкремент этапа 2 принят, весь этап ещё в работе. Следующий
шаг — общий supervisor/StreamStart lifecycle с authoritative ownership и
fencing, затем binary live ingress без знания длины/EOF и standalone package.
Не выдавать их за реализованные по факту общего scheduler. Stage 3 cutover,
full-session/network/quality/vehicle qualification и TensorRT promotion закрыты
до своих проверок. Профиль остаётся экспериментальным, actuation=false.