feat(observatory): ship modular AI inference labs

This commit is contained in:
DCCONSTRUCTIONS
2026-09-04 17:59:05 +03:00
parent eff60e490a
commit cada687173
145 changed files with 17651 additions and 1667 deletions
+11 -5
View File
@@ -227,9 +227,13 @@ Mission Core already has three semantic mechanisms:
3. `docs/domain-model/mission-core-experimental-vocabulary-v0alpha2.md` for
meanings that are not yet stable enough for Platform Ontology.
These mechanisms are sufficient before A3. A new RDF/graph store, ontology
service, or parallel entity catalog would introduce duplicated identity and
migration work without a current query or integration consumer.
These mechanisms were sufficient before A3. Observatory modular compositions
crossed the gate on 2026-09-04: planning, Worker dispatch, LAB publication and
replay presentation require the same module/composition/result/layer relations,
and typed single-result traversal lost the TGS member of a composed run. The
bounded local package is defined by
`docs/domain-model/observatory-domain-ontology-v1.md`. It keeps identity in the
existing stores and has no Platform Ontology runtime dependency.
A formal local runtime ontology is introduced only when:
@@ -239,8 +243,10 @@ A formal local runtime ontology is introduced only when:
- the graph answers named queries used by the product or automation;
- promotion or synchronization with NODE.DC Platform Ontology is defined.
Until those conditions hold, new stable meanings extend the versioned local
vocabulary and executable contracts. They do not create a second runtime model.
Other domains continue to extend the versioned local vocabulary and executable
contracts until they independently satisfy these conditions. The admitted
Observatory package projects existing store identities and cannot become a
second authority for them.
## Automated boundary gate
+301 -28
View File
@@ -1,11 +1,191 @@
# Observatory: модульные Docker-композиции → записанные LAB → CUDA-борт
## ЕДИНСТВЕННЫЙ ТЕКУЩИЙ МАРШРУТ — 2026-09-03, модульное решение
Этот раздел заменяет прежний маршрут ниже. Исторические `CURRENT`, «следующий
шаг», номера этапов и требования «один профиль = один полный Docker» в архивной
части не являются актуальными заданиями. Замеры и выполненная работа сохранены.
Решение владельца: [ADR 0051](adr/0051-modular-observatory-profiles.md).
Фактическая сверка и очистка:
[handoff report](../experiments/perception/OBSERVATORY_MODULAR_HANDOFF_2026-09-03.md).
### Цель и термины
Запись K1 → настройка AI-слоя по функциональным группам → расчёт выбранной
композиции → неизменяемая LAB и кэш на Core → повторный просмотр без Worker.
Один модуль используется разными композициями, одна композиция — разными
совместимыми записями. Удачная композиция позднее переносится на CUDA-борт.
- **Модуль:** отдельный версионированный Docker-образ модели или связанной
функции, например DDRNet, EoMT, RF-DETR, LiDAR/TGS geometry. Не отдельный
микросервис для каждого арифметического шага.
- **Профиль:** проверенная immutable композиция модулей, параметров, связей и
политики исполнения. Новая комбинация не требует сборки монолитного образа.
- **LAB:** применение точной композиции к точному снимку записи, с доказательствами,
границами покрытия и измерениями. Сохранённый результат не меняется задним числом.
- **Борт:** будущий совместимый CUDA-компьютер, не Mac Mini. Конкретные CPU/GPU,
драйверы и архитектура контейнеров квалифицируются после выбора оборудования.
Работа recorded-first. Расчёт медленнее записи допустим; достижение remote
realtime через Wi-Fi/LTE не блокирует лаборатории. Runtime всё равно сохраняет
потоковые контракты и оптимизированную подготовку данных. FPS проигрывания кэша
и скорость сборки из кэшированных узлов не выдаются за вычислительный FPS борта.
### CURRENT: установленное и доказанное
- Ветка `codex/m5-1-observatory`, HEAD `eff60e4`, поверх него есть незакоммиченные
изменения предыдущих инкрементов. Не сбрасывать и не считать всё новым diff
этой архитектурной правки. Полный список даёт `git status`.
- Core на8000: admission, очередь/claim v3, exact-cache/idempotency, publication
outbox/recovery, metadata pagination, отделение portable LAB от Legacy,
общий сохранённый viewer. На Worker установлен source CAS двух агентов и
bounded heartbeat retry. Это основа миграции, не повод написать всё заново.
- M4.9T5: CPU TGS, отдельный специализированный агент. Job
`observatory-run-b230216709dc4c59bc56c98c7e329bf1` ×004TREE опубликована:
6830 camera anchors,6811 LiDAR,19 UNOBSERVED; цикл1416.763s. Расписание
39.215757.160s внутри808.779s записи: не заявлять полное покрытие всей записи
или полный AI-граф. Сохранённую публикацию и рабочий release сохранить.
- LAB V1: установлен фиксированный стек prepare → EoMT → DDRNet → assemble.
Это старый сравнительный состав, не новый выбор одного segmenter. Последняя
job `observatory-run-67a6bf3e4d644e4a8ee3c03b915f8f01` завершена failed после
lease loss на EoMT; нового опубликованного LAB V1 нет. Исправления heartbeat
установлены, но успешный полный повтор ещё не доказан.
- Есть прототип DDRNet/RF-DETR/geometry/distance/motion/TGS/costmap/policy-shadow.
Переиспользовать алгоритмы, не называть прототип принятым автономным профилем.
- Реестр пользовательских композиций, per-node result-cache, групповые настройки
и независимо упакованные модули нового формата **ещё не реализованы**.
- Реальная полная visual/memory-lifecycle приёмка saved replay открыта. Прежние
749 frontend/166 backend checks — проверки предыдущего инкремента, не новой
модульной архитектуры. Исторические тесты не заменяют новые приёмочные сценарии.
- Audit:24 контейнера →11 после удаления13 проверенных остановленных
предшественников/debug.80 образов и9 volumes оставлены. Сохранены два текущих
агента, последняя rollback-пара, рабочие результаты и зависимости. Активные
Gaussian/Triton/perception требуют отдельной проверки потребителей.
- EoMT floor250GiB + working set изменён в source и узких тестах; установленный
образ пока350GiB. Нужен новый sealed release, не правка digest существующего.
### Продуктовые правила нового AI-конфигуратора
В существующей Обсерватории у выбранной записи — «Настройка AI-слоя» и компактное
окно с функциональными группами. Использовать существующие `Window`, `FieldFrame`,
`Select`, `WindowFooterActions` и канонические кнопки; не создавать новый workspace
или локальную дизайн-систему. Обычная checkbox-матрица Docker не подходит.
Группа сегментации: один выбор DDRNet / EoMT / «Не использовать», если частичный
состав допустим. Два segmenter в одной новой LAB запрещены сервером, не только UI.
Другие кандидаты групп: детекция, LiDAR/TGS/costmap, связь объектов с расстоянием,
motion, policy-shadow. Их окончательные границы определяются кодом/контрактами.
Один модуль с несколькими capabilities не запускается несколько раз.
Сервер проверяет зависимости: object-distance требует детекцию, облако и
калибровку; геометрические препятствия могут вычисляться без семантического
детектора. Не требовать необязательный модуль для независимого результата.
Для недоступного сочетания — понятная причина, не молчаливое включение другой ML.
Точная конфигурация уже опубликована → открыть существующую LAB, «Рассчитать» нет.
Нет результата → «Рассчитать», при активной job — существующий реальный progress
без дубликата. Нет кнопки/плашки «Расчёт завершён». Поставщики остаются в dropdown:
рассчитанность относится ко всей композиции, а не к отдельной модели. Это заменяет
старое правило удаления готового полного профиля из единственной выпадашки.
### Четыре этапа — действуют только эти
#### 1. Контракты композиции и безопасная граница миграции
- Сверка Desktop/кода/installed runtime, retention inventory и первая очистка
остановленных экземпляров выполнены в этом handoff. Спецификация ADR принята.
- Следующее: реализовать версионированные Module/Composition contracts поверх
installed-package boundary; определить producer/consumer схемы и capability
группы по фактическим алгоритмам. Не считать описательный ADR готовым API.
- Зафиксировать content identity: source, image/code/weights, параметры,
preprocessing/calibration, cadence/precision, temporal state и graph edges.
Порядок щелчков в UI не меняет identity; любые значимые входы — меняют.
- Retention manifest должен охватить pinned packages, текущий M49, старый V1,
прототип полного графа, модельные assets и один rollback. Затем отдельно
согласованно вывести активные устаревшие сервисы; только после проверки
зависимостей удалять недостижимые images/build caches/temp directories.
Приёмка: контрактные тесты несовместимости и exact identity; доказанный список
сохраняемых артефактов; никакой утраты записей/Legacy/публикаций. Этап целиком открыт.
#### 2. Переиспользуемые Docker-модули и общий Worker runtime
- Упаковать DDRNet и EoMT отдельно с закреплёнными зависимостями/весами;
LiDAR/TGS и остальные функции выделять по согласованным границам. Сохранить
общие базовые слои/проверенные assets без копирования всего набора в каждый image.
Веса входят в переносимый дистрибутив как image layers либо явные immutable
model assets с проверкой digest; случайный host checkout/conda environment
не является допустимой скрытой зависимостью модуля.
- Расширить generic launcher, не создавать агент под каждую модель. Одна аренда
на композицию Worker006, тяжёлые GPU шаги последовательно. Несколько активных
CPU/служебных контейнеров не означают разрешённый параллельный ML inference.
- Один source/preparation path, локальные межмодульные данные на Worker; не
отправлять промежуточные кадры/облака через Core туда-обратно. Сохранить bounded
потоковый I/O; целиковый cold input barrier не превращать в вечную архитектуру.
- Добавить exact per-node cache и зависимое invalidation, stateful history binding,
прогресс computed/reused/failed. Worker source CAS сам по себе это не реализует.
- Результат публикуется и просматривается с Core. Повтор publication не запускает
inference заново. Окончание/cancel освобождают временные процессы/RAM/VRAM,
не удаляют постоянные результаты. Ресурсную политику250GiB активировать новым release.
Приёмка: standalone cold start без developer checkout и необъявленных mount;
последовательные реальные прогоны двух допустимых композиций; exact cache hit,
частичный reuse, смена зависимости и безопасный failure/recovery.
#### 3. Конфигуратор, сохранённый просмотр и продуктовая приёмка
- Реализовать групповые Select и server admission в существующей Обсерватории.
Legacy не переносить назад; старый dual-segmentation V1 только совместимость/история.
- Доказать source × composition: новая совместимая запись без LAB, расчёт,
открытие сохранённой LAB, новая конфигурация, отсутствие дубликата точного повтора.
Минимум две совместимые записи и две допустимые композиции, последовательно.
- Проверить общую временную/пространственную привязку camera/segmentation/objects/
range/TGS по фактически выбранным outputs, full configured coverage и явные gaps.
- Завершить реальную normal/expanded/Escape/close/reopen приёмку и освобождение
viewer RAM/GPU после закрытия; не ограничиваться контрактными тестами.
- Проверить большие каталоги, рестарты Core/Worker, publication retry, отмену,
полную наблюдаемость результата без работающих моделей.
Приёмка: оператор выполняет весь цикл без инженерных команд; просмотр берётся
с Core, рабочий Worker не нужен. Этапы2–3 могут иметь согласованные инкременты,
но непройденный сквозной сценарий не считается закрытым.
#### 4. Перенос принятой композиции на CUDA-борт — позже
Те же логические модули и версии; аппаратно-совместимая упаковка, локальный
транспорт, долгоживущие процессы/модели вместо старта Docker на каждый кадр.
Квалифицировать полный граф и совместное потребление памяти, не сумму независимых
FPS и не cached replay. Горячие узлы можно позднее объединять по измерениям без
потери логической модульности. Mac Mini не является целевым бортом.
Моторы, автономное движение, ArduRover и safety acceptance — отдельная будущая
работа, сейчас observation-only/policy-shadow.
### Инструкция следующему чату
Прочитать актуальную верхушку Desktop `_MISSING_CORE_…FINAL_STATUS…md`, ADR0051,
этот раздел и handoff report. Проверить `git status`, Core8000 и точные installed
identities read-only; начать с незакрытых контрактов этапа1. Старые installer
scripts с зашитыми predecessor IDs не запускать повторно. Не начинать с новой
полной сборки старого dual-segment LAB V1 или глобального Docker prune.
Не менять Synology/деплой21, Little Snitch, чужие сервисы, Docker Desktop limits.
Не коммитить существующий общий dirty diff как собственную новую работу.
---
## АРХИВ ПРЕЖНЕГО МАРШРУТА — до модульного решения 2026-09-03
Весь следующий текст — история. Слова «актуальный», CURRENT и следующие шаги
внутри него описывают состояние своего инкремента, не текущий план.
# Observatory: четыре этапа — записанные лаборатории → переносимые профили → борт
## Актуальный маршрут — 2026-09-03
Сверено с кодом `bee8552`, установкой `54c8d82`, исправлением reindex `bd947b4`
и последними решениями владельца. M4.9T5 ×004TREE рассчитан через UI, опубликован
и повторно открыт как документ из кэша после перезапуска. Визуальный replay ещё
не реализован для этого portable-результата. Разделы до журнала инкрементов — текущий
и последними решениями владельца. Проверки и сборка текущего инкремента поверх
`eff60e4` завершены; возврат к основному маршруту зафиксирован ниже. M4.9T5 ×004TREE рассчитан через UI, опубликован
и повторно открыт из кэша после перезапуска. Общий camera/TGS replay реализован;
подробная визуальная и memory-lifecycle приёмка ещё открыта. Разделы до журнала инкрементов — текущий
маршрут; исторические «следующий шаг» и «этап открыт/закрыт» ниже не команды.
### Цель и результат
@@ -29,9 +209,11 @@ PASS через Wi-Fi/LTE не является условием готовно
рассчитаны → выбор пуст, «Рассчитать» нет, «Обновить» остаётся. Плашек завершения
нет; во время работы общий индикатор показывает настоящую фазу и доступные счётчики.
Внутри первичного decode/передачи архива детальные счётчики ещё отсутствуют.
Лимит первых 6 карточек снят,
но пагинация сотен записей ещё не доказана.
- **Последняя приёмка:** 726 frontend tests, 128 focused progress/queue/API/
Обсерватория теперь показывает только identity-bound portable результаты;
исторические LAB остаются в Legacy. Каталог дочитывает cursor pages по100
metadata entries (до256 страниц на scope с явным partial flag), поиск видит
все загруженные источники. Fixture500 sources и real20-page proof PASS.
- **Предыдущая функциональная приёмка:** 726 frontend tests, 128 focused progress/queue/API/
transport tests, отдельно40 runtime/wiring и3 installer tests, typecheck/build,
Ruff/mypy и browser QA. Для найденного при рестарте cache-дефекта — ещё89
session/publication и72 admission/cache/queue/API tests. Эти проходы пересекаются,
@@ -47,12 +229,49 @@ PASS через Wi-Fi/LTE не является условием готовно
- **Текущие составы:** M4.9T5 — CPU TGS; LAB V1 — последовательные EoMT и DDRNet.
Ни один не равен полному будущему AI-профилю рига. Архивные overlays в одном
viewer не доказывают, что один Docker вычислил все слои.
- **Последний viewer-инкремент:** primitive-only owner v2 и передача Escape/pointer
из iframe для существующих внешних controls. 740 frontend/64 focused backend
tests, полный typecheck/build PASS, новая сборка обслуживается на8000.
Разделитель native viewer снова передаёт координаты внешним панелям; проверено
контрактным тестом, реальная visual acceptance этой версии ещё не выполнена.
- **Входы Worker, новый инкремент2A:** общий source CAS двух агентов установлен;
другая job/generation/конфигурация переиспользует exact cached bytes, частичная
camera-cache требует только отсутствующие members. M49 проверяет готовый
LiDAR pack до raw decode; прежний producer/identity сохранён.111 focused tests,
Ruff/mypy и реальный cross-agent synthetic proof PASS, моделей не запускали.
Это не кэш viewer (он остаётся на Core) и не устранение cold whole-input barrier.
- **Последний продуктовый инкремент2D:** Legacy separation и pagination активны
на8000 (`app-9nK8VtbK.js`).747 frontend/41 backend tests, typecheck/build,
Ruff/mypy PASS. Browser catalog/search/normal/expanded/Refresh/dropdown Escape
принят; тяжёлый replay не открывался. Legacy API до/после побайтно неизменён.
- **Освобождение памяти:** найден остаток записанного viewer после закрытия.
Добавлены disposable upstream realm, размыкающий ссылки facade и backend
release/TTL. Предыдущий browser proof подтвердил освобождение GPU, но прежний
facade оставил829 MB renderer после закрытия (112 MB до). Для v2 реальный
open/close ещё не проверен: browser auto-review отклонил тяжёлое открытие при
pressure2; запрошено отдельное разрешение. Это не блокирует код/контракты
оставшихся частей этапа2 и не считается доказанным исправлением memory issue.
Активные данные/качество не урезаются, дисковый cache не удаляется.
- **Крупный проход saved review/recovery:** общий viewer подключён к сохранённым
EoMT/DDRNet masks LAB V1 через новый строгий adapter; M49 cache identity сохранена.
Outbox больше не застревает за префиксом exhausted/backoff rows. Краткие
heartbeat transport failures повторяются в пределах аренды с тем же sequence;
новый control layer установлен в оба агента.749 frontend/166 backend tests,
typecheck/build/Ruff/mypy PASS; Core `app-w6onjKPq.js` healthy на8000.
- **Реальный LAB V1 ×004TREE пока FAIL:** новая job
`observatory-run-67a6bf3e4d644e4a8ee3c03b915f8f01` потеряла lease на шаге EoMT.
После независимой проверки освобождения ресурсов штатно reconciled→failed;
история сохранена, очередь11 failed/2 succeeded,0 live leases. Новый LAB не
опубликован. Отдельно подтверждён устаревший EoMT disk floor350GiB сверх
рабочего набора: при текущих397.47GB free admission не пройдёт. Перед повтором
нужна новая sealed resource policy, не очистка данных/не покупка памяти.
[Полный отчёт и точные границы доказательств](../experiments/perception/OBSERVATORY_SAVED_REVIEW_RECOVERY_2026-09-03.md).
- **Есть инженерный прототип полного графа:** DDRNet/RF-DETR/geometry/distance/
motion/TGS/costmap/policy-shadow и короткие потоковые proofs. Не пишем заново.
Самостоятельный продуктовый образ и полный recorded-run этого состава не приняты.
- **Не закрыто:** полный recorded-analysis текущими
профилями, синхронный сохранённый visual replay, матрица двух профилей/записей, полный поиск/
пагинация каталога, standalone и фактический перенос на борт.
профилями, синхронный сохранённый visual replay, матрица двух профилей/записей,
оставшиеся recovery cases, standalone и фактический перенос на борт.
Источники: [ADR 0050](adr/0050-recorded-observatory-first.md),
[cache/UI evidence](../experiments/perception/OBSERVATORY_PUBLISHED_CACHE_2026-09-03.md),
@@ -62,6 +281,8 @@ Desktop final-status — операторская сводка и история
сохранение выполненной работы, не неподтверждённые сведения о runtime.
Текущее исполнение и точные declarations:
[progress / первый запуск](../experiments/perception/OBSERVATORY_RECORDED_PROGRESS_2026-09-03.md).
Последняя сверка и проверки:
[возврат к основному сценарию](../experiments/perception/OBSERVATORY_MAINLINE_RECONCILIATION_2026-09-03.md).
## Границы исполнения
@@ -106,8 +327,12 @@ normal/expanded UI; последний код `e436fb5` и отчёты выше
**Частично выполнено:** bounded attempt-scoped progress реализован и активирован.
Новый M49-run использовал прежний профиль и полностью выполнил его расписание.
Это не закрывает 2A: целиковый input barrier и `_capture_arrays()` до replay-cache
lookup ещё сохранены. Progress observation не является новым режимом исполнения.
Это не закрывает2A: целиковый input barrier ещё сохранён. Новый preparation adapter
проверяет exact LiDAR-cache до вызова прежнего producer, общий source CAS уже
установлен в оба агента. На warm input не повторяются raw decode и передача
готовых members, но cold materialization по-прежнему ждёт весь вход. Progress
observation и warm reuse не являются новым режимом исполнения.
Evidence: [source reuse](../experiments/perception/OBSERVATORY_SOURCE_REUSE_2026-09-03.md).
- Сохранить source timestamps и causal ordering. Медленный Worker притормаживает
подачу, а не выбрасывает обязательные кадры ради 1×. Учитывается каждый вход/
@@ -133,32 +358,45 @@ timeline. Это приёмка CPU TGS, не полного detector/segmentati
точный cache hit, исчезновение M49 из выбора и открытие документа после рестарта.
Найден и исправлен no-op reindex: служебная переиндексация больше не меняет
source identity; реальное изменение по-прежнему требует нового расчёта.
**Осталось в2B:** portable review сейчас JSON, не проигрыватель. Подключить
typed result/frame reader и общий `CanonicalRecordedLabReplay`, ленивое чтение
сохранённых TGS/costmap и точную камеру/временную привязку. Проверить coverage,
seek/play/pause, normal/expanded/restore/Escape и повторное открытие без job.
Сначала использовать уже sealed пакет; не считать заново и не подмешивать
архивные E47/M49 semantics. Название «полный маршрут и воспроизведение» само
по себе не доказывает доступность replay или полноту всей исходной сессии.
Общий `CanonicalRecordedLabReplay` уже получает сохранённый camera/source/TGS
RRD с Core; JSON не является единственным review. **Осталось в2B:** сохранение
ручного ракурса при blueprint activation, подробная визуальная оценка и
подтверждённое освобождение памяти закрытого viewer. Использовать уже sealed
пакет, не считать заново и не подмешивать архивные E47/M49 semantics. Название
«полный маршрут» не доказывает покрытия всех исходных timestamps.
**2C. LAB V1 и другая запись.** Выполнить LAB V1 × 004TREE, затем оба профиля
× RAVNOVES00, строго последовательно. Медленная EoMT не возвращает нас к гонке
за сетевым FPS. Не менять незаметно состав, cadence или разрешение ради PASS.
RAVNOVES01 — отрицательный случай до подтверждённой аттестации.
**Попытка2026-09-03:** LAB V1 ×004TREE запущен штатно, но после transfer и prepare
не завершил EoMT: lease expired, результата нет. Heartbeat retry исправлен и
установлен, exact-job resources освобождены, failed receipt сохранён. Перед
следующим расчётом изменить350GiB disk floor через новую sealed версию с
проверяемым бюджетом рабочего набора; предусмотреть дешёвый preflight до долгих
asset checks и bounded diagnostics до cleanup. Не считать этот canary успешным.
**2D. Повторное использование, сбои и большой каталог.**
- Refresh, повторный вход и перезапуск открывают тот же результат без новой job.
Все текущие профили рассчитаны → выбор пуст, «Рассчитать» нет; новая версия → новый расчёт,
старая остаётся ниже. Проверить transient disconnect, compute failure,
publication retry, missing/corrupt artifacts и отсутствие дубликатов.
- Исторические результаты получают допуск к review только при достаточном
evidence, без подделки provenance. Если binding отсутствует — исправить
проверяемую проекцию либо выполнить новый расчёт, не объявлять legacy новым.
- Довести постраничный поиск записей и результатов. Нельзя спрятать профиль
- **Реализовано:** Обсерватория не показывает Legacy/canonical архивные LAB;
они остаются в существующем архиве без миграции/удаления. Portable результаты
прошлых версий сохраняются при точном binding, независимо от имён и даты.
- **Реализовано и проверено:** постраничный каталог и поиск по загруженным
источникам. Нельзя спрятать профиль
из-за cache hit, соответствующий результат которого нельзя найти/открыть
из-за окна каталога. Сотни metadata entries проверяются функциональными
fixtures, не нагрузкой на Mac и не загрузкой всех видео в RAM.
[Evidence и границы traversal](../experiments/perception/OBSERVATORY_CATALOG_BOUNDARY_2026-09-03.md).
- **Новый recovery proof:** keyset outbox проходит мимо exhausted/backoff rows;
interruption до publish/после publish до ACK восстанавливает тот же результат
без compute. Transient heartbeat/lost ACK повторяет тот же sequence, истёкшая
аренда/чужая identity/HTTP401/403/409 не принимаются. Это contract tests и
установленный control layer, не реальная long-outage qualification.
**Приёмка:** матрица 2 профиля × 2 совместимые записи, полные обязательные выходы,
честный прогресс, published package, сохранённый просмотр без compute после
@@ -218,12 +456,16 @@ watchdog, stop/slow при пропаже данных, моторы и авто
- [x] 2026-09-03 — этап 1: queue/cache/identity/selector реализованы и локально проверены.
- [x] 2026-09-03 — история сохранена, completed-status UI удалён.
- [x] Этап 2A, часть progress — реальные bounded Worker → backend → UI snapshots.
- [x] Этап 2A, warm source reuse — shared CAS и LiDAR early lookup установлены на Worker;111 tests и cross-agent synthetic proof.
- [ ] Этап 2A, остаток — versioned recorded-analysis и устранение полного input barrier.
- [x] Этап 2B, compute/publish/cache — M4.9 ×004TREE завершён; документ повторно открыт после рестарта.
- [x] Найденный reindex-дефект exact cache исправлен; исходная связь восстановлена по точному SHA proof.
- [x] Этап 2B, saved replay — camera/source cloud/TGS в одном native Rerun, выдача с Core после рестарта без compute.
- [ ] Этап 2B, visual acceptance — сохранение ручного ракурса и подробная визуальная оценка; не подменять работающим проигрывателем.
- [ ] Этап 2C–2D — LAB V1/вторая запись, cache/recovery/каталог.
- [x] Primitive-only owner v2 и мост native input:16 focused/740 frontend/64 backend tests, typecheck/build; сборка на8000.
- [ ] Этап 2B/2D, memory lifecycle — GPU/server cleanup проверены в предыдущих циклах; прежний renderer удерживается нестабильно. Browser acceptance v2 отдельно не разрешена auto-review; остальные части этапа2 продолжаются.
- [x] Этап 2D, каталог — Legacy separation, cursor pagination, fixture500 и real20-page proof; UI на8000 проверен.
- [ ] Этап 2C2D — LAB V1/вторая запись и оставшиеся cache/recovery cases.
- [ ] Этап 3 — самостоятельный полный профиль и сравнение конфигураций.
- [ ] Этап 4 — кандидат, затем фактическая бортовая квалификация.
- [x] 2026-09-03 — план и Desktop-сводка синхронизируются с фактическим исполнением.
@@ -236,12 +478,40 @@ Core хранит/выдаёт 193,622,178-byte replay; Worker не нужен
blueprint clone activation. Не объявлять stable source ID сохранением eye;
выбирать только поддержанный native-механизм либо отдельно согласованный upgrade,
не патчить WASM и не создавать второй renderer. Подробная визуальная приёмка открыта.
Первым действием после нормализации памяти Mac повторить browser first-open для
последней правки initial cursor +1мкс; до этого не писать PASS начальной сцены.
Автотесты/build проходят; последняя визуальная проверка остановлена resource gate.
Отдельно закрыть остаток2A версионированным incremental input;
не объявлять прежний whole-recording materializer потоковым.
Не начинать снова с claim/v3, memory repair, селектора или сетевого canary.
Начальный cursor +1мкс показал camera/TGS в промежуточной проверке, но в финальном
expanded first-frame камера была пустой до playback; устойчивость не принята.
Прежний facade функционально работает, GPU715→375 MB освобождается,
но renderer112→829 MB после закрытия. Follow-up с `vmmap`: один цикл834→215 MB
за35с с исчезновением крупных VM областей, повторный812→824 MB за91с.
Это не принято как стабильное исправление memory issue; retained root не доказан.
В коде введён primitive-only owner v2: SDK handles/Promise/errors остаются в iframe,
parent получает JSON-строки, late start и все каналы завершаются независимо.
После решения владельца вернуться к основной работе завершены последовательно
полный typecheck,740 frontend tests,64 focused backend tests и build. Дополнительно
устранена потеря pointer/Escape при iframe boundary для существующих controls;
16 focused tests включают перевод координат native divider и cleanup listeners.
На8000 `app-DHVEqf5x.js`, backend89747 не перезапускался. Build15.14с,
max RSS1994817536 bytes; OOM нет. Swap за интервал финальной сборки вырос
1934.69→2173.69MiB: это не доказательство отсутствия resource pressure.
Browser auto-review отдельно отклонил тяжёлый M49 viewer при pressure2; запрос
владельцу отправлен, обхода не было, проверочная вкладка закрыта. Этот конкретный
visual gate открыт, но он не останавливает работу над input/catalog/contracts.
Подробности: [memory lifecycle](../experiments/perception/OBSERVATORY_MEMORY_LIFECYCLE_2026-09-03.md).
**Непосредственно дальше — основной этап2:** перед повтором LAB V1 исправить
ресурсную политику диска новой sealed версией и сохранение диагностики отказа;
не повторять известный350GiB admission FAIL. Затем закончить2C. Также открыты
versioned recorded-analysis и
incremental input2A, завершение saved-viewer2B, затем последовательная матрица
LAB V1/вторая запись2C и recovery/постраничный каталог2D. Подготовку2A и metadata
fixtures2D можно продолжать независимо от разрешения на тяжёлую browser-проверку.
Прежний `_capture_arrays()` остаётся только в cold producer path нового adapter;
early warm lookup и общий Worker source CAS проверены и установлены. Не называть
их новым incremental execution. Producer SHA pack неизменен; новый input path
должен сохранять старые exact-cache результаты. Memory lifecycle остаётся
критерием завершения операции, не отдельной
бесконечной оптимизацией или условием переписать план. Не повторять claim/v3,
ремонт селектора, Docker VM или сетевой canary. Лабы в целом ещё не закрыты.
## Карта продолжения, проверка и восстановление
@@ -268,6 +538,9 @@ visual entities требуют отдельного решения. Провер
- 2026-09-02, владелец: recorded-first вместо сетевого realtime-first; старые
FAIL сохраняются, лаборатории не зависят от LTE/борта.
- 2026-09-03, владелец: результат внизу вместо completion button/status — реализовано.
- 2026-09-03, владелец: активной операции разрешён необходимый расход памяти;
завершённая обязана освободить временные ресурсы. Не заменять cleanup снижением
качества/новыми жёсткими RAM caps. Little Snitch не трогать; файлы результатов сохранить.
- 2026-09-03, актуализация: этап 1 — реализованная основа, сквозной proof явно
в этапе 2. Это уточнение границы приёмки, не приписывание успешного end-to-end run.
- Desktop17/20, утверждение об отсутствии online prototype и безусловный1×
@@ -110,3 +110,48 @@ not a realtime inference or navigation claim.
- The migration does not improve DDRNet quality, prove terrain traversability
or grant navigation/actuation authority. Those remain separate model and
safety acceptance questions.
## Resource ownership addendum — 2026-09-03
An active calculation/view may allocate what its admitted workload needs. On
termination its ephemeral resources must become releasable; lowering evidence
quality or deleting durable results is not a substitute for lifecycle cleanup.
Recorded viewers run the same unmodified upstream SDK in a disposable,
same-origin iframe inside the existing viewer surface. A small synchronous
facade exposes only the public methods already used by the product adapter.
The revision-2 boundary returns primitive JSON strings, including events and
errors; the parent parses them in its own realm. Native handles, DOM nodes,
channels, unsubscribe closures and SDK startup Promises stay inside the iframe.
Parent-owned RRD bytes enter a synchronous channel call, without transfer or
changing the payload/quality. Parent startup Promises are settled by primitive
notifications and rejected on disposal. Every channel is closed independently;
a late SDK startup completion is stopped again. Teardown severs references and
removes the iframe. There is still exactly one native renderer and clock,
no new playback UI, SDK patch or second backend. The live source path stays
direct upstream. Page-cache restoration starts a fresh viewer lifecycle.
The iframe relays only Escape and primitive pointer fields to parent-owned
events for the existing outer controls. Coordinates are translated by the
iframe bounds, including the native-chrome crop. Native Rerun still owns its
canvas gestures and divider; nothing is cancelled or sent back to the canvas.
The parent tracks the same divider for control alignment, not a second layout
or renderer. Teardown removes every relay listener and foreign frame reference.
The backend's ephemeral blueprint store has an exact viewport owner, explicit
release, idle expiry (300 seconds; reaped every 30 seconds), and shutdown cleanup.
An open owner renews every 30 seconds. Release is serialized with rendering;
late updates for that released identity are rejected. Expiry never stops an
active render, a recording, a Worker profile or a vehicle. Durable files are not
removed. The pre-existing 32-entry cache bound is unchanged; no new active data
or image-quality cap is introduced.
DOM disappearance is not memory acceptance. Compare process footprints before,
during and after ordinary sequential open/close cycles without forced GC or
page reload. See the dated memory-lifecycle report for measurements and limits.
Revision 2 and the input relay passed full typecheck, 740 frontend tests,
64 focused backend tests and a production build, served on canonical 8000.
Real browser acceptance of this revision remains pending: auto-review rejected
opening the heavy saved viewer under elevated pressure; explicit owner approval
was requested. This does not gate unrelated input/catalog contract work, nor
does a successful build prove that the recorded memory retention is fixed.
@@ -1,5 +1,10 @@
# ADR 0050 — Recorded Observatory first; portable profiles then onboard
> 2026-09-03: [ADR 0051](0051-modular-observatory-profiles.md) now defines
> modular Docker composition and grouped single-provider settings. Its UI and
> packaging rules supersede the finite whole-profile selector/one-image target
> below. Recorded-first, exact cache, preserved evidence and safety remain.
Date: 2026-09-02. Decision accepted by the owner; implementation in progress.
This supersedes ADR 0049's realtime-first product gate and execution order,
not its live-stream integrity, ownership or safety contracts.
@@ -182,6 +187,29 @@ See [real-run and restart evidence](../../experiments/perception/OBSERVATORY_REC
## Boundaries
Owner clarification, 2026-09-03: Observatory's result list includes only admitted
portable-profile publications, not every historical LAB linked to a source.
Legacy contours, canonical archive projectors and stored evidence remain
unchanged. Filter by executable replay/publication binding, never by LAB label,
date, model name or equality to the currently installed definition. Older valid
portable versions remain reviewable. Versioned opt-in cursor pages feed the
existing source search; legacy catalog consumers retain their previous response.
See [catalog boundary evidence](../../experiments/perception/OBSERVATORY_CATALOG_BOUNDARY_2026-09-03.md).
Source-reuse increment (2026-09-03): both current control agents now share a
Worker-local source CAS. Every generation still obtains its own authenticated,
claim-bound manifest and checks exact digest/length before reusing bytes. Missing
camera members are fetched individually instead of retransferring a partly cached
epoch. Job/output/profile identities and model packages are unchanged. Cached
visual results remain served by Core, not this Worker input cache.
M49 now selects an exact current-producer LiDAR v2 pack before raw decoding;
the legacy producer file and its identity hash remain unchanged. Full source
hash and strict NPZ integrity validation still occur on reuse. Cold whole-source
materialization, versioned recorded-analysis and full workflow acceptance remain
open. Shared-cache synthetic Worker proof is not a model run or a throughput
measurement. See [source-reuse evidence](../../experiments/perception/OBSERVATORY_SOURCE_REUSE_2026-09-03.md).
No Synology deployment, hardware actuation, motor integration, new capture,
silent model substitutions or deletion of recordings/results. A Docker image's
portability does not promise that a CUDA build runs unchanged on Apple Silicon.
@@ -0,0 +1,181 @@
# ADR 0051 — Modular AI containers and composed Observatory profiles
Date: 2026-09-03. Owner-approved target; the first local modular vertical slice is installed.
## Decision and supersession
A reusable module is an independently packaged Docker image for a model or a
cohesive algorithmic function. A profile is an immutable, validated composition
of module versions, parameters, input/output connections and execution policy.
A LAB run applies that composition to an exact recording snapshot. A new
combination does not require building another image containing all models.
This replaces the earlier **one full profile = one image/container** packaging
requirement in the historical plan. It keeps ADR 0050's recorded-first purpose,
ADR 0048's generic installed-package boundary and the stream contracts from
ADR 0049. Several containers are not intrinsically a defect. Per-LAB application
forks, hidden host dependencies and duplicated data preparation remain defects.
The future onboard host is CUDA-capable, architecture/runtime compatible
hardware. It is explicitly **not Mac Mini**. Exact CPU architecture, GPU,
driver and inference-runtime compatibility still need target qualification;
CUDA availability alone is not a promise that every existing image will run.
New owned module images/containers use the `ndc-` namespace, readable model or
function names, explicit versions and ownership labels. A composition has its
own readable LAB label; module/composition/job identities are linked in runtime
metadata. A reused module need not be renamed to match every LAB that uses it.
## Operator composition
Each recording exposes AI-layer settings inside the existing Observatory.
Use functional groups with a single-choice Select, not a checklist of arbitrary
containers. Segmentation admits **at most one** provider: DDRNet or EoMT, never
both in the same new LAB. Optional groups may offer None if the resulting graph
still satisfies its declared outputs. A geometry-only or segmentation-only LAB
is valid and must not claim the omitted capabilities.
Candidate groups are segmentation, object detection, LiDAR/TGS geometry and
costmap, object/range association, motion and policy-shadow. Their final physical
module boundaries follow existing code ownership and measured data exchange,
not a mandatory container per mathematical operation. Multiple capabilities
provided by one module do not instantiate that module multiple times.
The server validates provider cardinality, dependencies, source capabilities,
calibration/time frames, output contracts and installed Worker versions. A client
cannot supply executable argv, image names, host paths or arbitrary resource
settings. Invalid dependencies are explained, never silently supplemented by
old LAB overlays or an unselected second segmenter.
An exact existing published composition is opened, not recomputed. The settings
remain editable so the operator can create another composition. There is no
Calculate action for a complete exact cache hit, no “calculation complete”
button/badge, and no duplicate LAB. The grouped selectors keep already-used
providers: completion belongs to the whole composition, not to an individual
dropdown option. This supersedes the old finite-profile selector grammar, not
its exact-cache and idempotency guarantees.
## Execution, identity and caches
- Keep one recorded owner on Worker006 and serialize heavy GPU execution.
Selecting several modules does not authorize concurrent GPU model jobs.
- Share source delivery/preparation locally on Worker. Intermediate image/point
buffers do not round-trip through Core between modules. Do not reintroduce
whole-recording upload/decode as a permanent streaming-start prerequisite.
- Keep a common timestamped, bounded I/O contract with explicit sensor gaps,
coordinate frames, unavailable outputs and causal temporal state. Recorded
analysis may be slower than acquisition; live has separate freshness gates.
- Freeze graph topology, module image/weights/code/config identities, input
identities, preprocessing, calibration, cadence, precision and state policy.
Canonical ordering of the selection UI is not part of the semantic identity.
- Reuse a node only for exact validated inputs and producer identity. A changed
detector invalidates its dependent range/motion results, not an independent
segmentation result. Stateful reuse also binds initialization and history.
- Final LAB/cache publication remains on Core. Worker source/preparation caches
are not the final viewer store. Failed publication retries the sealed result,
not inference. A partially cached graph is not a complete ready LAB.
- Record reused versus computed nodes and provenance. Cache playback or cached
composition assembly is never reported as measured onboard processing FPS.
Onboard modules are long-lived within a mission; do not start a container or
reload weights per frame. Resident memory, local transport, bounded queues and
end-to-end latency require a joint benchmark. An optional later co-location of
hot nodes is a measured deployment optimization, not a reason to remove logical
modularity. No automatic actuation or navigation acceptance is introduced.
## Current implementation and migration
Current M49 runs CPU TGS in its specialized agent. Current LAB V1 is an installed
fixed stack: prepare → EoMT → DDRNet → assemble, with host-bound model/runtime
assets. Neither is the new modular composition system. Keep the successful M49
publication and exact existing releases; retain old dual-segmentation results
as historical comparisons, without admitting that combination in new profiles.
Reuse `InstalledLabPackage`, its generic launcher, queue/claim/recovery, source
CAS, verified publication and common viewer. Extend the versioned contracts for
compositions and per-node reuse. Do not redesign the queue or create another
agent per model. Source CAS alone does not implement intermediate-result reuse.
The owner authorized Worker cleanup. Classify every exact container/image/cache
against running services, pinned packages, model assets, rollback and retained
evidence before deleting. Stopped instances can be retired independently of
images and volumes. Preserve raw recordings, published LABs, Legacy views,
required source/model caches and one usable rollback; no global Docker prune.
The accepted EoMT disk floor is now **250 GiB plus its working-set estimate**.
Source and narrow tests have changed; installed EoMT still has 350 GiB until a
new sealed image/release is activated. Never patch a historical digest in place.
## Acceptance and route
Done means: select one provider per group; compute two distinct compositions on
compatible recordings with exact cache reuse; view their complete bound outputs
from Core; recover publication without compute; prove exclusive GPU scheduling
and cleanup; cold-start the selected module distribution without developer
checkout or unlisted caches. Onboard qualification remains future work.
The historical combined route remains documented in
[the four-stage ExecPlan](../OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md).
## Local implementation record — 2026-09-03
The first implemented slice replaces the Observatory's fixed profile selector
and separate refresh/calculate controls with one always-available
`Сконфигурировать AI-слой` action for the selected source. Its canonical Window
contains functional groups, one provider Select per group, the close action and
one `Рассчитать` action. The Window uses background, spacing and typography for
grouping; it has no group outlines, header divider lines or modal rim.
DDRNet and EoMT are independent alternatives in the Segmentation group. They
share only the model-neutral `camera-source` preparation step and neither model
consumes the other model's result. The installed module repositories and exact
local image identities are:
- `ndc/mission-core-ai-module-camera-source`
`da926459aee0a841bbdfaf80a0eb5fbead354c56794d1f3384eeba66d0a49e00`;
- `ndc/mission-core-ai-module-ddrnet`
`489fc7d1157fd0f1cd1d82e06a15737b7b2aaaf72b2ddb2aca2992b91a97488e`;
- `ndc/mission-core-ai-module-eomt`
`5b770178e4a5c8fbe8f8ddab3b83a598973dbe103b669851110b11a0918ab846`;
- `ndc/mission-core-ai-module-rf-detr`
`2b8b44be8e9ee4060aa6997fc4c025ad7120f37ecd720a9e59b5e02ac6c90f66`;
- `ndc/mission-core-ai-module-object-distance`
`69d68f64981b41e5bcce1e642433e3d466b88c51942a5ba3aec9180d8ed04263`;
- `ndc/mission-core-ai-module-tgs`
`f9278ab21aa65045be993dd19bffc25f49955e19598893ac78cc4761ca63ecf3`.
The executable graph also contains `ai-detection-rf-detr-v1` for image-space
boxes and `ai-range-object-distance-v1` for box-to-LiDAR association. The range
package executes RF-DETR as its explicit dependency, then uses synchronized
LiDAR, pose and calibration to estimate range. TGS consumes LiDAR, pose and its
own history independently. Selecting TGS and range therefore produces two
independent durable jobs; segmentation does not feed either of them. The common
Worker agent launches package steps with job-specific container names under
`ndc-mission-core-ai-module-*`, serializes GPU work, publishes a
`missioncore.recorded-ai-layer-review/v1` result and leaves the historical
combined LAB V1 and Legacy contour intact.
Submission creates a durable Observatory job immediately. The source-bound
evidence area shows its selected configuration, current phase, measured
progress and an estimated remaining time. A published result moves into the
existing evidence list and uses the same open, rename and delete actions as
the other portable LAB results.
The active Worker 006 directory release is `20260903-v5`, release SHA-256
`a87c82adfa1058f14f850f488ace38e5c7c9d9e2145d4678a81b52f2a1aad573`.
Its common agent image SHA-256 is
`d6f2ef1a3f38ebc8503b62296ca9def10472a60a41ffc5edd123df565520dec8`.
The DDRNet, EoMT, RF-DETR and object-distance definition SHA-256 values are
respectively
`b04206a8472588fee22e0282228e51b7817c80f9739180e834b704733d7aaf76`,
`6d13402883e8fa79a8ea97b15e81e704d3c0f9dac5d94445e5e53c18dcebe98f`,
`a89f51a66a070deb50f4904f596545cdcd7289df7e42b8511aec9547dedd52e8`
and `cc56e72fdfb38565a0b402c90a91917821463d980f5855e4cdf4d8b9f262a94c`.
The standalone detector and composite range package have distinct resource
profile identities, so their otherwise shared RF-DETR model manifest cannot
collapse into one executor registration. All four package executor identities
are unique. DDRNet, EoMT, RF-DETR and object-distance pass live source,
executor, sealed-definition and durable-queue preflight for
`20260828T130511Z_viewer_live`; the published M49 TGS result is an exact cache
hit. No new full-recording RF-DETR or object-distance inference was run as part
of this installation acceptance.
@@ -0,0 +1,68 @@
# Missing Core Observatory domain ontology v1
Status: local runtime canonical. Owner: NODE.DC Mission Core.
The Observatory now has four independent consumers of the same relationships:
composition validation, Worker job dispatch, LAB/result projection and replay
controls. The previous typed-contract-only approach lost the relation between a
multi-module submission and its member results. This satisfies the local
ontology admission gate in `docs/18_APPLICATION_COMPONENT_ARCHITECTURE.md`.
The executable source is `config/observatory-domain-ontology.json`. It defines
transport and equipment units, time-bounded equipment mounts, capture profiles,
recorded sessions, module versions, immutable compositions, append-only
composition runs, container images, worker nodes, jobs, portable results, LAB
projections, viewer panes and viewer layers. These are peer subjects with independent identities and
lifecycles. A per-result LAB view profile owns the operator's mutable SLAM
display choices. The entities follow the NODE.DC Platform ontology architecture without making
Platform a dependency. Its named queries are recording capture context,
configuration label, member results, viewer layers and ready state.
A recorded session binds to the transport, equipment units, equipment mounts
and exact capture profile that produced it. A composition run points to that
session and never substitutes its own identity for transport or equipment. This
keeps future vehicle and sensor changes separate from model configuration and
from the published evidence.
A module version is implemented by an immutable container image. Installation
of that image on a worker and execution of a recorded job on a worker are
separate relationships, so Worker 006 is not encoded inside the module identity.
The replay layer remains a capability of the module version and can therefore be
derived through the module-to-image relationship without coupling UI controls to
a Docker runtime instance.
One saved composition is opened by one Rerun viewer and one shared recording
clock. Camera, LiDAR, depth and future sensor views are panes inside that viewer's
blueprint. Every pane owns its layer controls; the overlay follows the pane bounds
when a separator moves. A second Rerun viewer is reserved for a genuinely
independent recording or clock, because duplicating a viewer per pane would also
duplicate the recording transport, memory and synchronization work.
Pane construction is projected from module capabilities. DDRNet and EoMT create
only the camera pane with their independent segmentation layer. RF-DETR creates
the camera pane with object frames. TRAVEL TGS creates only the spatial pane with
source points, local SLAM and TGS. Object distance composes the camera detections
and spatial LiDAR panes it needs. Combining modules takes the ordered union of
these pane layers, so a configuration cannot invent an unrelated camera or point
cloud viewport.
Operator SLAM display settings belong to the published LAB result identity. They
are mutable presentation state, stored atomically in the Mission Core runtime,
and are loaded again after browser storage is cleared. They do not modify the
immutable calculation result, module configuration or recorded evidence.
Identity and lifecycle remain owned by the existing stores. The ontology does
not replace their contracts and does not contain executable commands, mutable
container instances, paths or resource grants. Image digests and worker
identities remain facts supplied by their owning registries. The ontology
projects their exact identities into one shared relationship model.
Version 1 uses additive migration for existing single-module results. A recorded
composition run may reference an already published exact module result; this is
recorded as reuse, not a new inference. Failed attempts remain audit evidence and
do not satisfy the ready-state query.
There is no runtime dependency or write path to NODE.DC Platform Ontology. The
Platform repository supplied the package architecture only. Synchronization is
`none` until a meaning becomes stable across products and receives a separate
owner-approved migration.