Document AI Inference architecture and freeze current baseline
This commit is contained in:
@@ -53,7 +53,7 @@ export const LABORATORY_REPORT_TEMPLATE_VERSION =
|
||||
|
||||
const EXECUTION_LABELS: Record<LaboratoryExecutionClass, string> = {
|
||||
deterministic: "Детерминированный",
|
||||
"ai-inference": "AI inference",
|
||||
"ai-inference": "AI Inference",
|
||||
hybrid: "Гибридный",
|
||||
};
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ export async function renameAICompositionRunProjection(
|
||||
displayName: string,
|
||||
): Promise<string> {
|
||||
if (!/^ai-composition-[a-f0-9]{64}$/.test(runId)) {
|
||||
throw new Error("Некорректная идентичность результата AI inference.");
|
||||
throw new Error("Некорректная идентичность результата AI Inference.");
|
||||
}
|
||||
const normalized = displayName.trim();
|
||||
if (!normalized || normalized.length > 160) {
|
||||
@@ -193,19 +193,19 @@ export async function renameAICompositionRunProjection(
|
||||
});
|
||||
const body = await bodyOf(response);
|
||||
if (!response.ok) throw apiError(body, response.status);
|
||||
const row = record(body, "результат AI inference");
|
||||
const row = record(body, "результат AI Inference");
|
||||
exactKeys(row, ["display_name", "run_id", "schema_version"]);
|
||||
if (
|
||||
row.schema_version !== "missioncore.observatory-ai-composition-run-projection/v1"
|
||||
|| row.run_id !== runId
|
||||
|| row.display_name !== normalized
|
||||
) throw new Error("Сервер не подтвердил переименование результата AI inference.");
|
||||
) throw new Error("Сервер не подтвердил переименование результата AI Inference.");
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export async function deleteAICompositionRunProjection(runId: string): Promise<void> {
|
||||
if (!/^ai-composition-[a-f0-9]{64}$/.test(runId)) {
|
||||
throw new Error("Некорректная идентичность результата AI inference.");
|
||||
throw new Error("Некорректная идентичность результата AI Inference.");
|
||||
}
|
||||
const response = await fetch(`/api/v1/observatory/ai-composition-runs/${encodeURIComponent(runId)}`, {
|
||||
method: "DELETE",
|
||||
|
||||
@@ -96,7 +96,7 @@ export async function deleteObservatoryLabProjection(
|
||||
headers: { Accept: "application/json" },
|
||||
signal,
|
||||
},
|
||||
"Не удалось удалить лабораторный результат из Обсерватории.",
|
||||
"Не удалось удалить лабораторный результат из AI Inference.",
|
||||
);
|
||||
const body = await responseBody(response);
|
||||
if (!response.ok || response.status !== 204) {
|
||||
@@ -132,7 +132,7 @@ function admittedProjectionId(binding: ObservatoryRecordedRunBinding): string {
|
||||
|| !SAFE_SESSION_ID.test(sessionId)
|
||||
) {
|
||||
throw new ObservatoryCatalogMutationError(
|
||||
"Выбранный результат не допущен к изменению каталога Обсерватории.",
|
||||
"Выбранный результат не допущен к изменению каталога AI Inference.",
|
||||
);
|
||||
}
|
||||
return sessionId;
|
||||
|
||||
@@ -39,7 +39,7 @@ type ObservatoryCatalogMutationDraft =
|
||||
function errorMessage(error: unknown): string {
|
||||
return error instanceof Error && error.message.trim()
|
||||
? error.message
|
||||
: "Каталог Обсерватории недоступен.";
|
||||
: "Каталог AI Inference недоступен.";
|
||||
}
|
||||
|
||||
function isAbortError(error: unknown): boolean {
|
||||
|
||||
@@ -170,9 +170,9 @@ export const workspaces: WorkspaceDefinition[] = [
|
||||
{
|
||||
id: "observatory",
|
||||
root: "polygon",
|
||||
label: "Обсерватория",
|
||||
title: "AI inference",
|
||||
eyebrow: "ТЕСТОВЫЙ КОНТУР / ОБСЕРВАТОРИЯ",
|
||||
label: "AI Inference",
|
||||
title: "AI Inference",
|
||||
eyebrow: "ТЕСТОВЫЙ КОНТУР / AI INFERENCE",
|
||||
description: "Сессии и квалификация без доступа к управлению.",
|
||||
icon: "eye",
|
||||
kind: "observatory",
|
||||
|
||||
@@ -165,7 +165,7 @@ function compositionProducedEvidence(
|
||||
function mutationErrorMessage(error: unknown): string {
|
||||
return error instanceof Error && error.message.trim()
|
||||
? error.message
|
||||
: "Не удалось изменить лабораторный результат в Обсерватории.";
|
||||
: "Не удалось изменить лабораторный результат в AI Inference.";
|
||||
}
|
||||
|
||||
function evidenceConfigurationLabel(
|
||||
@@ -276,12 +276,12 @@ function aiJobStageDetail(
|
||||
return "Не удалось запустить модель. Конфигурацию можно отправить повторно";
|
||||
}
|
||||
if (job.publication.state === "failed") {
|
||||
return "Результат рассчитан, но не сохранён в Обсерватории";
|
||||
return "Результат рассчитан, но не сохранён в AI Inference";
|
||||
}
|
||||
if (job.state === "succeeded") {
|
||||
if (job.publication.state === "pending") return "Завершаем сохранение результата";
|
||||
if (job.publication.state === "not-required") return "Публикация результата не требуется";
|
||||
return "Результат сохранён в Обсерватории";
|
||||
return "Результат сохранён в AI Inference";
|
||||
}
|
||||
if (!progress) {
|
||||
return "Готовим конфигурацию и место в очереди";
|
||||
@@ -862,7 +862,7 @@ export function ObservatoryWorkspace({
|
||||
{run.state === "ready" ? (
|
||||
<>
|
||||
<IconButton
|
||||
label={`Удалить ${run.displayName ?? run.presentation.configurationLabel} из Обсерватории`}
|
||||
label={`Удалить ${run.displayName ?? run.presentation.configurationLabel} из AI Inference`}
|
||||
onClick={() => openCompositionDelete(run)}
|
||||
>
|
||||
<Icon name="trash" size={16} />
|
||||
@@ -952,7 +952,7 @@ export function ObservatoryWorkspace({
|
||||
{evidence.recordedRun ? (
|
||||
<>
|
||||
<IconButton
|
||||
label={`Удалить ${evidence.lab.labId} из Обсерватории`}
|
||||
label={`Удалить ${evidence.lab.labId} из AI Inference`}
|
||||
onClick={() => openDelete(evidence)}
|
||||
>
|
||||
<Icon name="trash" size={16} />
|
||||
@@ -1094,7 +1094,7 @@ export function ObservatoryWorkspace({
|
||||
<Window
|
||||
open={renameTarget !== null || compositionRenameTarget !== null}
|
||||
title="Переименовать лабораторный результат"
|
||||
subtitle="Меняется только отображаемое название в Обсерватории"
|
||||
subtitle="Меняется только отображаемое название в AI Inference"
|
||||
size="sm"
|
||||
closeOnBackdrop={mutationPending !== "rename"}
|
||||
closeOnEscape={mutationPending !== "rename"}
|
||||
@@ -1161,12 +1161,12 @@ export function ObservatoryWorkspace({
|
||||
|
||||
<ConfirmationModal
|
||||
open={deleteTarget !== null || compositionDeleteTarget !== null}
|
||||
title="Удалить результат из Обсерватории?"
|
||||
title="Удалить результат из AI Inference?"
|
||||
description={deleteTarget || compositionDeleteTarget ? (
|
||||
<div className="observatory-delete-confirmation">
|
||||
<p>
|
||||
Будут удалены только каталожная проекция <strong>{deleteTarget?.label ?? compositionDeleteTarget?.displayName ?? compositionDeleteTarget?.presentation.configurationLabel}</strong>
|
||||
{" "}и её отображаемое название в Обсерватории.
|
||||
{" "}и её отображаемое название в AI Inference.
|
||||
</p>
|
||||
<p>
|
||||
Исходная сессия, запечатанный лабораторный результат и файлы доказательств
|
||||
@@ -1177,7 +1177,7 @@ export function ObservatoryWorkspace({
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
confirmLabel="Удалить из Обсерватории"
|
||||
confirmLabel="Удалить из AI Inference"
|
||||
pendingLabel="Удаляем…"
|
||||
danger
|
||||
onClose={() => {
|
||||
|
||||
@@ -114,10 +114,10 @@ test("Observatory mutations reject response drift and preserve API detail", asyn
|
||||
);
|
||||
await assert.rejects(
|
||||
deleteObservatoryLabProjection(binding, {
|
||||
fetcher: async () => Response.json({ detail: "Проекция не принадлежит Обсерватории." }, { status: 409 }),
|
||||
fetcher: async () => Response.json({ detail: "Проекция не принадлежит AI Inference." }, { status: 409 }),
|
||||
}),
|
||||
(error) => error instanceof ObservatoryCatalogMutationError
|
||||
&& error.status === 409
|
||||
&& error.message === "Проекция не принадлежит Обсерватории.",
|
||||
&& error.message === "Проекция не принадлежит AI Inference.",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -34,9 +34,9 @@ test("Observatory is the third independent Polygon workspace", () => {
|
||||
{
|
||||
id: "observatory",
|
||||
root: "polygon",
|
||||
label: "Обсерватория",
|
||||
title: "AI inference",
|
||||
eyebrow: "ТЕСТОВЫЙ КОНТУР / ОБСЕРВАТОРИЯ",
|
||||
label: "AI Inference",
|
||||
title: "AI Inference",
|
||||
eyebrow: "ТЕСТОВЫЙ КОНТУР / AI INFERENCE",
|
||||
description: "Сессии и квалификация без доступа к управлению.",
|
||||
icon: "eye",
|
||||
kind: "observatory",
|
||||
@@ -200,7 +200,7 @@ test("Observatory rename and delete use admitted projection mutations and canoni
|
||||
assert.match(workspace, /<Window[\s\S]*title="Переименовать лабораторный результат"/);
|
||||
assert.match(workspace, /<TextField[\s\S]*label="Название"[\s\S]*maxLength=\{160\}/);
|
||||
assert.match(workspace, /<WindowFooterActions>[\s\S]*Сохранить/);
|
||||
assert.match(workspace, /<ConfirmationModal[\s\S]*title="Удалить результат из Обсерватории\?"/);
|
||||
assert.match(workspace, /<ConfirmationModal[\s\S]*title="Удалить результат из AI Inference\?"/);
|
||||
assert.match(workspace, /Исходная сессия, запечатанный лабораторный результат и файлы доказательств/);
|
||||
assert.match(workspace, /renameAICompositionRunProjection/);
|
||||
assert.match(workspace, /deleteAICompositionRunProjection/);
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
# Observatory: модульные Docker-композиции → записанные LAB → CUDA-борт
|
||||
# AI Inference: история модульных Docker-композиций → записанные LAB → CUDA-борт
|
||||
|
||||
> Срез 2026-09-05: этап временно зафиксирован владельцем. Текущая фактическая
|
||||
> архитектура, ограничения и состояние приёмки описаны в
|
||||
> [AI Inference](audits/2026-09-05-ai-inference-architecture.md) и отдельной карте
|
||||
> Ops / MISSION CORE. Ниже сохранена история маршрута; старые «следующие шаги»
|
||||
> не означают поручение автоматически продолжать запуск или мигрировать legacy LAB.
|
||||
|
||||
## ЕДИНСТВЕННЫЙ ТЕКУЩИЙ МАРШРУТ — 2026-09-03, модульное решение
|
||||
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
Date: 2026-09-03. Owner-approved target; the first local modular vertical slice is installed.
|
||||
|
||||
Current implementation snapshot (2026-09-05): [AI Inference architecture](../audits/2026-09-05-ai-inference-architecture.md).
|
||||
The owner has temporarily frozen this stage; user acceptance remains incomplete.
|
||||
This ADR describes the target boundaries. The snapshot explicitly distinguishes
|
||||
the implemented setup mapping and source/result reuse from the not-yet-wired
|
||||
general DAG executor and per-node cache. The product name is now AI Inference;
|
||||
technical Observatory identifiers remain compatible.
|
||||
|
||||
## Decision and supersession
|
||||
|
||||
A reusable module is an independently packaged Docker image for a model or a
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
# AI Inference — принципы работы и фактическая архитектура
|
||||
|
||||
Срез на 5 сентября 2026 года. Репозиторий MISSION CORE, ветка `main`, исходный код аудита `e56eb42507d005cc372ac4a53785a080b116e227`. Изменения этого среза: терминология интерфейса и фиксация архитектуры. Исполнитель, модели, очередь, Rerun и способы обмена данными не рефакторились.
|
||||
|
||||
## 01. Решение и границы закрытия
|
||||
|
||||
AI Inference — текущий лабораторный путь применения выбранной AI-конфигурации к сохранённой физической записи и просмотра сохранённых доказательств. Раздел находится в LAB приложения Mission Core. Название «Обсерватория» больше не используется в текущем пользовательском интерфейсе. Технические `observatory` в URL, схемах, именах Python/TypeScript, Docker labels и старых evidence сохраняются для совместимости.
|
||||
|
||||
По решению владельца этот этап временно зафиксирован. Завершены архитектурный срез и консолидация контекста; пользовательская приёмка ещё не завершена. Это не статус production-ready, не доказательство real-time и не разрешение на управление транспортом. Поля `actuation_allowed`, `commands_enabled`, `navigation_or_safety_accepted`, `production_accepted` у действующих portable definitions имеют значение false.
|
||||
|
||||
Новые эксперименты строятся через этот путь. Старые LAB V1/M4.x и их приложения не становятся основой новых пользовательских поверхностей. Их результаты, код квалификации и происхождение алгоритмов сохраняются как история. Использование действующего TGS executor, выросшего из M4.9, не требует возвращать старый интерфейс лаборатории.
|
||||
|
||||
Worker выключен. В этом аудите его не включали, Docker daemon на нём не опрашивали, ничего не устанавливали и не запускали. Факты разделены на код и текущую конфигурацию Core, локальный сохранённый каталог/журнал, исторические измерения и непроверенные возможности.
|
||||
|
||||
## 02. Что является источником правды
|
||||
|
||||
Для текущей реализации первичны `config/observatory-ai-modules.json`, `config/observatory-portable-run-definitions.json`, `config/observatory-worker-runtime-candidates.json`, `config/observatory-domain-ontology.json` и соответствующие исполнители в `src/k1link/observatory/`. Наличие записи `executor.state=ready` означает сохранённую регистрацию executor identity, а не работающую сейчас машину.
|
||||
|
||||
Машинный срез: [2026-09-05-ai-inference-evidence.json](2026-09-05-ai-inference-evidence.json). В нём сохранены каталожные identities, ресурсные профили, текущая композиция и отобранные поля локальных jobs. Снимок не содержит ключей доступа, исходного видео, облаков, весов моделей и полных runtime-логов.
|
||||
|
||||
Связанные решения: [ADR 0051](../adr/0051-modular-observatory-profiles.md), [история маршрута](../OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md), [handoff 3 сентября](../../experiments/perception/OBSERVATORY_MODULAR_HANDOFF_2026-09-03.md), [runbook Worker](../runbooks/OBSERVATORY_PORTABLE_WORKER_006.md). Старые слова CURRENT/«следующий шаг» в исторических отчётах не являются новыми поручениями и не отменяют этот срез.
|
||||
|
||||
Ops MISSION CORE: #75 «AI Inference · Принципы работы и архитектура» (`e5768b6c-0817-4e9e-a786-f9167586c7dc`) с полным содержанием этого отчёта; #73 — история перехода к модульным профилям; #74 — подробный реестр кастомизации Rerun; #66 — канон Rerun; #9 — история AI Worker; #65 — историческая LAB V1. Новая карта не стирает свидетельства ошибок в старых картах. Статус Done у #75 означает завершение документирования среза; открытые пункты пользовательской/target-приёмки перечислены в checker и ниже.
|
||||
|
||||
## 03. Основные сущности и их владельцы
|
||||
|
||||
| Сущность | Значение и владелец |
|
||||
|---|---|
|
||||
| Физическая сессия | Запись оборудования: видео, LiDAR, pose/trajectory, временные шкалы, калибровка и provenance. Каталог сессий Core; не результат AI. |
|
||||
| Версия модуля | Модель либо связанная алгоритмическая функция с точными image/code/model/contract identities, входами и выходами. Реестр модулей и sealed package. |
|
||||
| CompositionSpec | Неизменяемый проверенный набор версий, параметров, зависимостей и execution policy; не привязан к одной конкретной записи. |
|
||||
| LAB / composition run | Применение композиции к точному source snapshot; связывает состав, member jobs и опубликованные результаты. |
|
||||
| Recorded job / attempt / lease | Единица выдачи работы и её конкретное владение исполнителем. Durable очередь Core, claim token и generation fencing. |
|
||||
| Portable result | Неизменяемые артефакты и метаданные доказательства, identities, покрытие и authority. Публикуются на Core. |
|
||||
| LAB display profile | Изменяемое оформление просмотра, отдельно от расчётной конфигурации и raw evidence. Хранится на Core по result_id. |
|
||||
| Viewer session | Временное положение камеры, FOLLOW, включённые слои и пропорции окон. Не следует отождествлять с сохранением всего LAB profile. |
|
||||
| Worker / installed executor | Доверенный исполнитель, которому разрешены конкретные версии packages и ресурсы. Не произвольная удалённая shell-машина из UI. |
|
||||
|
||||
Изменение цвета или размера точек не пересчитывает модель. Переименование отображаемой LAB не меняет immutable composition/result identity. Удаление из пользовательского каталога не следует трактовать как переписывание доказательства или автоматический Docker prune.
|
||||
|
||||
## 04. Пользовательский путь
|
||||
|
||||
Оператор выбирает сохранённую сессию. Core сообщает доступные каналы и применимость setup. Кнопка «Сконфигурировать AI-слой» открывает выбор по функциональным группам. UI получает каталог с сервера; он не извлекает возможности из свободного названия LAB.
|
||||
|
||||
Выбранные модули проходят проверку зависимостей и совместимости источника. Сохраняется точная композиция. Core создаёт либо использует уже существующие подходящие member jobs/results, показывает их совместный статус, а после публикации открывает связанный визуальный разбор. Повторный просмотр готовой LAB не должен запускать inference.
|
||||
|
||||
Название строки состоит из реальных конфигурационных значений. Название исходной сессии в строках списка не дублируется; в заголовке открытого результата сохраняется полный контекст. Дата и время расчёта, сортировка по времени, просмотр, переименование и удаление доступны в каталоге. Прогресс относится к активной обработке; готовая строка не должна навсегда оставаться шкалой 100%.
|
||||
|
||||
Глобальный смысл состояний: инициализация → передача на сервер → расчёт. Внутри расчёта могут быть подготовка камеры/LiDAR, загрузка модели, собственно inference и сборка результата. Эти подэтапы должны называться по фактической операции. Процент очереди/пакета нельзя интерпретировать как долю кадров модели или обещание точного ETA.
|
||||
|
||||
## 05. Каталог модулей и зависимости
|
||||
|
||||
| Модуль | Входы → выходы | Текущее назначение |
|
||||
|---|---|---|
|
||||
| camera-source | source.camera → camera.frames | Служебная подготовка камеры, добавляется зависимостью. Не отдельный пользовательский эксперимент. |
|
||||
| DDRNet-39 · GOOSE | camera.frames → segmentation.mask | Семантическая сегментация выбранной версией DDRNet. |
|
||||
| EoMT Large · Cityscapes | camera.frames → segmentation.mask | Альтернативный провайдер сегментации. |
|
||||
| RF-DETR Large | camera.frames → detections.2d | Детекция объектов; текущий package содержит TensorRT engine. |
|
||||
| Дистанция до объектов | detections.2d + source.calibration + source.lidar + source.pose → objects.ranged | Сопоставление детекций с калиброванными LiDAR/pose; собственных обученных весов нет. |
|
||||
| TRAVEL TGS | source.calibration + source.lidar + source.pose → geometry.costmap + geometry.ground | Геометрическая обработка, ground/costmap; без отдельной ML-модели. |
|
||||
|
||||
В новой композиции допускается не более одного провайдера в группе. DDRNet и EoMT — альтернативы, не два одновременно выбранных segmentation provider. Зависимости включаются детерминированно; range требует RF-DETR. Циклы, неоднозначные провайдеры и пустой недопустимый граф отвергаются.
|
||||
|
||||
Группы motion и policy присутствуют в модели каталога, но в текущем реестре пусты. Это не доказательство установленных модулей движения или управления. Полный исторический perception prototype имел более широкий состав; его нельзя автоматически приписать текущему UI.
|
||||
|
||||
Разрешённые параметры расчёта ограничены версией модуля: у текущих stateless AI modules cadence допускает 1; у TGS causal history-seconds допускает 1 и действует reset-at-source-start. Это вычислительные контракты. Пользовательский slider накопления SLAM 0–500 секунд относится к отображению и не увеличивает расчётную историю TGS.
|
||||
|
||||
## 06. Граф: декларация и реальное исполнение
|
||||
|
||||
`modular_composition.py` проверяет capabilities, identities, параметры и топологический порядок. `modular_composition_store.py` сохраняет неизменяемую спецификацию. Execution policy текущих композиций: `recorded-observation-only`, `max_parallel_nodes=1`. `composition_runs.py` связывает source, composition и результаты запуска.
|
||||
|
||||
Важная граница реализации: `web/modular_observatory_api.py` переводит известный набор модулей в заранее поддержанные setup IDs. Это работающий ограниченный композитор, но ещё не универсальный runtime, который исполняет произвольный DAG из любого числа новых Docker-узлов под одной lease.
|
||||
|
||||
Текущие AI setup IDs: `ai-segmentation-ddrnet-v1`, `ai-segmentation-eomt-v1`, `ai-detection-rf-detr-v1`, `ai-range-object-distance-v1`; геометрия — `m49-tgs-portable-v2`. Когда выбран range, отдельный standalone RF-DETR job не создаётся: RF-DETR выполняется внутри range package. Поэтому полная выбранная конфигурация DDRNet + RF-DETR + range + TGS даёт три member jobs, а не четыре.
|
||||
|
||||
Подходящий ранее созданный non-failed job может быть использован снова; опубликованный member result связывается с новой композиционной проекцией. Точная повторная отправка композиции с существующей допустимой работой не должна размножать расчёты; конфликт сообщает API. Failed execution допускает повторную попытку по действующему маршруту.
|
||||
|
||||
Очередь отдельного job durable. Создание группы member jobs и запись composition-run projection не являются одной общей SQL-транзакцией универсального DAG. Нельзя обещать атомарность всей композиции на основании транзакционности очереди. Полноценное расширение scheduler и его аварийная приёмка остаются отдельной работой.
|
||||
|
||||
## 07. Схема коммуникации
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
UI[Web UI: AI Inference] -->|same-origin HTTP| Core[Mission Core API :8000]
|
||||
Core --> Catalog[Sessions / composition / ontology projection]
|
||||
Core --> Queue[Durable recorded queue]
|
||||
Worker[Installed Worker agent] -->|claim / renew / progress / terminal| Core
|
||||
Core -->|verified source package| Worker
|
||||
Worker -->|local Docker API| Steps[Sequential compute containers]
|
||||
Steps -->|sealed output| Worker
|
||||
Worker -->|manifest + verified member uploads| Core
|
||||
Core --> Publish[Publication / artifact store / result catalogue]
|
||||
Publish -->|base + overlay + profile| Viewer[Official Rerun in Web UI]
|
||||
```
|
||||
|
||||
Браузер обращается к Core, не управляет Docker и не соединяется напрямую с Worker. Worker забирает работу у Core по HTTP pull-протоколу. Нынешний recorded-путь не отправляет каждый кадр через отдельный браузерный запрос или gRPC-поток: исходный пакет передаётся, вычислительные шаги работают с локальными входами, выход затем публикуется обратно.
|
||||
|
||||
Live telemetry оборудования — отдельный контур. Telegraf → MQTT → normalizer → Timescale → Core/System не заменяет HTTP job protocol. Свежая телеметрия не доказывает успешную публикацию LAB, а сохранённая LAB остаётся читаемой без работающего Worker.
|
||||
|
||||
## 08. Адресация, туннель и доверие
|
||||
|
||||
Файлы: `worker_http_transport.py`, `worker_tunnel_launchd.py`, `worker_container_proxy.py`, `worker_agent.py`. Текущий Core слушает локально `127.0.0.1:8000`. На Mac управляется SSH reverse tunnel через alias `mission-gpu`: `-R 127.0.0.1:18080:127.0.0.1:8000`, с BatchMode, ExitOnForwardFailure и keepalive.
|
||||
|
||||
Внутри agent container клиент обращается к loopback proxy :18080. Proxy направляет запросы на `host.docker.internal:18080`; на Windows host это loopback endpoint SSH-туннеля к Core. Следовательно, loopback HTTP защищён транспортом SSH на межмашинном участке. Здесь нет утверждения о публичном HTTP-порту Worker без защиты.
|
||||
|
||||
Transport принимает HTTPS либо HTTP только для loopback, передаёт Bearer auth и contour identity. Текущее исполнение привязано к `worker-006`. Два HTTP connection slots оставляют возможность служебного обмена при передаче пакета. Ключи, значения credentials и файлы с ними намеренно не входят в карту.
|
||||
|
||||
Это конкретная топология Mac Core ↔ Windows/Docker Desktop Worker. Наличие протокола не означает, что имя другого компьютера можно просто подставить в UI. Linux host networking и `host.docker.internal`, доверие SSH, токен, contour binding и установленный release потребуют согласованной адаптации. Реализация регистрации нового Worker в этот этап не входит.
|
||||
|
||||
## 09. Lease, очередь и восстановление
|
||||
|
||||
Worker вызывает `/api/v1/worker/observatory/recorded-jobs/claims` с claim schema v3 и перечнем поддержанных executor identities. При отсутствии работы получает 204. Затем идут start, lease renew, progress и terminal; upload result package имеет отдельные plan/member/complete операции.
|
||||
|
||||
Core сверяет source/definition/executor/resource/result contracts. Claim token и generation защищают от публикации запоздалым исполнителем. UI не может передать произвольный image, shell command, mount или network target через job. Вычислитель получает выбранный установленный package.
|
||||
|
||||
Ресурсные профили текущего Worker закрепляют последовательную работу на NVIDIA RTX 4090 и concurrency=1. Это не доказательство параллельного исполнения всех модулей. Политика допускает преимущество live-работы над recorded; текущие тяжёлые recorded jobs non-checkpointable. После вытеснения/ошибки до sealed результата нельзя обещать продолжение ровно с последнего кадра.
|
||||
|
||||
Worker имеет ограниченное восстановление транспортных ошибок и heartbeat; Core хранит durable job/publication state. Если вычисление завершено и результат запечатан, повтор публикации не должен повторять inference. Если результат ещё не запечатан, повторный запуск может начать обработку заново. История failed attempts сохраняется, а не становится фиктивным успехом при появлении следующего успешного результата.
|
||||
|
||||
## 10. Docker: что действительно упаковано
|
||||
|
||||
Нужно различать agent image, compute module image, installed package и реально запущенный контейнер. Agent опрашивает Core и управляет этапами. Compute container выполняет ограниченный шаг. Package закрепляет последовательность, изображения, assets, команды и contracts. Контейнерный ID — конкретный экземпляр на машине; его текущего значения этот offline-аудит не устанавливает.
|
||||
|
||||
Dockerfiles находятся в `experiments/perception/worker/observatory_portable/`: `Dockerfile.ai-module-camera-source`, `Dockerfile.ai-module-ddrnet`, `Dockerfile.ai-module-eomt`, `Dockerfile.ai-module-rf-detr`, `Dockerfile.ai-module-object-distance`, файлы installed-lab worker agent и специализированного M4.9 executor. Builder: `scripts/build_modular_ai_worker_release.py`. Исполнение: `installed_lab_packages.py`, `installed_lab_package_runner.py`, `modular_installed_package_steps.py`, installed worker service/container main; для TGS — `m49_worker_service.py` и соответствующий main.
|
||||
|
||||
Модульность сейчас прежде всего логическая и контрактная. Camera-source использует private base `ndc/mission-core-installed-lab-v1-eomt-step:ee0efdd9af72`; DDRNet — `ndc/mission-core-installed-lab-v1-ddrnet-step:439127908dba`; RF-DETR и object-distance опираются на `ndc-k1-perception-ddrnet39-rfdetr-tgs:stage1-joint-20260901`. Поэтому нельзя описывать каждый модуль как уже минимальный полностью независимый образ без наследованных окружений.
|
||||
|
||||
Некоторые FROM закреплены tag, хотя установленный release и готовые images проверяются по SHA. Для воспроизводимой чистой пересборки нужны именно соответствующие private bases, внешние assets и версии инструментов; один текст Dockerfile без них недостаточен. Отдельные conda/Python/model environments внутри compute stages остаются частью переносимого комплекта.
|
||||
|
||||
`ModuleSpec.docker_name` и ownership labels задают идентичность/наименование, а не доказывают наличие отдельного постоянно работающего сервиса на каждый модуль. В частности, TRAVEL TGS в текущем пути использует квалифицированный специализированный executor. Старые контейнеры LAB V1/других исследований не удалялись этой фиксацией.
|
||||
|
||||
## 11. Зафиксированные образы, модели и releases
|
||||
|
||||
SHA ниже взяты из текущих versioned registries; это конфигурационный срез, не сегодняшняя команда docker inspect на выключенном Worker.
|
||||
|
||||
| Модуль | Compute image SHA-256 |
|
||||
|---|---|
|
||||
| camera-source | da926459aee0a841bbdfaf80a0eb5fbead354c56794d1f3384eeba66d0a49e00 |
|
||||
| DDRNet | 489fc7d1157fd0f1cd1d82e06a15737b7b2aaaf72b2ddb2aca2992b91a97488e |
|
||||
| EoMT | 5b770178e4a5c8fbe8f8ddab3b83a598973dbe103b669851110b11a0918ab846 |
|
||||
| RF-DETR | 2b8b44be8e9ee4060aa6997fc4c025ad7120f37ecd720a9e59b5e02ac6c90f66 |
|
||||
| object-distance | 69d68f64981b41e5bcce1e642433e3d466b88c51942a5ba3aec9180d8ed04263 |
|
||||
| TRAVEL TGS | f9278ab21aa65045be993dd19bffc25f49955e19598893ac78cc4761ca63ecf3 |
|
||||
|
||||
Веса DDRNet: `b99c2838051bcd7b092fd3970aa62a77d5c0bbb809c9b9afb2ff4b0ebdaa4ee6`. EoMT weights: `c265da9a74f58f5c3f4826d23ca4ca78beac0b106cca5842beca61580de5b782`. RF-DETR TensorRT engine: `b8a40b3580edff001ec9680de68707242294ff590ab296000fae371f1083f695`. TensorRT engine не следует считать универсальным переносимым checkpoint для любого GPU/runtime.
|
||||
|
||||
У четырёх новых AI setup текущий executor image SHA `7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab`, release ID `ai-modular-installed-package-v1`, release SHA `97bfe743689766285b22627c4020d10df7949ef1f4546ef904dccb9ca4c6f721`. Все привязаны к worker-006.
|
||||
|
||||
TGS definition v3 использует image `f9278ab2…`, release `m49-tgs-portable-executor-v1`, release SHA `c5b0670d943fe0452ef4bbfbc144ab2439a1a674f9ef164798ad9f8b1ecc29fa`. Старая совместная LAB V1 definition v2 с executor `5ad7d95b…` и release `66785862…` остаётся в совместимом реестре; она не заменяет новые modular setups.
|
||||
|
||||
Важно сохранять provenance каждого результата: успешно опубликованный DDRNet member произведён предыдущим release `ecbb0edc1c4c3708329247a2210ef98dfa776bf948974e778ba6d131ad17a924`, хотя image agent совпадает. Range member использует текущий `97bfe743…`. Совпадение agent image не означает одинаковость sealed package. Каталоги `.runtime/*v8/v9/v10` — локальные артефакты сборки; наибольший номер папки не является источником истины о фактически установленном release.
|
||||
|
||||
## 12. Ресурсы и изоляция compute
|
||||
|
||||
Installed agent — доверенный оркестратор с доступом к Docker API/socket. Его нельзя описывать как полностью непривилегированный компонент без влияния на host.
|
||||
|
||||
Дочерние вычислительные контейнеры запускаются с ограничениями package runner: `network=none`, read-only root filesystem, drop ALL capabilities, no-new-privileges, без privileged mode. Входы, модели и проверенные code assets монтируются read-only; writable output ограничен каталогом шага. Заданы RAM/MemorySwap, CPU NanoCpus, Pids, SHM/tmpfs и GPU DeviceRequests. Точное значение бюджета зависит от resource profile/package, а не от свободного UI ввода.
|
||||
|
||||
GPU device admission не является жёсткой квотой VRAM. На имеющейся конфигурации действует последовательный допуск. Обещание безопасной параллельной работы N разных GPU моделей требует отдельного замера памяти и admission policy.
|
||||
|
||||
Историческая инвентаризация 3 сентября сообщала 11 containers, 7 running/4 stopped, 80 images, 9 volumes. Эти числа сохранены в архиве, но не являются текущим состоянием выключенного Worker. Другие исследования/сервисы, включая Gaussian и retained LAB packages, не следует автоматически считать зависимостями AI Inference или удалять по этой карте.
|
||||
|
||||
## 13. Передача данных и фактический кэш
|
||||
|
||||
Source package строится из конкретной сессии и проверенных members. Проверяются digest, размер и допустимость путей. `worker_source_cache.py` содержит source CAS (`.source-cas-v1`), который позволяет повторно использовать совпадающие исходные bytes. Кэш не разрешает смешивать похожие записи или произвольные версии калибровки.
|
||||
|
||||
Холодная подготовка остаётся существенной: загрузка camera archive завершается до extraction; декодирование/согласование камеры и LiDAR может предшествовать модельному этапу. Model-neutral camera-source убирает логическую зависимость подготовки от выбора segmentation, но не доказывает, что каждый отдельный job уже использует один готовый общий prepared-frame cache.
|
||||
|
||||
`portable_result_cache.py` и composition member reuse работают на уровне совпадающих сохранённых результатов. Чтение уже опубликованного результата не должно требовать GPU Worker.
|
||||
|
||||
Особенно важная проверка: `modular_node_cache.py` и `node_input_identity` существуют и покрыты тестами, но поиск production call sites обнаруживает определения и тесты без подключения `ModularNodeCache` к основному исполнителю. Поэтому универсальный кэш каждого узла композиции пока не заявляется работающей функцией. Старое намерение «каждый модуль считается один раз для всех LAB» ещё не равно реализации.
|
||||
|
||||
## 14. Результат и публикация
|
||||
|
||||
Результат связывает source snapshot, exact definition, module/package/model identities, временное покрытие и артефакты. `portable_artifact_transport.py` принимает manifest и members, `portable_result_publisher.py` создаёт опубликованную проекцию, `portable_publication_reconciler.py` доводит durable publication/outbox до согласованного состояния.
|
||||
|
||||
Результат проверки/расчёта и построенный для Rerun cache — разные артефакты. Смена renderer identity может потребовать перестроить производный cache; она не должна переписать исходные sealed results. Недоступный или неподходящий source должен давать явное состояние, а не демонстрационные точки вместо реальных данных.
|
||||
|
||||
Готовность полной LAB означает доступность требуемых member results по composition projection. Она не делает timestamps всех member jobs одинаковыми и не доказывает, что весь состав был вычислен одним совместным запуском. Сохранённая точная конфигурация важнее свободного названия строки.
|
||||
|
||||
## 15. Что действительно есть в текущем каталоге
|
||||
|
||||
Проверено через локальный Core API 5 сентября, без подключения Worker. Источник: `20260828T130511Z_viewer_live`, имя RAVNOVES004TREE, XGRIDS LixelKity K1, capture profile `xgrids-k1.viewer-live.fw-3.0.2.v1`, длительность 808.779 секунды (13:28.779).
|
||||
|
||||
В текущей проекции есть ready composition `ai-composition-33389babab33b801e8892f7b991683487eef2deea507486e52569fe943082e4b`, composition SHA `230396b858b09eea3d1d3a190c5e32d1d5e379da0058d32341026937fbb5cf24`. Создана 4 сентября в 06:59:35 UTC. Состав: DDRNet, RF-DETR, object-distance, TGS. Связаны три опубликованных member result; в UI также доступны отдельные сохранённые DDRNet и TGS строки.
|
||||
|
||||
| Member | Job | От создания job до публикации, UTC |
|
||||
|---|---|---|
|
||||
| DDRNet | observatory-run-ef3c14a64fca4d5a8674df82a5a0fca2 | 04.09 03:57:16.996 → 04:26:44.704; 29 мин 27.708 с |
|
||||
| TRAVEL TGS | observatory-run-b230216709dc4c59bc56c98c7e329bf1 | 03.09 08:08:03.013 → 08:31:39.776; 23 мин 36.763 с |
|
||||
| object-distance, включая RF-DETR | observatory-run-185e25280d58472ab8b4a0245a35c888 | 04.09 06:29:36.181 → 07:00:02.263; 30 мин 26.082 с |
|
||||
|
||||
Result IDs: `ai-layer-ddrnet-7c6a79942683933390f5ff0ecf2c6da1867d40032e91303746a567198772ce5c`; `m49-tgs-portable-review-a09d2b4a07d103e4f3693ba746a51be2197214768774eabfded4f109ae80dce4`; `ai-layer-object-distance-05f3931621585c9ac32132bef8c7afa961cea317cc29def09a8312339f8421e4`.
|
||||
|
||||
Это wall time конкретных успешных jobs, включая всё между enqueue и publication; это не model latency. Не надо складывать эти числа и называть суммой latency одного composition run: его members переиспользованы из разных дат.
|
||||
|
||||
История по этой сессии и setup при запросе до 100 jobs: DDRNet — 7, из них 1 succeeded/published и 6 failed; range — 7, из них 1 succeeded/published и 6 failed; TGS — 4, из них 1 succeeded/published, 1 succeeded с publication not-required и 2 failed. У новых standalone EoMT и RF-DETR setup — 0 jobs для этой сессии. Ноль здесь не означает отсутствия модели или старых экспериментов; успешный standalone recorded прогон ими в этом срезе не подтверждён. Действующие failures не стираются итоговой готовностью одной LAB.
|
||||
|
||||
## 16. Реальное покрытие и смысл измерений
|
||||
|
||||
Полная длительность источника и фактическое покрытие результатов должны быть отдельными полями. Исторический TGS handoff для этой записи указывает 6830 camera anchors, 6811 LiDAR matches и 19 unobserved; processing schedule примерно 39.215–757.160 секунды внутри источника 808.779 секунды. Надпись «полный маршрут» не должна скрывать начальные/конечные непокрытые интервалы и отсутствующие наблюдения.
|
||||
|
||||
В сохранённом TGS performance: candidate TGS p50=1.204 ms, p95=2.6075 ms, p99=3.2357 ms, max=4.651 ms. Более широкий stage wall: p50=17.676102 ms, p95=29.99172 ms, p99=36.24682261 ms, max=1269.499327 ms. Это разные границы измерения внутри алгоритма и обвязки; они не опровергают десятки минут enqueue→publish при подготовке записи.
|
||||
|
||||
Для честного сравнения нужно сохранять source rate, coverage, cold/warm режим, hardware/runtime identity, sample count и границы: queue wait; source transfer; decode/align; warmup; model/algorithm compute; serialize/seal; result upload/publication; replay preparation. Нельзя вычитать p95 одной фазы из p95 другой и получать корректный p95 остатка. FPS визуального воспроизведения Rerun тоже не является inference FPS.
|
||||
|
||||
Текущий recorded-first путь предназначен для воспроизводимых сравнений и сохранённых доказательств. Из имеющихся результатов не следует ни обещание полного real-time, ни утверждение, что модель сама считает один кадр две секунды. Долгие пользовательские ожидания из истории были реальными и должны оставаться частью performance backlog.
|
||||
|
||||
## 17. Предыдущий streaming experiment и его результат
|
||||
|
||||
Сохранены исследования `experiments/perception/worker/streaming_profile_stage1/`, [stage 1](../../experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md), [cross-host graph](../../experiments/perception/PERCEPTION_STREAM_STAGE2_CROSSHOST_GRAPH_2026-09-02.md), [control clock](../../experiments/perception/PERCEPTION_STREAM_STAGE2_CONTROL_CLOCK_2026-09-02.md), [TLS attribution](../../experiments/perception/PERCEPTION_STREAM_STAGE2_TLS_ATTRIBUTION_2026-09-02.md), [LAN route](../../experiments/perception/PERCEPTION_STREAM_STAGE2_LAN_ROUTE_2026-09-02.md). Подробные receipts также перенесены из Desktop в архив.
|
||||
|
||||
Это отдельный resident perception prototype: DDRNet/RF-DETR, LiDAR/range, motion, TGS/costmap и policy stages, бинарный обмен gRPC/TLS и pacing источника 1×. Он не является текущим recorded HTTP worker protocol и не становится автоматически модулем motion/policy в сегодняшнем UI.
|
||||
|
||||
Исторический joint image: `986dbe7126992359c69da0ddda674925a5efe8e3429a6d5f60765f9c9ad34a4e`, tag `ndc-k1-perception-ddrnet39-rfdetr-tgs:stage1-joint-20260901`. Использовались model/code mounts; это не полностью автономный образ. Конкретный приёмочный фрагмент: 32 released/accepted results с byte-exact доставкой; fresh scene outputs — 12. Эти числа нельзя заменять фразой «32 полностью свежих результатов сцены».
|
||||
|
||||
На Worker локально compute→local receiver p95/p99 = 74.243/76.322 ms. Межмашинная граница Mac source-due→consumer-ready p95/p99 = 205.864/213.751 ms при gate 125 ms: FAIL. Min 86.598 ms, median 121.85 ms не превращают хвосты в PASS. Историческая проверка выявила Wi-Fi с обеих сторон и TCP tails 67.921–91.142 ms ниже приложения; это основание изучать сеть, а не основание объявить всё задержкой модели. Истощение VRAM в этом конкретном опыте не было доказано.
|
||||
|
||||
Опыты показывают полезный compute budget и нерешённый end-to-end gate на тогдашней сети. Перенос resident runtime на будущий борт, совместимость другого GPU и абсолютный real-time не квалифицированы этим отчётом. Повторный streaming benchmark сейчас не запускался.
|
||||
|
||||
## 18. Локальная онтология и связи с оборудованием
|
||||
|
||||
В Mission Core уже есть предметная проекция: `config/observatory-domain-ontology.json` и `src/k1link/observatory/domain_ontology.py`. Она связывает transport/equipment/mount, capture profile, source session, module version/image, worker, composition, run/job/result, LAB view profile и layers/panes.
|
||||
|
||||
Она обслуживает согласованные запросы планирования, dispatch, публикации и replay: точная подпись конфигурации, состав member results, доступные слои и готовность. Идентичности берутся из существующих реестров/хранилищ; это не конкурирующая база, самовольно переименовывающая raw evidence.
|
||||
|
||||
Онтология отдельного NDC Platform repository не изменялась, runtime dependency на неё для AI Inference не добавлялась. Архитектурный принцип связанной модели применён локально. Формальное присутствие transport/equipment сущностей не равно готовой регистрации любого оборудования, универсальному драйверу RealSense или автоматическому конструктору 50 камер.
|
||||
|
||||
## 19. Rerun: один runtime, локальные контролы и сохранение
|
||||
|
||||
Полная самостоятельная карта: Ops #74 и [2026-09-05-rerun-customization-inventory.md](2026-09-05-rerun-customization-inventory.md), с [проверкой upstream](2026-09-05-rerun-upstream-evidence.json). В ней перечислены все действующие и архивные надстройки, точные файлы, хеши и upgrade gates. Здесь только роль в AI Inference.
|
||||
|
||||
Используется официальный Rerun 0.36.3; установленные JS/WASM и Python SDK в предыдущем аудите побайтно сверены с upstream. Recorded viewer живёт в same-origin iframe, имеет один native renderer/store/clock. Камера и spatial — виды внутри общего viewer. Внешний SplitPane владеет разделением, контролы принадлежат своим секциям, native layout получает согласованную долю. Верхняя панель переносит не помещающиеся группы; refresh/fullscreen относятся к общему layout.
|
||||
|
||||
Слои строятся из capabilities результата: фон КАМЕРА независим от segmentation и РАМОК; кнопка рамок зависит от detections; TGS от geometry evidence. Отключённый фон камеры не должен выключать остальные 2D layers. Один тип источника допускает одно окно. Сегодня реализованы camera/spatial и single-pane варианты, а не произвольное дерево из 50 камер.
|
||||
|
||||
ИСХ. ТОЧКИ и ЛОК. SLAM сейчас используют одно sealed `/world/points`. Отличаются отображение/накопление и дополнительные trajectory controls; это не две независимые коллекции «математические» и «декоративные». Изменения размера/цвета не меняют raw/AI расчёт.
|
||||
|
||||
Надстройка FOLLOW и восстановления eye использует прикладной журнал native gestures и blueprint. Это не официальный универсальный get-camera-pose API. Не все gestures покрыты: WASD, double-click/picking-fit, inertia могут расходиться с журналом. Такие ограничения явно оставлены в #74; этот документ не объявляет все пользовательские сценарии зума принятыми.
|
||||
|
||||
Server-side LAB display profile сохраняет point_size, accumulation_seconds, color_mode, palette, show_grid, show_labels, show_camera_frustums отдельно от immutable result. Применение point size/накопления/цвета/grid подключено; show_labels и show_camera_frustums сохраняются, но визуально не подключены к текущему canonical LAB пути. Layer toggles, FOLLOW, eye и split ratio в этот durable profile не входят.
|
||||
|
||||
Slider накопления 0–500 s и точный ввод конечного неотрицательного значения без верхнего product cap; размер slider 0.1–10 px, точный ввод ≥0.1 без верхнего cap. Закрытие настроек отправляет PUT; ошибка не должна блокировать закрытие и показывается компактным сообщением. Только успешная серверная запись подтверждает сохранение после очистки локального кэша. Сохранение в памяти/localStorage само по себе этого не доказывает.
|
||||
|
||||
## 20. Переносимость — что возможно и чего ещё нет
|
||||
|
||||
| Объект переноса | Реальное условие |
|
||||
|---|---|
|
||||
| Просмотр готовых LAB на другом Core | Перенести каталог, source/result artifacts, lineage и profiles с сохранением identities; обеспечить renderer/SDK и восстановление производных caches. Worker для просмотра не требуется. |
|
||||
| Та же композиция на другой записи K1 | Источник обязан пройти admission по требуемым каналам, калибровке, media epoch/codec, геометрии и timestamps. Один совпавший label недостаточен. |
|
||||
| GPU-модули на другом AI Worker | Нужны compatible CPU architecture/GPU/CUDA/TensorRT, exact images, private bases для rebuild, models/code assets, installed package, resource profiles и протокол связи. Не один docker load. |
|
||||
| Worker с другим именем/contour | Сейчас имеются worker-006 bindings и проверки. Общая динамическая регистрация/автовыбор любого Worker не заявляется готовой. В эту задачу не входит. |
|
||||
| Linux вместо Windows Docker Desktop | Нужна проверка network/host bridge, paths, mounts, GPU runtime и SSH topology; host.docker.internal нельзя молча считать одинаковым. |
|
||||
| Новая модель | Требуются ModuleSpec, versioned image/contract, adapter/installed steps, setup projection, input/result verification, capability→viewer mapping и evidence. Сейчас UI не универсальный marketplace Docker images. |
|
||||
| Другое оборудование / 50 камер | Нужны source adapters, calibration/time contracts, admission и расширение layout/ресурсной модели. Сущности онтологии дают место для этого, но не готовую реализацию. |
|
||||
| Бортовой real-time | Resident prototype, recorded LAB и бортовая qualification — разные границы. Нужен отдельный измеренный deployment на выбранном target. |
|
||||
|
||||
Переносимость достигнута в identities, пакетах, протоколах и сохранённых результатах. Привязки к Worker-006, K1 и имеющимся окружениям остаются конкретными. Утверждение «полностью независимо от host» сегодня было бы неточным. Изменять эти границы ради красивого отчёта без работающего Worker не стали.
|
||||
|
||||
## 21. Архив Desktop без потери контекста
|
||||
|
||||
Два относящихся к AI Inference документа перенесены побайтно в `docs/handoff/ai-inference-source-documents/` и снабжены [manifest.json](../handoff/ai-inference-source-documents/manifest.json). Это полные исходные тексты, включая ошибки, планы, замеры, списки Docker и последовательные обновления; не только краткий пересказ.
|
||||
|
||||
| Исходный файл Desktop | Bytes | SHA-256 |
|
||||
|---|---:|---|
|
||||
| _MISSING_CORE_MODULAR_AUDIT_AND_PLAN_2026-09-03.md | 53637 | d6c201d083fbec4b1db031379b515ff821a09ccfa0cea62443e211a9d76cb1c2 |
|
||||
| _MISSING_CORE_OBSERVATORY_DOCKER_LABS_FINAL_STATUS_2026-09-01.md | 330260 | 45e870700baddab8f31a2f0f0bfe1f9e99e8e73a490195c1e6a3beb5265e49ee |
|
||||
|
||||
Другие документы на Desktop не объявляются перенесёнными этой картой. Исходники не удалялись автоматически. После публикации commit пользователь может удалить именно эти два оригинала: versioned копии и хеши остаются в репозитории, а их актуальная интерпретация — здесь и в Ops.
|
||||
|
||||
Исторические указания из этих файлов не исполняются как команды. Раннее требование «весь профиль в одном монолитном образе» заменено ADR 0051. Историческое описание node cache как цели отделено от фактического отсутствия production wiring. Старые Docker inventories и streaming receipts датированы; не выдаются за результаты сегодняшнего запуска.
|
||||
|
||||
## 22. Проверки этого изменения и открытые границы
|
||||
|
||||
Для переименования выполнены архитектурные frontend tests (4 passed), полный frontend typecheck, полный unit suite (759 passed), production build и targeted Python tests `test_modular_observatory_api.py`/`test_observatory_setups.py` (22 passed). Изменения runtime поведения и новые вычислительные jobs в этом этапе не выполнялись.
|
||||
|
||||
В открытом in-app browser обновлена сборка и пройден путь LAB → AI Inference. Новые sidebar label, eyebrow, title и aria-подсказки удаления подтверждены реальным UI. Проверены обычный и развёрнутый shell, три сохранённых строки с датами/действиями; открыта полная сохранённая конфигурация с камерой, DDRNet, рамками и TGS. Fullscreen самого результата и возврат по Escape проверены. Escape на shell сам по себе не меняет его состояние; это не объявляется успешным закрытием shell. Текущая задача не меняет политику Escape/диалогов. Реальная сохранённая конфигурация оставляется для просмотра владельцем.
|
||||
|
||||
Срез временно закрыт по документации. Открыты: окончательная пользовательская приёмка навигации Rerun и настроек; два неподключённых display fields; полный native camera-state API вместо неполного gesture journal; универсальный multi-pane constructor; универсальное исполнение DAG/production node cache; новые Worker/оборудование и target CUDA qualification; end-to-end real-time gate и полноценные cold/warm phase metrics. Это границы текущего продукта, не скрыто выполненные пункты.
|
||||
|
||||
При возобновлении работы исходная точка — этот срез, actual registry и конкретные new measurements. Legacy LAB приложения автоматически не возвращаются; неизвестные состояния выключенного Worker сначала проверяются после его появления. Любое следующее обновление Rerun проходит отдельно по карте #74.
|
||||
|
||||
## 23. Изменённые файлы и эксплуатационная фиксация
|
||||
|
||||
Переименование: `apps/control-station/src/productModel.ts`, `components/laboratory/LaboratoryPresentation.tsx`, `workspaces/observatory/ObservatoryWorkspace.tsx`, `core/observatory/{aiComposition,catalogMutations,useObservatoryCatalog}.ts` внутри frontend; `src/k1link/observatory/setups.py`, `src/k1link/web/{observatory_api,modular_observatory_api}.py`. Обновлены ожидания существующих `observatoryWorkspace.test.mjs` и `observatoryCatalogMutations.test.mjs`. Дизайн, identifiers, параметры расчёта и бинарные модели не изменены.
|
||||
|
||||
Документация: этот отчёт, JSON evidence, README/manifest и две полные копии в `docs/handoff/ai-inference-source-documents/`; указатели текущего среза в ADR 0051 и историческом ExecPlan. Ops #75 создана как текущая архитектурная карта; #73 переименована в историческую карту с указателем #75 и сохранением всех прежних блоков.
|
||||
|
||||
Production frontend bundle пересобран. Канонический локальный LaunchAgent `com.nodedc.mission-core.local` перезапущен из того же checkout для применения Python-текстов. `/api/health` на :8000 подтверждает operational=true, plugin runtimes 1/1, готовность источников и artifact store. Новый сервер на другом порту не создавался; удалённый Worker не запускался. Код и архив публикуются в main обычным commit/push без переписывания истории. Точный итоговый commit указывается в финальном блоке Ops #75.
|
||||
@@ -0,0 +1,850 @@
|
||||
{
|
||||
"snapshot_date": "2026-09-05T06:51:04.590227+00:00",
|
||||
"code_baseline": "e56eb42507d005cc372ac4a53785a080b116e227",
|
||||
"worker_live_inspection": false,
|
||||
"source_session_id": "20260828T130511Z_viewer_live",
|
||||
"modules_registry": {
|
||||
"schema_version": "missioncore.observatory-ai-module-registry/v1",
|
||||
"modules": [
|
||||
{
|
||||
"module_id": "camera-source",
|
||||
"label": "Подготовка камеры K1",
|
||||
"group": "preparation",
|
||||
"image_sha256": "da926459aee0a841bbdfaf80a0eb5fbead354c56794d1f3384eeba66d0a49e00",
|
||||
"implementation_sha256": "a0b1a74887e5f1cf78e867f81f246bae08e872fed320a2939986c17913418524",
|
||||
"model_sha256": null,
|
||||
"contract_sha256": "87c9e8864f9469719e69bfd750c418e077944a6260ffc6fd3ce12daf4a1da7d5",
|
||||
"requires": [
|
||||
"source.camera"
|
||||
],
|
||||
"provides": [
|
||||
"camera.frames"
|
||||
],
|
||||
"optional_inputs": [],
|
||||
"parameter_choices": {
|
||||
"cadence": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"defaults": {
|
||||
"cadence": 1
|
||||
},
|
||||
"state_policy": "stateless"
|
||||
},
|
||||
{
|
||||
"module_id": "ddrnet",
|
||||
"label": "DDRNet-39 · GOOSE",
|
||||
"group": "segmentation",
|
||||
"image_sha256": "489fc7d1157fd0f1cd1d82e06a15737b7b2aaaf72b2ddb2aca2992b91a97488e",
|
||||
"implementation_sha256": "9a3fceb65374ccc3dccdbe02691c2b62376ff3a3a6d16439cb9f6266e73c78b0",
|
||||
"model_sha256": "b99c2838051bcd7b092fd3970aa62a77d5c0bbb809c9b9afb2ff4b0ebdaa4ee6",
|
||||
"contract_sha256": "197c9d7dd0f55f79992215a57e450c5442f3d1510d74083bcf123577f85da199",
|
||||
"requires": [
|
||||
"camera.frames"
|
||||
],
|
||||
"provides": [
|
||||
"segmentation.mask"
|
||||
],
|
||||
"optional_inputs": [],
|
||||
"parameter_choices": {
|
||||
"cadence": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"defaults": {
|
||||
"cadence": 1
|
||||
},
|
||||
"state_policy": "stateless"
|
||||
},
|
||||
{
|
||||
"module_id": "eomt",
|
||||
"label": "EoMT Large · Cityscapes",
|
||||
"group": "segmentation",
|
||||
"image_sha256": "5b770178e4a5c8fbe8f8ddab3b83a598973dbe103b669851110b11a0918ab846",
|
||||
"implementation_sha256": "17ac471d5c51f70b3af6fb6046e1880c731691253c338b1626702ce4ca375d2b",
|
||||
"model_sha256": "c265da9a74f58f5c3f4826d23ca4ca78beac0b106cca5842beca61580de5b782",
|
||||
"contract_sha256": "09ca841400b08af0607d19d346f78ab768567256c8c58789a6ade4ede8f425a0",
|
||||
"requires": [
|
||||
"camera.frames"
|
||||
],
|
||||
"provides": [
|
||||
"segmentation.mask"
|
||||
],
|
||||
"optional_inputs": [],
|
||||
"parameter_choices": {
|
||||
"cadence": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"defaults": {
|
||||
"cadence": 1
|
||||
},
|
||||
"state_policy": "stateless"
|
||||
},
|
||||
{
|
||||
"module_id": "tgs",
|
||||
"label": "TRAVEL TGS · облако и карта проходимости",
|
||||
"group": "geometry",
|
||||
"image_sha256": "f9278ab21aa65045be993dd19bffc25f49955e19598893ac78cc4761ca63ecf3",
|
||||
"implementation_sha256": "52813392aabd02efc5c2b8f7c22ed88e3ef4cc8ad3aafeba2792efe503e29fe9",
|
||||
"model_sha256": null,
|
||||
"contract_sha256": "9dd80c8e2504559d2156fca933de6eb27901e35305e6853aeb84707e1cb13892",
|
||||
"requires": [
|
||||
"source.calibration",
|
||||
"source.lidar",
|
||||
"source.pose"
|
||||
],
|
||||
"provides": [
|
||||
"geometry.costmap",
|
||||
"geometry.ground"
|
||||
],
|
||||
"optional_inputs": [],
|
||||
"parameter_choices": {
|
||||
"history-seconds": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"defaults": {
|
||||
"history-seconds": 1
|
||||
},
|
||||
"state_policy": "causal-reset-at-source-start"
|
||||
},
|
||||
{
|
||||
"module_id": "rf-detr",
|
||||
"label": "RF-DETR Large · рамки объектов",
|
||||
"group": "detection",
|
||||
"image_sha256": "2b8b44be8e9ee4060aa6997fc4c025ad7120f37ecd720a9e59b5e02ac6c90f66",
|
||||
"implementation_sha256": "4eb580eb938164bf0624e94fdc3b046aacf32fb8022c93c67fa26bab7c3d19d0",
|
||||
"model_sha256": "b8a40b3580edff001ec9680de68707242294ff590ab296000fae371f1083f695",
|
||||
"contract_sha256": "815d0afd24355da3a462e0423dab8284165c89cebd136d7c8584a32602178b96",
|
||||
"requires": [
|
||||
"camera.frames"
|
||||
],
|
||||
"provides": [
|
||||
"detections.2d"
|
||||
],
|
||||
"optional_inputs": [],
|
||||
"parameter_choices": {
|
||||
"cadence": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"defaults": {
|
||||
"cadence": 1
|
||||
},
|
||||
"state_policy": "stateless"
|
||||
},
|
||||
{
|
||||
"module_id": "object-distance",
|
||||
"label": "Дистанция до объектов · K1 LiDAR",
|
||||
"group": "range",
|
||||
"image_sha256": "69d68f64981b41e5bcce1e642433e3d466b88c51942a5ba3aec9180d8ed04263",
|
||||
"implementation_sha256": "0e3e426e2f768bc019a3715a50fc77a88626869abd9fa919e1aef5763d0c53da",
|
||||
"model_sha256": null,
|
||||
"contract_sha256": "5a6e446f009420352587f83388331b368d00950ab2fb896c6350aaa9b31c2e2e",
|
||||
"requires": [
|
||||
"detections.2d",
|
||||
"source.calibration",
|
||||
"source.lidar",
|
||||
"source.pose"
|
||||
],
|
||||
"provides": [
|
||||
"objects.ranged"
|
||||
],
|
||||
"optional_inputs": [],
|
||||
"parameter_choices": {
|
||||
"cadence": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"defaults": {
|
||||
"cadence": 1
|
||||
},
|
||||
"state_policy": "stateless"
|
||||
}
|
||||
]
|
||||
},
|
||||
"configured_definitions": [
|
||||
{
|
||||
"setup_id": "lab-v1-eomt-ddrnet-portable-v1",
|
||||
"definition_sha256": "269d71a24b4e63cff54e01273f9d4b35fc6cdd72bc6fadec206169ae0777e6ac",
|
||||
"version": 2,
|
||||
"executor": {
|
||||
"contour_id": "worker-006",
|
||||
"image_sha256": "5ad7d95baac63af13812cb693d492add4e806a333aba8e60edb2ea1aba754373",
|
||||
"reason": null,
|
||||
"reason_code": null,
|
||||
"release_id": "lab-v1-installed-package-v1",
|
||||
"release_sha256": "667858623962cd6d9849a8985b803f59e429916b5c56f76a6fc6c80c0c54526b",
|
||||
"state": "ready"
|
||||
},
|
||||
"resource_profile": {
|
||||
"accelerator_id": "nvidia-rtx-4090",
|
||||
"allowed_checkpoints": [],
|
||||
"checkpoint_policy": "non-checkpointable",
|
||||
"concurrency": 1,
|
||||
"contour_id": "worker-006",
|
||||
"profile_id": "worker006-single-gpu-sequential-ai-v1",
|
||||
"profile_sha256": "7468138cad115210eda18e7a3350e3423d3d39ac0aae650b3266cdc2bc63fd5d",
|
||||
"schema_version": "missioncore.observatory-portable-resource-profile/v2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"setup_id": "m49-tgs-portable-v2",
|
||||
"definition_sha256": "f56d6321bd794ccdfb7d2e3b05d044b11f616ffb81ee29517386cc253046d4eb",
|
||||
"version": 3,
|
||||
"executor": {
|
||||
"contour_id": "worker-006",
|
||||
"image_sha256": "f9278ab21aa65045be993dd19bffc25f49955e19598893ac78cc4761ca63ecf3",
|
||||
"reason": null,
|
||||
"reason_code": null,
|
||||
"release_id": "m49-tgs-portable-executor-v1",
|
||||
"release_sha256": "c5b0670d943fe0452ef4bbfbc144ab2439a1a674f9ef164798ad9f8b1ecc29fa",
|
||||
"state": "ready"
|
||||
},
|
||||
"resource_profile": {
|
||||
"accelerator_id": "cpu-only",
|
||||
"allowed_checkpoints": [],
|
||||
"checkpoint_policy": "non-checkpointable",
|
||||
"concurrency": 1,
|
||||
"contour_id": "worker-006",
|
||||
"profile_id": "worker006-cpu-single-run-portable-v2",
|
||||
"profile_sha256": "49e373f1cbf314e7fab2d176db295f3d3d9ddbbcbd724bbde988ef60ad767dee",
|
||||
"schema_version": "missioncore.observatory-portable-resource-profile/v2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"setup_id": "ai-segmentation-ddrnet-v1",
|
||||
"definition_sha256": "04dd11b9bca4956bc253c970a9020a5fac80e9ef5981ff1fffc32b9646087fec",
|
||||
"version": 1,
|
||||
"executor": {
|
||||
"contour_id": "worker-006",
|
||||
"image_sha256": "7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab",
|
||||
"reason": null,
|
||||
"reason_code": null,
|
||||
"release_id": "ai-modular-installed-package-v1",
|
||||
"release_sha256": "97bfe743689766285b22627c4020d10df7949ef1f4546ef904dccb9ca4c6f721",
|
||||
"state": "ready"
|
||||
},
|
||||
"resource_profile": {
|
||||
"accelerator_id": "nvidia-rtx-4090",
|
||||
"allowed_checkpoints": [],
|
||||
"checkpoint_policy": "non-checkpointable",
|
||||
"concurrency": 1,
|
||||
"contour_id": "worker-006",
|
||||
"profile_id": "worker006-single-gpu-sequential-ai-v1",
|
||||
"profile_sha256": "7468138cad115210eda18e7a3350e3423d3d39ac0aae650b3266cdc2bc63fd5d",
|
||||
"schema_version": "missioncore.observatory-portable-resource-profile/v2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"setup_id": "ai-segmentation-eomt-v1",
|
||||
"definition_sha256": "387f42bdf707b0e3e357fec1cfb5aa90a64133ebf0095f9b01d749ca2364d47c",
|
||||
"version": 1,
|
||||
"executor": {
|
||||
"contour_id": "worker-006",
|
||||
"image_sha256": "7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab",
|
||||
"reason": null,
|
||||
"reason_code": null,
|
||||
"release_id": "ai-modular-installed-package-v1",
|
||||
"release_sha256": "97bfe743689766285b22627c4020d10df7949ef1f4546ef904dccb9ca4c6f721",
|
||||
"state": "ready"
|
||||
},
|
||||
"resource_profile": {
|
||||
"accelerator_id": "nvidia-rtx-4090",
|
||||
"allowed_checkpoints": [],
|
||||
"checkpoint_policy": "non-checkpointable",
|
||||
"concurrency": 1,
|
||||
"contour_id": "worker-006",
|
||||
"profile_id": "worker006-single-gpu-sequential-ai-v1",
|
||||
"profile_sha256": "7468138cad115210eda18e7a3350e3423d3d39ac0aae650b3266cdc2bc63fd5d",
|
||||
"schema_version": "missioncore.observatory-portable-resource-profile/v2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"setup_id": "ai-detection-rf-detr-v1",
|
||||
"definition_sha256": "598ce44f087c392ee95a024c3c45c95bdd02ad8530a3ccbac13422c2ad2f4a94",
|
||||
"version": 1,
|
||||
"executor": {
|
||||
"contour_id": "worker-006",
|
||||
"image_sha256": "7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab",
|
||||
"reason": null,
|
||||
"reason_code": null,
|
||||
"release_id": "ai-modular-installed-package-v1",
|
||||
"release_sha256": "97bfe743689766285b22627c4020d10df7949ef1f4546ef904dccb9ca4c6f721",
|
||||
"state": "ready"
|
||||
},
|
||||
"resource_profile": {
|
||||
"accelerator_id": "nvidia-rtx-4090",
|
||||
"allowed_checkpoints": [],
|
||||
"checkpoint_policy": "non-checkpointable",
|
||||
"concurrency": 1,
|
||||
"contour_id": "worker-006",
|
||||
"profile_id": "worker006-single-gpu-sequential-ai-v1",
|
||||
"profile_sha256": "7468138cad115210eda18e7a3350e3423d3d39ac0aae650b3266cdc2bc63fd5d",
|
||||
"schema_version": "missioncore.observatory-portable-resource-profile/v2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"setup_id": "ai-range-object-distance-v1",
|
||||
"definition_sha256": "af5e637b78c670930b60cd4527b611aba4af601e6da58aa4dc8326ea6e13c5c2",
|
||||
"version": 1,
|
||||
"executor": {
|
||||
"contour_id": "worker-006",
|
||||
"image_sha256": "7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab",
|
||||
"reason": null,
|
||||
"reason_code": null,
|
||||
"release_id": "ai-modular-installed-package-v1",
|
||||
"release_sha256": "97bfe743689766285b22627c4020d10df7949ef1f4546ef904dccb9ca4c6f721",
|
||||
"state": "ready"
|
||||
},
|
||||
"resource_profile": {
|
||||
"accelerator_id": "nvidia-rtx-4090",
|
||||
"allowed_checkpoints": [],
|
||||
"checkpoint_policy": "non-checkpointable",
|
||||
"concurrency": 1,
|
||||
"contour_id": "worker-006",
|
||||
"profile_id": "worker006-single-gpu-sequential-ai-object-distance-v1",
|
||||
"profile_sha256": "c244efed459915508044fed4ef0e73c810fbe750e5e379d06723f734bd4385ca",
|
||||
"schema_version": "missioncore.observatory-portable-resource-profile/v2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"composition_runs": {
|
||||
"schema_version": "missioncore.observatory-ai-composition-run-list/v1",
|
||||
"items": [
|
||||
{
|
||||
"schema_version": "missioncore.observatory-ai-composition-run/v1",
|
||||
"run_id": "ai-composition-33389babab33b801e8892f7b991683487eef2deea507486e52569fe943082e4b",
|
||||
"source_session_id": "20260828T130511Z_viewer_live",
|
||||
"composition_sha256": "230396b858b09eea3d1d3a190c5e32d1d5e379da0058d32341026937fbb5cf24",
|
||||
"module_ids": [
|
||||
"tgs",
|
||||
"ddrnet",
|
||||
"rf-detr",
|
||||
"object-distance"
|
||||
],
|
||||
"setup_ids": [
|
||||
"ai-segmentation-ddrnet-v1",
|
||||
"m49-tgs-portable-v2",
|
||||
"ai-range-object-distance-v1"
|
||||
],
|
||||
"job_ids": [
|
||||
"observatory-run-ef3c14a64fca4d5a8674df82a5a0fca2",
|
||||
"observatory-run-b230216709dc4c59bc56c98c7e329bf1",
|
||||
"observatory-run-185e25280d58472ab8b4a0245a35c888"
|
||||
],
|
||||
"created_at_utc": "2026-09-04T06:59:35.000Z",
|
||||
"state": "ready",
|
||||
"configuration_label": "RAVNOVES004TREE · DDRNet-39 · GOOSE · RF-DETR Large · TRAVEL TGS · Дистанция до объектов · K1 LiDAR",
|
||||
"display_name": "DDRNet-39 · GOOSE · RF-DETR Large · TRAVEL TGS · Дистанция до объектов · K1 LiDAR",
|
||||
"presentation": {
|
||||
"schema_version": "missioncore.observatory-presentation-projection/v1",
|
||||
"modules": [
|
||||
{
|
||||
"module_id": "ddrnet",
|
||||
"label": "DDRNet-39 · GOOSE"
|
||||
},
|
||||
{
|
||||
"module_id": "rf-detr",
|
||||
"label": "RF-DETR Large"
|
||||
},
|
||||
{
|
||||
"module_id": "tgs",
|
||||
"label": "TRAVEL TGS"
|
||||
},
|
||||
{
|
||||
"module_id": "object-distance",
|
||||
"label": "Дистанция до объектов · K1 LiDAR"
|
||||
}
|
||||
],
|
||||
"configuration_label": "DDRNet-39 · GOOSE · RF-DETR Large · TRAVEL TGS · Дистанция до объектов · K1 LiDAR",
|
||||
"viewer_layers": [
|
||||
{
|
||||
"layer_id": "camera.source",
|
||||
"pane_id": "camera",
|
||||
"label": "КАМЕРА",
|
||||
"control": "toggle",
|
||||
"order": 10
|
||||
},
|
||||
{
|
||||
"layer_id": "camera.ddrnet",
|
||||
"pane_id": "camera",
|
||||
"label": "DDRNET",
|
||||
"control": "toggle",
|
||||
"order": 20
|
||||
},
|
||||
{
|
||||
"layer_id": "camera.detections",
|
||||
"pane_id": "camera",
|
||||
"label": "РАМКИ",
|
||||
"control": "toggle",
|
||||
"order": 40
|
||||
},
|
||||
{
|
||||
"layer_id": "spatial.source-points",
|
||||
"pane_id": "spatial",
|
||||
"label": "ИСХ. ТОЧКИ",
|
||||
"control": "toggle",
|
||||
"order": 10
|
||||
},
|
||||
{
|
||||
"layer_id": "spatial.local-slam",
|
||||
"pane_id": "spatial",
|
||||
"label": "ЛОК. SLAM",
|
||||
"control": "toggle-with-settings",
|
||||
"order": 20
|
||||
},
|
||||
{
|
||||
"layer_id": "spatial.tgs",
|
||||
"pane_id": "spatial",
|
||||
"label": "TGS",
|
||||
"control": "toggle",
|
||||
"order": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
"jobs": [
|
||||
{
|
||||
"schema_version": "missioncore.observatory-recorded-job/v1",
|
||||
"job_id": "observatory-run-ef3c14a64fca4d5a8674df82a5a0fca2",
|
||||
"idempotency_key": "ai-layer:fba5a33f38ba5beace38e4a4e99b4a468d2d6d760370027a9a6563b3c1279eae",
|
||||
"request_sha256": "16c22588dc443c1296782a4c4034fb895f888fddc8777a6d892b9f94da99b064",
|
||||
"identity_sha256": "47ddde3a49a77e9783a0ffaddff5f3219a0dc0cace1b77dbf71610575d5973b6",
|
||||
"submission_receipt_sha256": "8d7267ed9f652054fc9b42afb5faa341195d3fcbaad7a3f4fcb3979f827d91da",
|
||||
"source": {
|
||||
"session_id": "20260828T130511Z_viewer_live",
|
||||
"catalog_sha256": "2db6b8f109f5cc31bb32733ca633e03becca83d1f140a68ecc9ec9522010c24e",
|
||||
"bundle_sha256": "ee8aa75ff7fbf747ad62161d6e3bc83e291253e6df219a4d1b3a07bc69c79e84",
|
||||
"capability_manifest_sha256": "a4adc08ab0f867fcf7992aacaedd63328c9af222c829238c3f6e58903b95fa5e",
|
||||
"adapter": {
|
||||
"adapter_id": "xgrids-k1-recorded-ai-layer-v1",
|
||||
"version": 1,
|
||||
"adapter_sha256": "2b8e624b2b16b00c9dd75b96e4c56c5438aa6889b0b2fa7a2b2da39d6aa81c6e"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"setup_id": "ai-segmentation-ddrnet-v1",
|
||||
"definition_id": "ai-segmentation-ddrnet",
|
||||
"definition_version": 1,
|
||||
"definition_sha256": "e2f1b59e8680e0ad7e715cf61cac1bfe53b183429f933a65fd3ec22e1e198f16"
|
||||
},
|
||||
"executor": {
|
||||
"release_id": "ai-modular-installed-package-v1",
|
||||
"release_sha256": "ecbb0edc1c4c3708329247a2210ef98dfa776bf948974e778ba6d131ad17a924",
|
||||
"image_sha256": "7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab",
|
||||
"model_release_ids": [
|
||||
"lab-v1-ddrnet-39-goose-fine-64-v1"
|
||||
],
|
||||
"learned_models": [
|
||||
"lab-v1-ddrnet-39-goose-fine-64-v1"
|
||||
],
|
||||
"model_manifest_sha256": "c9144b30d054e3d495961486a4aed70ae5f60bcadadb4e3309865ced4123739e",
|
||||
"resource_profile_id": "worker006-single-gpu-sequential-ai-v1",
|
||||
"resource_profile_sha256": "7468138cad115210eda18e7a3350e3423d3d39ac0aae650b3266cdc2bc63fd5d"
|
||||
},
|
||||
"checkpoint_policy": {
|
||||
"mode": "non-checkpointable",
|
||||
"allowed_checkpoints": [],
|
||||
"last_checkpoint_id": null
|
||||
},
|
||||
"priority": {
|
||||
"class": "recorded",
|
||||
"rank": 100,
|
||||
"server_owned": true
|
||||
},
|
||||
"state": "succeeded",
|
||||
"preemption_requested": false,
|
||||
"restart_from_zero": false,
|
||||
"preemption_receipt_sha256": null,
|
||||
"claim_generation": 1,
|
||||
"claim_lease": null,
|
||||
"result": {
|
||||
"result_id": "ai-layer-ddrnet-7c6a79942683933390f5ff0ecf2c6da1867d40032e91303746a567198772ce5c",
|
||||
"sha256": "cbc433c51f49c63f45673f53ab5491d1cdbca04f2da7c5c9515c9f47c61cf01e"
|
||||
},
|
||||
"terminal": {
|
||||
"code": "result-sealed",
|
||||
"message": "Recorded result was sealed by the Worker."
|
||||
},
|
||||
"publication": {
|
||||
"state": "published",
|
||||
"attempts": 1,
|
||||
"error": null,
|
||||
"published_at_utc": "2026-09-04T04:26:44.704Z"
|
||||
},
|
||||
"created_at_utc": "2026-09-04T03:57:16.996Z",
|
||||
"updated_at_utc": "2026-09-04T04:26:44.704Z",
|
||||
"authority": {
|
||||
"commands_enabled": false,
|
||||
"actuation_allowed": false,
|
||||
"navigation_or_safety_accepted": false,
|
||||
"production_accepted": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema_version": "missioncore.observatory-recorded-job/v1",
|
||||
"job_id": "observatory-run-b230216709dc4c59bc56c98c7e329bf1",
|
||||
"idempotency_key": "observatory-ui:8966e8a8-cfde-4ff1-9361-e6becd9f0a87",
|
||||
"request_sha256": "b18a41134bfc18d007b2d94aed7b71dcfdb51791ae1f1f78bf8665c719a33c59",
|
||||
"identity_sha256": "bbf59ed8c0087b17e14b0f5f5ea903456e17f05bd4c7608744c05671c4e1382b",
|
||||
"submission_receipt_sha256": "72b4d576ec79cf9df64d8a7c1f9c4decd316c52c1f0dcd48438dc3323cc4642b",
|
||||
"source": {
|
||||
"session_id": "20260828T130511Z_viewer_live",
|
||||
"catalog_sha256": "2db6b8f109f5cc31bb32733ca633e03becca83d1f140a68ecc9ec9522010c24e",
|
||||
"bundle_sha256": "2412ee2374590a3b0bca8849a2410188325397b1651b7ae2916c48ead664c417",
|
||||
"capability_manifest_sha256": "c7c23096144bbb28b62edb1a8dad1b916decfac82c781687d22380721cafba96",
|
||||
"adapter": {
|
||||
"adapter_id": "xgrids-k1-recorded-observatory-v2",
|
||||
"version": 2,
|
||||
"adapter_sha256": "4e12be6d2503e2e237eddb290b28d6a7d16cf983855b6d8e6b4e3b65d2feb0de"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"setup_id": "m49-tgs-portable-v2",
|
||||
"definition_id": "m49-tgs-portable",
|
||||
"definition_version": 3,
|
||||
"definition_sha256": "f56d6321bd794ccdfb7d2e3b05d044b11f616ffb81ee29517386cc253046d4eb"
|
||||
},
|
||||
"executor": {
|
||||
"release_id": "m49-tgs-portable-executor-v1",
|
||||
"release_sha256": "c5b0670d943fe0452ef4bbfbc144ab2439a1a674f9ef164798ad9f8b1ecc29fa",
|
||||
"image_sha256": "f9278ab21aa65045be993dd19bffc25f49955e19598893ac78cc4761ca63ecf3",
|
||||
"model_release_ids": [],
|
||||
"learned_models": [],
|
||||
"model_manifest_sha256": "489a43448f720a9b5c7993dc8279d167b77191a586f0d87b6d38b81cf728e2f1",
|
||||
"resource_profile_id": "worker006-cpu-single-run-portable-v2",
|
||||
"resource_profile_sha256": "49e373f1cbf314e7fab2d176db295f3d3d9ddbbcbd724bbde988ef60ad767dee"
|
||||
},
|
||||
"checkpoint_policy": {
|
||||
"mode": "non-checkpointable",
|
||||
"allowed_checkpoints": [],
|
||||
"last_checkpoint_id": null
|
||||
},
|
||||
"priority": {
|
||||
"class": "recorded",
|
||||
"rank": 100,
|
||||
"server_owned": true
|
||||
},
|
||||
"state": "succeeded",
|
||||
"preemption_requested": false,
|
||||
"restart_from_zero": false,
|
||||
"preemption_receipt_sha256": null,
|
||||
"claim_generation": 1,
|
||||
"claim_lease": null,
|
||||
"result": {
|
||||
"result_id": "m49-tgs-portable-review-a09d2b4a07d103e4f3693ba746a51be2197214768774eabfded4f109ae80dce4",
|
||||
"sha256": "52e8afd6aaa38b615008463b873b94feae160946a69ce67aba12efc5f12b1589"
|
||||
},
|
||||
"terminal": {
|
||||
"code": "result-sealed",
|
||||
"message": "Recorded result was sealed by the Worker."
|
||||
},
|
||||
"publication": {
|
||||
"state": "published",
|
||||
"attempts": 1,
|
||||
"error": null,
|
||||
"published_at_utc": "2026-09-03T08:31:39.776Z"
|
||||
},
|
||||
"created_at_utc": "2026-09-03T08:08:03.013Z",
|
||||
"updated_at_utc": "2026-09-03T08:31:39.776Z",
|
||||
"authority": {
|
||||
"commands_enabled": false,
|
||||
"actuation_allowed": false,
|
||||
"navigation_or_safety_accepted": false,
|
||||
"production_accepted": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema_version": "missioncore.observatory-recorded-job/v1",
|
||||
"job_id": "observatory-run-185e25280d58472ab8b4a0245a35c888",
|
||||
"idempotency_key": "ai-layer:502ec972ec9e6d190720d1e820e6b204066ed31c560baf571797e6aed74b154b",
|
||||
"request_sha256": "bf3cd7b4dd0738f1a52341ccd4b9cc39db542e83c2c7ce1dda31a80c4932bc8d",
|
||||
"identity_sha256": "568a9d42642aee9ce798c5e2f8920651d1fd9b383293345a2a7ab322685900f2",
|
||||
"submission_receipt_sha256": "e568e257e941e63a3e84b95311fa15e33dcf31defacacaa55b5a617c6a8731a7",
|
||||
"source": {
|
||||
"session_id": "20260828T130511Z_viewer_live",
|
||||
"catalog_sha256": "2db6b8f109f5cc31bb32733ca633e03becca83d1f140a68ecc9ec9522010c24e",
|
||||
"bundle_sha256": "2412ee2374590a3b0bca8849a2410188325397b1651b7ae2916c48ead664c417",
|
||||
"capability_manifest_sha256": "c7c23096144bbb28b62edb1a8dad1b916decfac82c781687d22380721cafba96",
|
||||
"adapter": {
|
||||
"adapter_id": "xgrids-k1-recorded-observatory-v2",
|
||||
"version": 2,
|
||||
"adapter_sha256": "4e12be6d2503e2e237eddb290b28d6a7d16cf983855b6d8e6b4e3b65d2feb0de"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"setup_id": "ai-range-object-distance-v1",
|
||||
"definition_id": "ai-range-object-distance",
|
||||
"definition_version": 1,
|
||||
"definition_sha256": "af5e637b78c670930b60cd4527b611aba4af601e6da58aa4dc8326ea6e13c5c2"
|
||||
},
|
||||
"executor": {
|
||||
"release_id": "ai-modular-installed-package-v1",
|
||||
"release_sha256": "97bfe743689766285b22627c4020d10df7949ef1f4546ef904dccb9ca4c6f721",
|
||||
"image_sha256": "7a1d425b4678dcade7d7d6ffd14733d639a4df29f45e1759ba4c512e930da8ab",
|
||||
"model_release_ids": [
|
||||
"rf-detr-large-native-kb4-v1"
|
||||
],
|
||||
"learned_models": [
|
||||
"rf-detr-large-native-kb4-v1"
|
||||
],
|
||||
"model_manifest_sha256": "edef8446597b801f67538e9e1f056cbb55e56bf61ca4127efd97ce98e7473788",
|
||||
"resource_profile_id": "worker006-single-gpu-sequential-ai-object-distance-v1",
|
||||
"resource_profile_sha256": "c244efed459915508044fed4ef0e73c810fbe750e5e379d06723f734bd4385ca"
|
||||
},
|
||||
"checkpoint_policy": {
|
||||
"mode": "non-checkpointable",
|
||||
"allowed_checkpoints": [],
|
||||
"last_checkpoint_id": null
|
||||
},
|
||||
"priority": {
|
||||
"class": "recorded",
|
||||
"rank": 100,
|
||||
"server_owned": true
|
||||
},
|
||||
"state": "succeeded",
|
||||
"preemption_requested": false,
|
||||
"restart_from_zero": false,
|
||||
"preemption_receipt_sha256": null,
|
||||
"claim_generation": 1,
|
||||
"claim_lease": null,
|
||||
"result": {
|
||||
"result_id": "ai-layer-object-distance-05f3931621585c9ac32132bef8c7afa961cea317cc29def09a8312339f8421e4",
|
||||
"sha256": "05e9431dd5cfb7e55b8d59644cdadccf67588974975455e376d37f880f4652f6"
|
||||
},
|
||||
"terminal": {
|
||||
"code": "result-sealed",
|
||||
"message": "Recorded result was sealed by the Worker."
|
||||
},
|
||||
"publication": {
|
||||
"state": "published",
|
||||
"attempts": 1,
|
||||
"error": null,
|
||||
"published_at_utc": "2026-09-04T07:00:02.263Z"
|
||||
},
|
||||
"created_at_utc": "2026-09-04T06:29:36.181Z",
|
||||
"updated_at_utc": "2026-09-04T07:00:02.263Z",
|
||||
"authority": {
|
||||
"commands_enabled": false,
|
||||
"actuation_allowed": false,
|
||||
"navigation_or_safety_accepted": false,
|
||||
"production_accepted": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"result_ids": [
|
||||
"ai-layer-ddrnet-7c6a79942683933390f5ff0ecf2c6da1867d40032e91303746a567198772ce5c",
|
||||
"m49-tgs-portable-review-a09d2b4a07d103e4f3693ba746a51be2197214768774eabfded4f109ae80dce4",
|
||||
"ai-layer-object-distance-05f3931621585c9ac32132bef8c7afa961cea317cc29def09a8312339f8421e4"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"recorded_jobs": {
|
||||
"ai-segmentation-ddrnet-v1": [
|
||||
{
|
||||
"job_id": "observatory-run-ef3c14a64fca4d5a8674df82a5a0fca2",
|
||||
"state": "succeeded",
|
||||
"publication": {
|
||||
"state": "published",
|
||||
"attempts": 1,
|
||||
"error": null,
|
||||
"published_at_utc": "2026-09-04T04:26:44.704Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-884ad2f787244abdb12373a8f6f2d2e0",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-db32fced93ad46b6a3f7d2ff7421a557",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-77f8470a8593454ab777bcacf2d47b9f",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-24de2abb929a42738e4cfef6c4e86b95",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-cc9c9c5cd18844f0ab25fb20524e5073",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-1079d7c81ea0499e86738abfc1c35f49",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"ai-segmentation-eomt-v1": [],
|
||||
"ai-detection-rf-detr-v1": [],
|
||||
"ai-range-object-distance-v1": [
|
||||
{
|
||||
"job_id": "observatory-run-185e25280d58472ab8b4a0245a35c888",
|
||||
"state": "succeeded",
|
||||
"publication": {
|
||||
"state": "published",
|
||||
"attempts": 1,
|
||||
"error": null,
|
||||
"published_at_utc": "2026-09-04T07:00:02.263Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-cef3ba45c2024c55b6fb461e653d7187",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-5ab19401156d4d05b770ba57384387f0",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-f1a3cd0475964d62867cf17f135efbaa",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-96c0b491ae604772af19bca478837599",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-ee9d0b283b68470c91db5199a0374146",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-500a5a3b31e34061b52e1c09ff4f9604",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"m49-tgs-portable-v2": [
|
||||
{
|
||||
"job_id": "observatory-run-b230216709dc4c59bc56c98c7e329bf1",
|
||||
"state": "succeeded",
|
||||
"publication": {
|
||||
"state": "published",
|
||||
"attempts": 1,
|
||||
"error": null,
|
||||
"published_at_utc": "2026-09-03T08:31:39.776Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-d9e1089a503d46988847ad9f86cbf7d9",
|
||||
"state": "succeeded",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-e8645450dbe74f08b5944f35d3ee5c9f",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"job_id": "observatory-run-a627da1692cb4a2a9106d3e7e2870a90",
|
||||
"state": "failed",
|
||||
"publication": {
|
||||
"state": "not-required",
|
||||
"attempts": 0,
|
||||
"error": null,
|
||||
"published_at_utc": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"desktop_documents": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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 автоматически не удалялись. После публикации этого архива
|
||||
они могут быть удалены владельцем без потери именно этих двух документов.
|
||||
+488
@@ -0,0 +1,488 @@
|
||||
# Mission Core / Missing Core — сверка модульной Обсерватории и план реализации
|
||||
Дата: 3 сентября 2026. Срез runtime: 16:21–16: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, закрытие модалки и итоговый вариант без обводок.
|
||||
+3556
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -148,7 +148,7 @@ class LaboratorySetup:
|
||||
]
|
||||
if compatible and ready_result_ids:
|
||||
action = "open-existing"
|
||||
action_reason = "Точный запечатанный результат уже опубликован в Обсерватории."
|
||||
action_reason = "Точный запечатанный результат уже опубликован в AI Inference."
|
||||
elif compatible and any(
|
||||
result.access == "legacy-lab" for result in self.preserved_results
|
||||
):
|
||||
|
||||
@@ -174,7 +174,7 @@ def build_modular_observatory_router(
|
||||
try:
|
||||
source = store.get_session(request.source_session_id).summary
|
||||
except SessionNotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail="Запись Обсерватории не найдена.") from exc
|
||||
raise HTTPException(status_code=404, detail="Запись AI Inference не найдена.") from exc
|
||||
if source.lab is not None:
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
@@ -412,7 +412,7 @@ def build_modular_observatory_router(
|
||||
try:
|
||||
display_name = composition_runs.rename_projection(run_id, request.display_name)
|
||||
except CompositionRunError as exc:
|
||||
raise HTTPException(404, "Результат AI inference не найден.") from exc
|
||||
raise HTTPException(404, "Результат AI Inference не найден.") from exc
|
||||
return {
|
||||
"schema_version": "missioncore.observatory-ai-composition-run-projection/v1",
|
||||
"run_id": run_id,
|
||||
@@ -429,7 +429,7 @@ def build_modular_observatory_router(
|
||||
try:
|
||||
composition_runs.delete_projection(run_id)
|
||||
except CompositionRunError as exc:
|
||||
raise HTTPException(404, "Результат AI inference не найден.") from exc
|
||||
raise HTTPException(404, "Результат AI Inference не найден.") from exc
|
||||
return Response(status_code=204)
|
||||
|
||||
@router.get("/api/v1/observatory/ai-runs")
|
||||
|
||||
@@ -456,7 +456,7 @@ def build_observatory_router(
|
||||
if setup_registry is None:
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог legacy-сетапов Обсерватории недоступен.",
|
||||
detail="Каталог legacy-сетапов AI Inference недоступен.",
|
||||
)
|
||||
source = source_summary(source_session_id)
|
||||
return setup_registry.catalog(
|
||||
@@ -623,7 +623,7 @@ def build_observatory_router(
|
||||
del source_session_id
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории не прошёл проверку целостности.",
|
||||
detail="Каталог сетапов AI Inference не прошёл проверку целостности.",
|
||||
)
|
||||
|
||||
@router.post("/api/v1/observatory/run-preflights")
|
||||
@@ -633,7 +633,7 @@ def build_observatory_router(
|
||||
del request
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории не прошёл проверку целостности.",
|
||||
detail="Каталог сетапов AI Inference не прошёл проверку целостности.",
|
||||
)
|
||||
|
||||
if setup_registry is not None and run_preparation_ledger is not None:
|
||||
@@ -688,7 +688,7 @@ def build_observatory_router(
|
||||
if not isinstance(setups, list):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
projected = next(
|
||||
(
|
||||
@@ -701,7 +701,7 @@ def build_observatory_router(
|
||||
if projected is None:
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
definition = projected.get("run_definition")
|
||||
if not isinstance(definition, dict):
|
||||
@@ -725,7 +725,7 @@ def build_observatory_router(
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
if compatibility.get("compatible") is not True:
|
||||
raise HTTPException(
|
||||
@@ -743,7 +743,7 @@ def build_observatory_router(
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Dispatch-контракт Обсерватории не установлен.",
|
||||
detail="Dispatch-контракт AI Inference не установлен.",
|
||||
)
|
||||
definition_id = definition.get("definition_id")
|
||||
definition_version = definition.get("version")
|
||||
@@ -759,7 +759,7 @@ def build_observatory_router(
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
try:
|
||||
intent = ObservatoryRunPreparationIntent(
|
||||
@@ -826,7 +826,7 @@ def build_observatory_router(
|
||||
del request
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Подготовка расчётов Обсерватории недоступна.",
|
||||
detail="Подготовка расчётов AI Inference недоступна.",
|
||||
)
|
||||
|
||||
@router.get("/api/v1/observatory/run-preparations/{preparation_id}")
|
||||
@@ -840,7 +840,7 @@ def build_observatory_router(
|
||||
del preparation_id
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Подготовка расчётов Обсерватории недоступна.",
|
||||
detail="Подготовка расчётов AI Inference недоступна.",
|
||||
)
|
||||
|
||||
if recorded_job_queue is not None and (
|
||||
@@ -1022,7 +1022,7 @@ def build_observatory_router(
|
||||
if not isinstance(setups, list):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
projected = next(
|
||||
(
|
||||
@@ -1035,7 +1035,7 @@ def build_observatory_router(
|
||||
if projected is None:
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
compatibility = projected.get("compatibility")
|
||||
preflight = projected.get("preflight")
|
||||
@@ -1043,7 +1043,7 @@ def build_observatory_router(
|
||||
if not isinstance(compatibility, dict) or not isinstance(preflight, dict):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
if compatibility.get("compatible") is not True:
|
||||
raise HTTPException(
|
||||
@@ -1064,7 +1064,7 @@ def build_observatory_router(
|
||||
if not isinstance(definition_sha256, str):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Каталог сетапов Обсерватории нарушил контракт.",
|
||||
detail="Каталог сетапов AI Inference нарушил контракт.",
|
||||
)
|
||||
try:
|
||||
admission = recorded_binding_service.admit(
|
||||
@@ -1175,7 +1175,7 @@ def build_observatory_router(
|
||||
except ObservatoryRecordedQueueNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Расчёт Обсерватории не найден.",
|
||||
detail="Расчёт AI Inference не найден.",
|
||||
) from exc
|
||||
except (ObservatoryRecordedQueueError, ValueError) as exc:
|
||||
raise HTTPException(
|
||||
@@ -1206,7 +1206,7 @@ def build_observatory_router(
|
||||
except ObservatoryRecordedQueueNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Расчёт Обсерватории не найден.",
|
||||
detail="Расчёт AI Inference не найден.",
|
||||
) from exc
|
||||
except (ObservatoryRecordedQueueError, ValueError) as exc:
|
||||
raise HTTPException(
|
||||
@@ -1305,17 +1305,17 @@ def build_observatory_router(
|
||||
except SessionNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Проекция Обсерватории не найдена.",
|
||||
detail="Проекция AI Inference не найдена.",
|
||||
) from exc
|
||||
except SessionIntegrityError as exc:
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
detail="Запись не является управляемой проекцией Обсерватории.",
|
||||
detail="Запись не является управляемой проекцией AI Inference.",
|
||||
) from exc
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=422,
|
||||
detail="Некорректные параметры проекции Обсерватории.",
|
||||
detail="Некорректные параметры проекции AI Inference.",
|
||||
) from exc
|
||||
return ObservatoryProjectionDocument(
|
||||
schema_version=OBSERVATORY_PROJECTION_SCHEMA,
|
||||
@@ -1333,17 +1333,17 @@ def build_observatory_router(
|
||||
except SessionNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Проекция Обсерватории не найдена.",
|
||||
detail="Проекция AI Inference не найдена.",
|
||||
) from exc
|
||||
except SessionIntegrityError as exc:
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
detail="Запись не является управляемой проекцией Обсерватории.",
|
||||
detail="Запись не является управляемой проекцией AI Inference.",
|
||||
) from exc
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=422,
|
||||
detail="Некорректный идентификатор проекции Обсерватории.",
|
||||
detail="Некорректный идентификатор проекции AI Inference.",
|
||||
) from exc
|
||||
return Response(status_code=204)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user