Document AI Inference architecture and freeze current baseline

This commit is contained in:
DCCONSTRUCTIONS
2026-09-05 10:05:01 +03:00
parent e56eb42507
commit 57f2537af3
19 changed files with 5280 additions and 53 deletions
@@ -0,0 +1,15 @@
# Исторические исходники AI Inference
Полные побайтные копии двух Desktop-отчётов, заархивированные 2026-09-05.
Размеры и SHA-256: [manifest.json](manifest.json).
Текущий архитектурный срез и интерпретация старых результатов:
[AI Inference — принципы и архитектура](../../audits/2026-09-05-ai-inference-architecture.md).
Полный актуальный контекст также опубликован отдельной картой AI Inference в Ops / MISSION CORE.
Эти исходники исторические. Содержащиеся в них планы, слова CURRENT, «следующий
шаг» и старые требования к монолитной упаковке не являются текущими инструкциями.
Их даты измерений и ограниченная область доказательства сохраняются.
Оригиналы на Desktop автоматически не удалялись. После публикации этого архива
они могут быть удалены владельцем без потери именно этих двух документов.
@@ -0,0 +1,488 @@
# Mission Core / Missing Core — сверка модульной Обсерватории и план реализации
Дата: 3 сентября 2026. Срез runtime: 16:2116:35 UTC. Режим: исследование и планирование.
## 1. Вывод и границы этого прохода
Нужная модель продукта ясна: выбранная запись K1 → «Сконфигурировать AI-слой» → выбор независимых возможностей и моделей → расчёт точной композиции → сохранённая LAB. На одной записи допустимы несколько разных композиций; одна композиция применяется к разным совместимым записям.
Существующий код даёт хорошую основу очереди, transport, проверяемых входов, запуска Docker и публикации. Однако операторский конструктор, независимые модельные контракты и повторное использование результатов отдельных узлов ещё отсутствуют. Наличие отдельных контейнеров EoMT и DDRNet не означает их независимость: DDRNet сейчас читает входные кадры из результата EoMT.
В этот проход:
- Прочитан актуальный раздел 0.46 Desktop-документа, изучены связанные ADR, план, handoff и релевантная история. Указания внутри документов рассматриваются как контекст, а не как новый запрос на исполнение.
- Изучены карточки MISSION CORE через прямой Ops MCP, backend, frontend, generic Worker runtime, текущие adapters и полный экспериментальный graph.
- Выполнено реальное SSH-подключение к Worker 006, прочитаны Docker inventory и installed manifests; проверен HTTP-доступ к Core из обоих агентов.
- Исходники, установленные сервисы и Legacy не изменялись. Новые jobs, builds и inference не запускались. Контейнеры, images, volumes и caches не удалялись.
- Канон деплоя DCPLATFORM-21, Synology и rollout на борт в этот проход не применялись.
- Созданы только этот отчёт и приватные файлы сверки.
## 2. Что именно изучено
Рабочая копия: /Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory.
Ветка: codex/m5-1-observatory. HEAD: eff60e4.
В копии есть многочисленные ранее внесённые tracked/untracked изменения. Они сохранены и не считаются результатом этого прохода.
Backend — Python 3.12, FastAPI, SessionStore, artifact gateway, SQLite queue, portable registries.
Frontend — React 19 / TypeScript / Vite; NODE.DC UI packages; Rerun 0.36.3.
Авторитетная запись и управление K1 принадлежат Core и K1 plugin. Worker создаёт производные результаты.
| Область | Основные исходники |
|---|---|
| Сборка backend и подключение сервисов | src/k1link/web/app.py |
| API оператора | src/k1link/web/observatory_api.py |
| API Worker | src/k1link/web/observatory_worker_api.py |
| Реестр полных профилей | src/k1link/observatory/portable_run_definitions.py, portable_setup_projection.py |
| Admission и привязка к записи | source_admission.py, portable_queue_binding.py |
| Очередь, аренды, idempotency, publication state | recorded_jobs.py |
| Worker service и выбор executor | worker_service.py, worker_agent.py |
| Передача исходников и результатов | worker_http_transport.py, portable_artifact_transport.py |
| Общий source CAS | worker_source_cache.py |
| Установленные пакеты и запуск Docker | installed_lab_packages.py, installed_lab_package_runner.py, installed_lab_worker_service.py |
| Текущий LAB V1 | lab_v1_installed_package_steps.py, portable_lab_v1_executor.py; experiments/perception/worker/observatory_portable/ |
| Текущий M49 | m49_worker_service.py, m49_portable_executor.py, m49_portable_source.py |
| Сохранение и повторное открытие | portable_result_publisher.py, portable_result_cache.py, portable_publication_reconciler.py |
| Контракты просмотра | portable_replay.py, portable_semantic_replay.py, portable_tgs_replay.py, portable_result_view.py |
| Обсерватория frontend | apps/control-station/src/workspaces/observatory/ObservatoryWorkspace.tsx |
| Каталог, выбор, jobs и progress | apps/control-station/src/core/observatory/ |
| Общий LAB viewer | apps/control-station/src/components/laboratory/PortableResultReplay.tsx, CanonicalResultRerunReplay.tsx |
| Lifecycle spatial viewer | apps/control-station/src/components/RerunViewport.tsx и components/rerun/ |
| Полный экспериментальный graph | experiments/perception/worker/streaming_profile_stage1/pilot_graph.py, run_joint_pilot.py, pilot_model.py |
| Реальные алгоритмы | src/k1link/perception/{detector,geometry,motion,temporal,rolling_map,threat,rf_detr_native_object_detector}.py |
| Системная телеметрия | src/k1link/web/system_telemetry_api.py, src/k1link/compute/pipeline_telemetry.py |
Пути без префикса в строках таблицы относятся к src/k1link/observatory/.
Опорные документы: ADR0051, верхний текущий раздел OBSERVATORY_REALTIME_PROFILES_EXECPLAN, OBSERVATORY_MODULAR_HANDOFF_2026-09-03, каноны UI/компонентной архитектуры. Канонические Window, FieldFrame, Select и WindowFooterActions подтверждены в registry/components.json Design Guideline.
В Ops прочитаны, в частности:
- №73 «Обсерватория — модульные профили: решение и сверка Worker» — прямой контекст нового решения; карточка в Backlog.
- №71 «Milestone 5 · OSS-конструктор Mission Core» — общий M5 и границы Observatory.
- №50 «Фундаментальная архитектура Mission Core».
- №9 «Mission Core AI Server Worker — RTX 4090».
- №47 «[Mission Core] Worker telemetry: agent → MQTT → Timescale».
- №62/63 — отдельные TGS и integrated reference-graph испытания.
- №64/66 — sealed playback и канон интеграции Rerun.
Также просмотрены связанные карточки Worker, исходной архитектуры, LiDAR и perception. Исторические показатели этих карточек не выдаются за приёмку новых модулей. Чтение комментариев №73 завершилось транспортной ошибкой Ops MCP; содержимое самой карточки получено. Записей в Ops в этом проходе не было.
## 3. Фактический runtime
### Core
- http://127.0.0.1:8000/api/health: operational=true.
- PID 2421 слушает 127.0.0.1:8000; listener на 8765 не найден.
- Recording cache: 20 entries, 653 266 743 bytes.
- Artifact cache: 9 pinned objects, 721 626 746 bytes.
- Background reconciler работает; на последнем срезе consecutive_failures=0.
- В очереди 13 jobs: 11 failed, 2 succeeded, активных jobs и live leases нет.
- Из двух succeeded одна имеет publication_state=published, другая — историческое not-required. Это не две заново принятые модульные LAB.
Текущая опубликованная portable LAB:
job observatory-run-b230216709dc4c59bc56c98c7e329bf1;
result m49-tgs-portable-review-a09d2b4a07d103e4f3693ba746a51be2197214768774eabfded4f109ae80dce4.
Каталог API подтверждает open-existing для M49 × RAVNOVES004TREE без разрешения повторного вычисления. Последняя LAB V1 job observatory-run-67a6bf3e4d644e4a8ee3c03b915f8f01 остаётся failed, результата нет.
### Worker 006
SSH alias mission-gpu разрешён существующей конфигурацией в desktop-opj8j04.tail8d32ac.ts.net; hostname действительно DESKTOP-OPJ8J04.
| Объект | Текущий факт |
|---|---|
| GPU | RTX 4090; driver 610.47; 24 564 MiB |
| Моментальный GPU snapshot | 1 778 MiB занято, utilization 14%; это общий счётчик устройства, не замер нового LAB |
| Контейнеры | 11 всего: 7 running, 4 stopped |
| Images / named volumes | 80 / 9 |
| Generic Observatory agent | be85dc40147a; image bfdc94ae5190…; running, restart count 0 |
| M49 Observatory agent | d58b3872d2ab; image e545a47a7ea2…; running, restart count 0 |
| Rollback-пара | a01b0fc675a0 и c51bd8d95a85; stopped |
| Frigate / Ollama | stopped, restart=no |
| Прежние Gaussian | gateway/pipeline unhealthy; terrain executor healthy |
| Прежний perception worker | running на срезе, RestartCount=450 |
| Прежний Triton | healthy |
Повторно проверено наличие image полного прототипа:
sha256:986dbe7126992359c69da0ddda674925a5efe8e3429a6d5f60765f9c9ad34a4e
(tag ndc-k1-perception-ddrnet39-rfdetr-tgs:stage1-joint-20260901).
Сверены SHA-256 пяти файлов внутри работающего generic agent с checkout: worker_agent.py, worker_http_transport.py, worker_service.py, worker_source_cache.py, installed_lab_package_runner.py. Все пять совпали. Поэтому замечания об этих участках относятся и к проверенному установленному агенту.
### Текущие вычислительные пути
LAB V1 package:
1bc84be07634ff69ac7459a2c39dc8fc9bcee33f72985dfa2c6088bb78976d8e.
| Шаг | Image SHA-256, начало | GPU | Лимит RAM контейнера |
|---|---|---:|---:|
| prepare | 5ad7d95baac6… | 0 | 4 GiB |
| eomt | adba3dc8c97b… | 1 | 24 GiB |
| ddrnet | e6c986100613… | 1 | 16 GiB |
| assemble | 5ad7d95baac6… | 0 | 8 GiB |
Это фиксированная последовательность prepare → EoMT → DDRNet → assemble. Лимиты RAM не являются квотами VRAM.
M49 выполняет подготовку и CPU TRAVEL TGS через установленный бинарник внутри специализированного агента. Это ещё не самостоятельный модуль общего composer runtime.
Согласно handoff, сохранённый M49 обработал 6 830 camera anchors, 6 811 LiDAR bindings, 19 UNOBSERVED за 1 416.763 s. Покрытый интервал 39.215–757.160 s внутри записи длительностью 808.779 s. Эти числа в этом проходе не пересчитывались; свежо подтверждены queue/result binding и доступность сохранённого результата.
### Отдельное расхождение: hardware telemetry сейчас не работает
Свежая проверка /api/v1/system/worker-telemetry:
source=agent-mqtt, reachable=false, error_code=telemetry-agent-unavailable.
Дополнительные read-only проверки:
- 127.0.0.1:18030/health: Connection refused.
- Docker API Mac по текущему socket недоступен.
- Windows service telegraf / «NDC Mission Core Telemetry Agent»: Stopped.
Вычислительные Observatory agents при этом видят Core. Нельзя объединять эти два состояния в «Worker недоступен» или «вся телеметрия работает». Причина остановки не устанавливалась. Для будущих ресурсных замеров нужно отдельно вернуть телеметрию либо явно определить ограниченный measurement path; автоматического запуска служб в исследовании не было.
## 4. Как сейчас идут задания и данные
~~~mermaid
flowchart LR
UI["Обсерватория · React"] --> API["Core API · 8000"]
API --> Q["SQLite queue · exact identity"]
W["Worker agent"] -->|"pull claim v3 / heartbeat / progress"| API
Q -->|"sealed job"| W
A["Core source / artifact API"] -->|"verified source bytes"| CAS["Worker source CAS"]
CAS --> P["Подготовка записи"]
P --> C["Установленный executor / fixed-stack"]
C --> R["Запечатанный результат"]
R -->|"manifest + members"| O["Core publication / outbox"]
O --> S["Saved LAB / artifacts"]
S --> V["Общий viewer на Core"]
~~~
Фактический путь HTTP из каждого агента:
127.0.0.1:18080 внутри контейнера → фиксированный TCP bridge → host.docker.internal:18080 → существующий reverse SSH tunnel → Core 127.0.0.1:8000.
Mac-owned tunnel описан в worker_tunnel_launchd.py:
-R 127.0.0.1:18080:127.0.0.1:8000 через mission-gpu.
Оба текущих агента используют BASE_URL=http://127.0.0.1:18080 и общий /source-cache.
Это текущий лабораторный transport. Экспериментальные gRPC/binary streaming adapters полного graph существуют отдельно; они не заменяют установленную recorded queue.
Основные свойства, которые нужно сохранить:
1. Frontend передаёт идентификаторы данных, а не shell/Docker команды.
2. Core проверяет запись, source snapshot и доступную версию executor.
3. Queue атомарно исключает дубликаты и выдаёт одну активную аренду для recorded compute; сохраняет fencing/generation и границу live K1.
4. Worker проверяет exact identities и claim, получает bounded source streams.
5. Generic launcher разрешает только установленные images/assets/argv, идёт по dependency order, запускает шаги последовательно и удаляет принадлежащие запуску временные контейнеры.
6. Результат проверяется и публикуется на Core. Core outbox умеет повторять публикацию уже принятого пакета без inference.
7. Saved viewer читает запись и сохранённые артефакты с Core.
Телеметрия оборудования — отдельный путь:
Windows Telegraf → MQTT → normalizer → Timescale → Core System API.
Job progress передаётся собственным Observatory HTTP-протоколом и не должен зависеть от доступности MQTT.
## 5. Существенные разрывы между текущим кодом и composer
### 5.1 DDRNet не независим от EoMT
run_portable_lab_v1_ddrnet_component.py:139 вызывает _validate_eomt_input.
lab_v1_installed_package_steps.py:202 формирует для DDRNet eomt_result_root и source-frames из EoMT step. Installed manifest объявляет depends_on=[eomt,prepare].
Нужен самостоятельный output подготовки камеры: decoded-frame index, verified frames/chunks, source timestamps, valid-FOV/preprocessing metadata и decode-repair accounting. DDRNet и EoMT должны потреблять его независимо. Нельзя снять dependency только в JSON.
### 5.2 Package registry уже поддерживает DAG, но только фиксированный пакет
installed_lab_packages.py:192 связывает package с одним definition_sha256 и runtime_candidate_sha256.
worker_service.py:380 строит ready registry по этим точным парам.
worker_agent.py:428 выбирает только заранее установленную executor identity.
Следовательно, простое добавление React Select не создаёт динамические композиции. Нужны server-owned composition registry и проверка плана на Worker по локальному реестру модулей. Новая комбинация не должна требовать image build, ручного installer или нового agent.
### 5.3 Нет общего результата произвольного набора слоёв
PortableResultReplay.tsx:18 распознаёт конкретные M49 и EoMT+DDRNet schemas.
portable_semantic_replay.py:67 ожидает одновременно city_masks и vegetation_masks, обе component identities и их artifacts.
lab_v1_installed_package_steps.py:158 собирает именно два component result.
Нужен versioned result с inventory фактически вычисленных capabilities, общим source clock, coordinate frame, taxonomy и artifact references. Пример: detector-only публикует boxes/classes/scores; segmentation-only — masks/taxonomy; range появляется только при наличии соответствующего вычисления.
### 5.4 Source admission шире потребностей отдельных алгоритмов
Нынешние два профиля требуют camera + point-cloud + trajectory, точную camera/calibration identity и одну media epoch. RecordedSourceRequirements в portable_run_definitions.py требует video даже в общем типе.
Для частичных композиций требования должны выводиться из выбранного графа. Segmentation и detector не должны автоматически требовать LiDAR. Для LiDAR-only режима нужно отдельно определить timestamp anchor и поддерживаемую аттестацию источника; нельзя просто убрать video из проверки текущего camera-anchored M49.
| Запись, API-срез | Текущее состояние |
|---|---|
| RAVNOVES004TREE, 808.779 s | video + cloud + trajectory; оба старых профиля source-compatible, M49 уже сохранён |
| RAVNOVES00, 535.718 s | video + cloud + trajectory; оба старых профиля source-compatible |
| RAVNOVES01, 517.468 s | cloud + trajectory; нет video; оба профиля сейчас блокируются уже по capture-attestation-missing |
RAVNOVES01 — отрицательный тест текущего admission, а не уже допущенный LiDAR-only источник. Новый режим требует отдельной проверки фактической аттестации, временных и пространственных данных.
### 5.5 Полный прототип нельзя переносить как готовый универсальный модуль
pilot_graph.py использует настоящие detector/geometry/motion/TGS алгоритмы, но также:
- жёстко заданные RAVNOVES00/session IDs;
- camera 800×600, конкретную KB4 calibration и valid-FOV;
- DDRNet crop/resize 600→512 и конкретный GOOSE mapping;
- связывает TGS rasterization, material projection, препятствия и policy в одном costmap method;
- удерживает state surface/association/temporal/rolling/history.
Нужны adapters из общего SourceEnvelope, явные image transforms и taxonomy maps. EoMT нельзя подставить вместо DDRNet в этот method без mapping/geometry contract.
### 5.6 Source CAS и финальный result cache уже есть; per-node cache отсутствует
worker_source_cache.py повторно использует точные исходные bytes.
portable_result_cache.py проверяет уже опубликованный полный LAB.
Промежуточные steps сейчас принадлежат попытке конкретной job. Нет независимой идентичности node-result, reusable across compositions. На cold path сначала завершается materialize всего входа, затем запускается runner. Бounded передача файлов уже есть, но это ещё не progressive compute.
### 5.7 Cancellation/lease loss нужно довести до самого executor
worker_agent.py:524 запускает adapter.execute синхронно и проверяет heartbeat.failed после возврата.
installed_lab_package_runner.py:326 ждёт Docker not-running; отдельного cancellation token между heartbeat и launcher нет.
Cleanup после выхода/ошибки существует. Однако быстрое освобождение ресурсов при потере аренды или operator cancel этим не доказано. Новому runtime нужны общий cancellation context, прекращение выдачи новых chunks, остановка точных child containers/processes, bounded join и подтверждение освобождения перед следующей GPU-job. Это вывод из проверенного кода, не проведённый здесь аварийный эксперимент.
### 5.8 Packaging и установленная resource policy ещё расходятся с целью
EoMT использует host-mounted Python/environment/transformers/model cache/runner/FFmpeg. DDRNet использует mounted checkpoint/mapping/runner и старый vegetation adapter. Это явные текущие зависимости, но ещё не переносимый модуль без developer layout.
В checkout EoMT DISK_FLOOR_BYTES=250 GiB. По последнему handoff установленный step image содержит прежние 350 GiB; точный installed image в этом проходе совпал с тем handoff. Внутренний файл stopped compute image заново не извлекался. Изменение policy требует новой immutable версии, а не редактирования прежнего digest.
### 5.9 Системная видимость Docker сейчас задана старым списком
system_telemetry_api.py:34 и :1163 строит runtime cards по CONTAINER_GROUPS: Triton, perception, Frigate, Ollama. Само появление новых module containers не даст им полноценного представления в этой проекции.
Нужны versioned module/job events и связь по labels: module version, composition, job, attempt, node. Существующий transport телеметрии можно переиспользовать; дополнительный telemetry-agent на каждую модель не нужен.
## 6. Предлагаемое разбиение
Это проектирование будущих контрактов. Приведённые ndc-имена не являются уже собранными releases.
| Узел / группа | Кандидат | Вход → результат | Независимость |
|---|---|---|---|
| Внутренняя подготовка, без выбора модели | Source adapter / decoder | raw source → verified bounded camera/LiDAR/pose chunks и индексы | Подготавливает только нужные графу каналы; не запускает ML |
| Сегментация | ndc-k1-segmentation-ddrnet39 | Camera + preprocessing → mask + GOOSE taxonomy + transforms | Без EoMT, detector и LiDAR |
| Сегментация, альтернатива | ndc-k1-segmentation-eomt-cityscapes | Camera + preprocessing → mask + versioned taxonomy | Без DDRNet; output adapter фиксируется отдельно от raw labels модели |
| Детекция | ndc-k1-detection-rfdetr | Camera/FOV → bbox, class, score | Без segmentation; текущий RF-DETR-L native KB4 wrapper сохраняется как точная версия |
| LiDAR / TGS / geometry costmap | ndc-k1-lidar-tgs | Cloud + необходимая pose/history → ground/occupied/rejected/unobserved | Без semantic detector и segmenter; camera нужен лишь если выбран camera-anchored режим |
| Объектная геометрия / расстояния | ndc-k1-object-geometry | Objects + cloud + pose/calibration/time binding → metric association/range | Не требует segmentation; geometry-only output не выдаётся за semantic detection |
| Temporal / motion | ndc-k1-object-motion | Geometry observations + bounded history → tracks/motion/retention | Явный state/history/reset contract |
| Semantic fusion / policy-shadow | ndc-k1-policy-shadow | TGS, material projection и объявленные obstacle/temporal outputs → наблюдаемые policy outputs | Зависимости задаются конкретным policy provider |
Тесно связанные temporal/motion/rolling функции допустимо держать в одном модуле. Аналогично TGS и его геометрическую rasterization/costmap. Логическая dependency не требует отдельного процесса для каждого математического шага.
Разделять TGS и semantic fusion нужно хотя бы в контракте: TGS-only не должен скрыто запускать segmentation. В полном pilot graph они сейчас соединены кодом.
Текущий detector использует RF-DETR-L с COCO-derived классами и ограниченным risk-class subset: человек, ряд транспорта и животных. Фраза «детекция всех объектов» не соответствует этому контракту. Дальность named object требует association; сегментация сама по себе расстояние не создаёт.
## 7. Контракты и идентичность
Предлагаемые новые исполнимые сущности:
- ModuleSpec: stable ID/version, image digest, code/weights/assets digests, capabilities, input/output schema, taxonomy, preprocessing, resource profile, state model.
- CompositionSpec: canonical nodes + module versions + parameters + typed edges + requested outputs + cadence/precision/history/reset rules.
- CompositionRun: composition digest + source snapshot + выбранный временной диапазон + execution attempt/ownership + node outcomes + publication.
- NodeResultManifest: exact input/output identities, actual coverage/gaps, computed/reused status, artifacts и timings.
- CapabilityResult: единый сохранённый LAB с перечислением доступных слоёв, renderer-neutral artifact refs и provenance.
Ключевые правила:
1. CompositionSpec не содержит конкретную запись, labels UI, Docker host paths, argv или credentials. Он переиспользуем.
2. Core выдаёт data-only manifest. Worker разрешает module IDs только через собственные установленные ModuleSpecs.
3. Worker подтверждает capability snapshot и exact module versions. Текущего списка готовых полных executor identities недостаточно для произвольного composer. Рекомендуется versioned extension capability/claim contract с сохранением чтения v3 для старых jobs; конкретная версия фиксируется в этапе 1.
4. Composition digest не зависит от порядка кликов; зависит от значимых modules/parameters/edges/outputs/time rules.
5. Node cache key включает module identity, relevant source/preparation inputs, hashes upstream outputs, effective parameters, calibration/transforms/taxonomy, cadence/precision и state/history.
6. В node cache key нельзя включать job ID или digest всей композиции: это уничтожит reuse при изменении независимой ветки. Job/attempt/composition сохраняются в provenance отдельно.
7. Для stateful узлов совпадения frame ID недостаточно: нужны initial state или checkpoint identity, input prefix/history, reset/epoch и time range.
8. Смена detector сохраняет независимую segmentation; пересчитывает association и всё, что от него зависит. Смена segmentation сохраняет detector, но меняет semantic fusion.
9. Массивы передаются локально на Worker: immutable chunks/files/mmap refs с размером, dtype, shape, digest, clock и coordinate frame. В API идут bounded metadata. Промежуточные tensors не ходят Worker→Core→Worker.
10. Final publication связывает node artifacts с новой job независимо от происхождения computed/reused. Наличие частичного node cache не делает LAB завершённой.
11. Нужны atomic cache publication, validation перед reuse, quarantine damaged entries, retention pins для активных jobs/готовых LAB/retry/rollback.
12. Одна композиция владеет Worker 006; тяжёлые GPU стадии исполняются последовательно. Процесс модели живёт на протяжении её обработки записи, а не создаётся на каждый кадр.
## 8. Поведение интерфейса
В существующей Обсерватории рядом с выбранной записью постоянно доступна кнопка «Сконфигурировать AI-слой». Наличие уже рассчитанных LAB или активной job не должно убирать вход в настройки. Если источника вообще нет, нужен обычный empty state.
Модальное Window:
- Сегментация: «Не использовать» / DDRNet / EoMT.
- Детекция: «Не использовать» / RF-DETR.
- LiDAR/TGS: допустимый provider либо отключено.
- Расстояния, motion, policy-shadow — по availability и объявленным зависимостям.
- По одному provider на группу; один module с несколькими capabilities не запускается несколько раз.
- Модели остаются в списках после расчёта. Готовность относится к целой композиции.
- Недоступные сочетания объясняются внутри формы. Зависимости нельзя молча исправлять включением другой ML-модели.
- Пустой состав без вычисляемого output не создаёт LAB.
- Оператору показываются имена моделей/возможностей; технические digests и Docker paths остаются в engineering details.
Состояния точного source × composition:
| Состояние | Действие |
|---|---|
| Допустим, ещё не рассчитан | Рассчитать |
| Уже принят / queued / running | Показать существующую job и реальный progress |
| Полностью опубликован и проверен | Открыть сохранённую LAB |
| Расчёт завершён, публикация требует повтора | Повторить публикацию без inference |
| Недопустим или нет installed module | Причина несовместимости; настройки остаются открываемыми |
| Расчёт failed/cancelled | Честный terminal state и допустимый повтор; partial node cache не выдаётся за готовую LAB |
Никаких отдельных страниц/микроприложений на модель или новую LAB. Компоненты формы — отдельные bounded feature modules, чтобы не расширять бесконечно ObservatoryWorkspace.tsx/App.tsx.
Escape сначала закрывает открытый Select, затем окно; проверяются focus restore, normal/expanded viewer, close/reopen и release ресурсов. Отображаются только реально рассчитанные capabilities; старые Legacy overlays не используются для заполнения отсутствующих слоёв.
## 9. План реализации
### Этап 1 — executable contracts и граница миграции
1. Зафиксировать ModuleSpec / CompositionSpec / NodeResult / CapabilityResult и source requirements по графу.
2. Построить server-side dependency admission: один segmenter; detector-only и segmentation-only допустимы; distance без нужных входов отклоняется.
3. Спроектировать dynamic composition registration и Worker capability negotiation поверх существующей очереди. Новая комбинация не требует image build/reinstall агента.
4. Реализовать canonical identities и правила reuse/invalidation, включая stateful nodes.
5. Зафиксировать coexistence новых schemas со старым installed V1/M49 и Legacy.
6. Составить retention closure существующих images/assets/packages/results/rollback. Очистку выполнять только отдельным последующим действием по проверенной достижимости; она не нужна для завершения текущего планирования.
Выход: контрактные fixtures и тесты, точная модель admission, migration table. Новых GPU-прогонов для этого этапа не требуется.
### Этап 2 — modules и Worker; первым сквозным результатом DDRNet-only
2A. Вынести подготовку камеры из EoMT, создать независимый DDRNet module и общий capability result writer.
Прогнать на настоящем источнике: source → prepare → DDRNet → sealed LAB → Core viewer. Это минимальный полезный вертикальный срез.
2B. Добавить RF-DETR detector-only и альтернативный EoMT. Доказать, что отключённые модели не загружаются. Упаковка включает закреплённый runtime и weights либо явно поставляемые immutable assets, без зависимости от случайного checkout/conda на host.
2C. Перенести TRAVEL TGS в общий package runtime. Отделить geometry-only от semantic fusion, подключить object association, motion и policy-shadow по реальным зависимостям полного prototype graph. Убрать hardcoded source IDs; сохранить точные calibration/FOV/taxonomy contracts.
2D. Добавить node cache, composition progress, cancellation/lease fencing, module/job labels, cleanup и retry. Обобщить capabilities системной телеметрии; перед measurement вернуть рабочий telemetry path без изменения Legacy.
2E. Довести progressive input: bounded chunks, early-start и accounting gaps; первичная полная материализация может быть промежуточным ограничением первого вертикального среза, но не критерием завершения всего этапа. Измерять disk I/O и memory вместе с inference.
Новый EoMT release отдельно активирует согласованную resource policy. Images старых releases не меняются на месте.
### Этап 3 — composer и полная продуктовая приёмка
- Подключить grouped Window к server admission и immutable compositions.
- Перенести readiness и dedup с одного фиксированного setup dropdown на source × composition.
- Добавить generic replay по capabilities: camera/mask/boxes/range/TGS/motion. Проверить отсутствие неназначенных слоёв.
- Выполнить последовательную матрицу на RAVNOVES00 и RAVNOVES004TREE; допустимость RAVNOVES01 проверять отдельно, не обходя отсутствие attestation.
- Проверить recovery, exact cache reuse, большие каталоги, закрытие/повторное открытие и освобождение RAM/GPU viewer.
- Сохранённые записи и LAB должны открываться без работающего Worker.
- Прогресс показывает фактически выполненные/переиспользованные/ошибочные узлы, source frames и coverage. Percent без измеренного total не выдумывается.
Этапы 2 и 3 разумно выполнять вертикальными инкрементами: сначала реальная DDRNet-only LAB и её минимальная форма, затем остальные группы через те же контракты.
### Этап 4 — будущий CUDA-борт
Перенос тех же логических модулей на конкретное совместимое железо, долгоживущие процессы в пределах миссии, общий benchmark memory/latency/I/O. Этот этап не является условием готовности записанных лабораторий и сейчас не исполняется.
## 10. Приёмочные сценарии
| Сценарий | Проверяемый результат |
|---|---|
| DDRNet-only | Нет EoMT/detector процесса; есть masks и saved review |
| EoMT-only | Нет DDRNet; собственная taxonomy и корректный source transform |
| Detector-only | Есть bbox/class/score; segmentation отсутствует |
| TGS-only | Геометрические состояния без скрытой ML; clock выбран явно |
| Distance без detector/cloud/calibration | Server admission отклоняет named-object distance |
| Geometry-only без detector | Нет выдуманных semantic labels; только заявленный geometric output |
| Два segmenter / пустой граф / cycle | Отклонение на сервере, до enqueue |
| Повтор одной композиции | Существующая job или проверенная LAB, без нового inference |
| Изменён detector | Segmentation reuse; зависимые association/motion пересчитаны |
| Изменена calibration/cadence/history | Нужные cache entries инвалидированы |
| Повреждён node cache | Не принимается как hit; нет ложной готовой LAB |
| Restart Core/Worker, потеря сети | History и ownership сохранены; нет конкурентной GPU-job |
| Cancel / lease loss внутри inference | Bounded stop, освобождение exact resources до следующего владельца |
| Upload обрывается / Core publication падает | Сохранённый sealed output используется для recovery; inference не повторяется ради публикации |
| Viewer с Worker offline | Полный сохранённый просмотр с Core |
| Close/reopen, normal/expanded/Escape | Один clock/receiver, отсутствие накопления временных ресурсов |
| Две записи × две композиции | Никакой привязки результата к чужой записи или старому overlay |
| Вычисление медленнее записи | Честный wall time и полное заявленное coverage, без ложного realtime PASS |
Existing tests для расширения: test_observatory_installed_lab_packages.py, test_observatory_installed_lab_package_runner.py, test_observatory_installed_lab_worker_service.py, test_observatory_recorded_jobs.py, test_observatory_portable_worker_runtime.py, test_worker_source_cache*.py, test_observatory_heartbeat_recovery.py, test_observatory_portable_result_publisher.py и Observatory frontend contract tests. Новый прогон тестов не выполнялся, поскольку этот проход не менял реализацию.
## 11. Конкретные точки следующего изменения
Предлагаемые новые bounded backend modules:
module_contracts.py, composition_contracts.py, composition_admission.py, composition_registry.py, node_result_cache.py, capability_result.py.
Окончательные имена — implementation detail; не нужно разносить каждую dataclass по отдельному файлу.
Изменяемые существующие seams:
- portable_run_definitions / source_admission / portable_queue_binding: переход от fixed profile к graph-derived требованиям;
- recorded_jobs / worker_agent / worker_service / worker_http_transport: composition identity, capability negotiation и cancellation;
- installed_lab_packages / installed_lab_package_runner: compilation разрешённого graph и module execution;
- отдельные adapters в experiments/perception/worker/observatory_portable;
- portable_result_* / portable_replay: generic capabilities и exact publication/review;
- ObservatoryWorkspace + отдельный AI-layer configuration feature в core/observatory и components;
- system_telemetry_api / pipeline_telemetry: динамическая module/job correlation.
Первое реализационное действие: согласованный executable контракт независимого source preparation и DDRNet module, затем настоящий DDRNet-only вертикальный срез. Повторный полный dual-segment LAB V1 и массовая чистка Docker не закрывают этот разрыв.
## 12. Evidence и пределы сверки
Приватные файлы:
/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/.runtime/observatory-context-audit-20260903
Содержат allowlisted inventory, hashes installed manifests, сравнение пяти исходников агента, source catalog, portable setup projections, queue summary и health/telemetry snapshot. Credentials, auth headers и содержимое записей не извлекались.
Основной Worker inventory SHA-256:
1a960a8ec05572dbd69409dcff1030076fc785fd91e3b2c729aad19143b7e195.
Сверка доказывает текущее устройство и перечисленные разрывы. Она не доказывает cold-start новых modules, скорость нового graph, визуальное качество, полноту покрытия всех записей или memory-lifecycle приёмку. Эти критерии включены в план, а не отмечены выполненными.
## 13. Ссылки на проверенные участки кода
- [Скрытая зависимость DDRNet от EoMT](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/worker/observatory_portable/run_portable_lab_v1_ddrnet_component.py:139)
- [Формирование связанных component inputs](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/lab_v1_installed_package_steps.py:202)
- [Package привязан к конкретной definition](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/installed_lab_packages.py:192)
- [Реестр готовых установленных executor](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/worker_service.py:380)
- [Синхронный вызов executor и heartbeat](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/worker_agent.py:524)
- [Ожидание завершения Docker step](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/installed_lab_package_runner.py:326)
- [Текущая граница общего source contract](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/portable_run_definitions.py:127)
- [Viewer выбирает фиксированные result schemas](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/apps/control-station/src/components/laboratory/PortableResultReplay.tsx:18)
- [Обязательные обе segmentation ветки](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/portable_semantic_replay.py:67)
- [Жёсткие source IDs полного прототипа](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/worker/streaming_profile_stage1/pilot_graph.py:302)
- [Текущий profile selector в Обсерватории](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/apps/control-station/src/workspaces/observatory/ObservatoryWorkspace.tsx:439)
- [Статический список системной телеметрии](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/web/system_telemetry_api.py:34)
## 10. Реализация после сверки — 3 сентября 2026, финальный локальный срез
Этот раздел заменяет формулировки выше о том, что модульный runtime и интерфейс ещё не реализованы. Указания исходного status-документа использовались как контекст; выполнен запрос владельца из диалога. Legacy лабораторный контур и исторический combined LAB V1 не изменялись. Канон Synology/DCPLATFORM-21 не применялся.
### Интерфейс
- Удалены фиксированный selector готового LAB-профиля и кнопки «Обновить»/«Рассчитать» рядом с ним.
- На их месте постоянно доступна кнопка «Сконфигурировать AI-слой» для выбранной записи.
- Каноническое модальное окно содержит отдельные функциональные блоки, статус в header, одиночный Select и нижнюю кнопку «Рассчитать».
- DDRNet и EoMT представлены как независимые альтернативы группы «Сегментация»; ни одна из моделей не выбирает и не запускает вторую.
- После отправки durable job сразу появляется в «Лабораторных доказательствах» с записью, составом, фазой, прогрессом и оценкой оставшегося времени. После публикации результат использует существующие действия просмотра, переименования и удаления.
- По последнему уточнению владельца из модального окна удалены внешняя обводка, рамки блоков, разделители header и контурные тени полей. Группировка держится на фоне, отступах и типографике.
### Модули и Worker 006
Модельно-нейтральная подготовка камеры вынесена в самостоятельный шаг. DDRNet и EoMT зависят только от `camera.frames` и не читают результаты друг друга.
| Модуль | Docker image | Image SHA-256 |
| --- | --- | --- |
| Camera source | `ndc/mission-core-ai-module-camera-source:61d1cd0adbac` | `da926459aee0a841bbdfaf80a0eb5fbead354c56794d1f3384eeba66d0a49e00` |
| DDRNet | `ndc/mission-core-ai-module-ddrnet:61d1cd0adbac` | `489fc7d1157fd0f1cd1d82e06a15737b7b2aaaf72b2ddb2aca2992b91a97488e` |
| EoMT | `ndc/mission-core-ai-module-eomt:61d1cd0adbac` | `5b770178e4a5c8fbe8f8ddab3b83a598973dbe103b669851110b11a0918ab846` |
Общий агент `ndc-mission-core-observatory-ai-agent` запущен на Worker 006 из image SHA-256 `b7ce60a851703375e77234d9ae37dfc6221b74c9dff8de719d2a1f2772c6b089`. Он использует release `20260903-v2`, SHA-256 `a5017e73216b566d3dc61d62df1ba7bbaf1fb348dde26e42d818a121e7a4aef5`. На финальном срезе контейнер `running`, `RestartCount=0`; Core получает его claim-запросы с HTTP 204.
| Setup | Definition SHA-256 | Package SHA-256 |
| --- | --- | --- |
| `ai-segmentation-ddrnet-v1` | `3adeba6595e31503a21f731f4b1427b09c64705c4a506659854c7c366b2d144f` | `958aa340819b42880cb79001efed946f369272937bd166e1844ee57784c6fd78` |
| `ai-segmentation-eomt-v1` | `499105c06a50b046ef1c5cd2148254e916156528ad21a824a66b787915a7f96b` | `019205fd5f0e6253759f4e7cf7aa1daa6d132163d36d4be5f8d07cca3ad1598d` |
Для записи `20260828T130511Z_viewer_live` оба setup прошли три независимые живые проверки: `source_compatible=true`, `executor_ready=true`, `submission_allowed=true`. Во время QA пользовательская запись не отправлялась на реальный GPU-прогон.
### Проверка
- Backend: 98 целевых pytest-проверок модульной композиции, setup/admission, Worker integration, adapters, release и replay — успешно.
- Frontend: 749 unit-тестов — успешно; TypeScript typecheck и production build — успешно.
- Ruff и mypy по новому backend/Worker контуру — успешно.
- Release-файлы сверены по SHA-256 между локальной копией и Worker 006.
- В браузере проверены отсутствие старых controls, независимый выбор DDRNet/EoMT, закрытие модалки и итоговый вариант без обводок.
@@ -0,0 +1,16 @@
{
"archived_at": "2026-09-05",
"role": "historical_desktop_reports_not_current_instructions",
"files": [
{
"filename": "_MISSING_CORE_MODULAR_AUDIT_AND_PLAN_2026-09-03.md",
"sha256": "d6c201d083fbec4b1db031379b515ff821a09ccfa0cea62443e211a9d76cb1c2",
"bytes": 53637
},
{
"filename": "_MISSING_CORE_OBSERVATORY_DOCKER_LABS_FINAL_STATUS_2026-09-01.md",
"sha256": "45e870700baddab8f31a2f0f0bfe1f9e99e8e73a490195c1e6a3beb5265e49ee",
"bytes": 330260
}
]
}