feat(observatory): admit canonical recorded replay

This commit is contained in:
DCCONSTRUCTIONS
2026-08-30 19:21:27 +03:00
parent e6a9846167
commit 023151c186
32 changed files with 4069 additions and 342 deletions
@@ -11,6 +11,7 @@ let fetchM49TgsAnchorSpatial;
let AdvancedLaboratoryContractError;
let buildLaboratoryCatalog;
let buildLaboratoryProfiles;
let isLegacyPublishedLaboratoryWork;
let experimentOptionsForProfile;
let freshestLaboratorySelection;
let workOptionsForExperiment;
@@ -928,6 +929,7 @@ before(async () => {
({
buildLaboratoryCatalog,
buildLaboratoryProfiles,
isLegacyPublishedLaboratoryWork,
experimentOptionsForProfile,
freshestLaboratorySelection,
workOptionsForExperiment,
@@ -962,6 +964,31 @@ after(async () => {
await server?.close();
});
test("capability-owned projections never enter the legacy LAB catalog", () => {
const legacy = {
status: "ready",
replayable: true,
modalities: ["point-cloud", "trajectory"],
lab: { replayCapability: null },
};
const capabilityProjection = {
...legacy,
lab: {
replayCapability: {
schemaVersion: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewerProfile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commandsEnabled: false,
},
},
};
assert.equal(isLegacyPublishedLaboratoryWork(legacy), true);
assert.equal(isLegacyPublishedLaboratoryWork(capabilityProjection), false);
});
test("LAB catalog is pipeline-scoped and ordered by real run time", () => {
const catalog = buildLaboratoryCatalog({
rigLabel: "K1",
@@ -105,10 +105,14 @@ test("laboratory UI is a bounded feature slice, not a central workspace branch",
assert.match(e30HumanReviewCss, /\.e30-human-review/);
});
test("Observatory is a bounded read-only slice outside legacy LAB and viewer lifecycles", async () => {
test("Observatory owns a bounded explicit-open lifecycle around the shared recorded viewer", async () => {
const workspaceHub = await read("workspaces/Workspaces.tsx");
const observatory = await read("workspaces/observatory/ObservatoryWorkspace.tsx");
const observatoryCore = await read("core/observatory/catalog.ts");
const recordedRun = await read("core/observatory/recordedRun.ts");
const sharedReplay = await read(
"components/laboratory/CanonicalVegetationRerunReplay.tsx",
);
const workspaceCss = await read("styles/workspaces.css");
const observatoryCss = await read("styles/observatory.css");
@@ -119,12 +123,27 @@ test("Observatory is a bounded read-only slice outside legacy LAB and viewer lif
assert.match(observatory, /export function ObservatoryWorkspace/);
assert.match(observatory, /useObservatoryCatalog/);
assert.match(observatory, /data-observatory-authority="observation-only"/);
assert.match(observatory, /data-observatory-viewer="detached"/);
assert.match(
observatory,
/data-observatory-viewer={replay\.kind === "ready" \? "attached" : "detached"}/,
);
assert.doesNotMatch(
`${observatory}\n${observatoryCore}`,
/(?:core|components|workspaces)\/laboratory|\/api\/v1\/laboratory|RerunViewport|ObservationSessionSelect/,
/(?:core|workspaces)\/laboratory|\/api\/v1\/laboratory|RerunViewport|ObservationSessionSelect/,
);
assert.doesNotMatch(observatory, /replayObservationSession|deleteObservationSession/);
assert.match(observatory, /replay\.kind === "ready"[\s\S]*<CanonicalVegetationRerunReplay/);
assert.match(observatory, /closeReplay\(\);[\s\S]*setSelectedSessionId/);
assert.doesNotMatch(
observatory,
/replayObservationSession|deleteObservationSession|useObservationSessions|useAdvancedLaboratoryCatalog/,
);
assert.match(recordedRun, /fetchVegetationShadowResultMetadata/);
assert.doesNotMatch(
recordedRun,
/advanced-index|resolveObservationSessionReplay|resolveCanonicalLabReplay|RerunViewport/,
);
assert.equal(sharedReplay.match(/<RerunViewport\b/g)?.length, 1);
assert.match(sharedReplay, /recordedSessionRerunProfile/);
assert.doesNotMatch(workspaceCss, /\.observatory-/);
assert.match(observatoryCss, /\.observatory-workspace/);
});
@@ -77,6 +77,57 @@ function session(overrides = {}) {
};
}
function canonicalLab(overrides = {}) {
const resultId = `lab-v1-vegetation-shadow-${"8".repeat(64)}`;
return {
lab_id: "LAB V1",
source_session_id: "20260828T130511Z_viewer_live",
result_kind: "recorded-perception-qualification",
result_id: resultId,
source_result_id: `lab-v1-vegetation-shadow-${"9".repeat(64)}`,
config_sha256: null,
run_created_at_utc: "2026-08-29T18:05:11.329061+00:00",
published_at_utc: "2026-08-30T12:00:00.000Z",
replay_capability: {
schema_version: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewer_profile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commands_enabled: false,
},
provenance: {},
...overrides,
};
}
function canonicalProjectionProvenance(resultId, replayCapability) {
return {
schema_version: "missioncore.canonical-recorded-lab-projection/v1",
evidence_identity_sha256: resultId.slice("lab-v1-vegetation-shadow-".length),
result_document_sha256: "a".repeat(64),
replay_capability: replayCapability,
authority: {
commands_enabled: false,
navigation_or_safety_accepted: false,
actuation_accepted: false,
},
method: {
schema_version: "missioncore.laboratory-method/v1",
completeness: "legacy-partial",
execution_class: "ai-inference",
pipeline_id: "ravnoves004tree-full-eomt-ddrnet-recorded-review/v1",
components: [{
kind: "source",
name: "sealed full-route LAB result",
version: "missioncore.lab-v1-vegetation-shadow/v1",
role: "immutable Session catalog projection",
identity_sha256: resultId.slice("lab-v1-vegetation-shadow-".length),
}],
},
};
}
function replay(overrides = {}) {
const sessionId = overrides.session_id ?? "session-20260716T205632Z";
const sourceUrl = overrides.source_url ??
@@ -141,6 +192,74 @@ test("session catalog decodes canonical snake_case into a path-free camelCase mo
assert.equal("path" in catalog.items[0], false);
});
test("session catalog strictly decodes the explicit recorded LAB replay capability", () => {
const resultId = `lab-v1-vegetation-shadow-${"8".repeat(64)}`;
const decoded = decodeObservationSessionCatalog({
items: [session({ id: resultId, lab: canonicalLab() })],
}).items[0].lab;
assert.deepEqual(decoded.replayCapability, {
schemaVersion: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewerProfile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commandsEnabled: false,
});
const rollingUpgradeLab = canonicalLab();
rollingUpgradeLab.provenance = canonicalProjectionProvenance(
resultId,
rollingUpgradeLab.replay_capability,
);
delete rollingUpgradeLab.replay_capability;
assert.deepEqual(
decodeObservationSessionCatalog({
items: [session({ id: resultId, lab: rollingUpgradeLab })],
}).items[0].lab.replayCapability,
decoded.replayCapability,
);
const invalidComponents = [
{ kind: "tool" },
{ name: "unsealed result" },
{ version: "missioncore.lab-v1-vegetation-shadow/v0" },
{ role: "mutable projection" },
{ identity_sha256: "0".repeat(64) },
{ unexpected: true },
];
for (const componentOverride of invalidComponents) {
const invalidRollingUpgradeLab = canonicalLab();
invalidRollingUpgradeLab.provenance = canonicalProjectionProvenance(
resultId,
invalidRollingUpgradeLab.replay_capability,
);
invalidRollingUpgradeLab.provenance.method.components = [{
...invalidRollingUpgradeLab.provenance.method.components[0],
...componentOverride,
}];
delete invalidRollingUpgradeLab.replay_capability;
assert.throws(
() => decodeObservationSessionCatalog({
items: [session({ id: resultId, lab: invalidRollingUpgradeLab })],
}),
ObservationSessionContractError,
);
}
assert.throws(
() => decodeObservationSessionCatalog({
items: [session({
id: resultId,
lab: canonicalLab({
replay_capability: {
...canonicalLab().replay_capability,
commands_enabled: true,
},
}),
})],
}),
ObservationSessionContractError,
);
});
test("opened archive is named in the scene header and trash hover has no pill", async () => {
const appSource = await readFile(new URL("../src/App.tsx", import.meta.url), "utf8");
const styles = await readFile(
@@ -246,7 +365,7 @@ test("source and laboratory catalogs are requested as disjoint backend projectio
assert.deepEqual(calls, [
"/api/v1/observation-sessions?limit=100&scope=source",
"/api/v1/observation-sessions?limit=100&scope=laboratory",
"/api/v1/observation-sessions?limit=100&scope=laboratory&lab_contract=v2",
]);
});
@@ -60,11 +60,47 @@ function evidence(id, sourceSessionId, publishedAtUtc) {
configSha256: "a".repeat(64),
runCreatedAtUtc: publishedAtUtc,
publishedAtUtc,
replayCapability: null,
provenance: { verdict: "must-not-be-inferred" },
},
};
}
function canonicalProvenance(resultId) {
const identitySha256 = resultId.slice("lab-v1-vegetation-shadow-".length);
return {
schema_version: "missioncore.canonical-recorded-lab-projection/v1",
evidence_identity_sha256: identitySha256,
result_document_sha256: "a".repeat(64),
replay_capability: {
schema_version: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewer_profile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commands_enabled: false,
},
authority: {
commands_enabled: false,
navigation_or_safety_accepted: false,
actuation_accepted: false,
},
method: {
schema_version: "missioncore.laboratory-method/v1",
completeness: "legacy-partial",
execution_class: "ai-inference",
pipeline_id: "ravnoves004tree-full-eomt-ddrnet-recorded-review/v1",
components: [{
kind: "source",
name: "sealed full-route LAB result",
version: "missioncore.lab-v1-vegetation-shadow/v1",
role: "immutable Session catalog projection",
identity_sha256: identitySha256,
}],
},
};
}
test("Observatory joins evidence only by sourceSessionId and keeps deterministic order", () => {
const catalog = buildObservatoryCatalog(
[
@@ -130,7 +166,7 @@ test("Observatory fetches disjoint read-only source and laboratory projections",
assert.deepEqual(
calls.map(({ input }) => input).sort(),
[
"/api/v1/observation-sessions?limit=50&scope=laboratory",
"/api/v1/observation-sessions?limit=50&scope=laboratory&lab_contract=v2",
"/api/v1/observation-sessions?limit=50&scope=source",
],
);
@@ -157,3 +193,43 @@ test("Observatory exposes bounded-window uncertainty without inventing a broken
["outside-window"],
);
});
test("Observatory projects a typed canonical run only through its exact sourceSessionId", () => {
const canonicalResultId = `lab-v1-vegetation-shadow-${"8".repeat(64)}`;
const canonical = evidence(
canonicalResultId,
"20260828T130511Z_viewer_live",
"2026-08-29T18:05:11Z",
);
canonical.lab = {
...canonical.lab,
labId: "LAB V1",
resultKind: "recorded-perception-qualification",
resultId: canonicalResultId,
sourceResultId: `lab-v1-vegetation-shadow-${"9".repeat(64)}`,
configSha256: null,
provenance: canonicalProvenance(canonicalResultId),
replayCapability: {
schemaVersion: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewerProfile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commandsEnabled: false,
},
};
const catalog = buildObservatoryCatalog(
[source("20260828T130511Z_viewer_live", "2026-08-28T13:05:11Z")],
[canonical],
);
assert.deepEqual(catalog.items[0].evidence[0].recordedRun, {
kind: "canonical-recorded-rerun",
evidenceSessionId: canonicalResultId,
sourceSessionId: "20260828T130511Z_viewer_live",
resultId: canonicalResultId,
viewerProfile: "recorded-session",
timeline: "session_time",
activation: "explicit",
});
});
@@ -0,0 +1,180 @@
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let admitObservatoryRecordedRunReview;
let observatoryRecordedRunBinding;
let ObservatoryRecordedRunContractError;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({
admitObservatoryRecordedRunReview,
observatoryRecordedRunBinding,
ObservatoryRecordedRunContractError,
} = await server.ssrLoadModule("/src/core/observatory/recordedRun.ts"));
});
after(async () => {
await server?.close();
});
const sourceSessionId = "20260828T130511Z_viewer_live";
const resultId = `lab-v1-vegetation-shadow-${"8".repeat(64)}`;
function canonicalProvenance() {
const identitySha256 = resultId.slice("lab-v1-vegetation-shadow-".length);
return {
schema_version: "missioncore.canonical-recorded-lab-projection/v1",
evidence_identity_sha256: identitySha256,
result_document_sha256: "a".repeat(64),
replay_capability: {
schema_version: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewer_profile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commands_enabled: false,
},
authority: {
commands_enabled: false,
navigation_or_safety_accepted: false,
actuation_accepted: false,
},
method: {
schema_version: "missioncore.laboratory-method/v1",
completeness: "legacy-partial",
execution_class: "ai-inference",
pipeline_id: "ravnoves004tree-full-eomt-ddrnet-recorded-review/v1",
components: [{
kind: "source",
name: "sealed full-route LAB result",
version: "missioncore.lab-v1-vegetation-shadow/v1",
role: "immutable Session catalog projection",
identity_sha256: identitySha256,
}],
},
};
}
function lab(overrides = {}) {
return {
labId: "LAB V1",
sourceSessionId,
resultKind: "recorded-perception-qualification",
resultId,
sourceResultId: `lab-v1-vegetation-shadow-${"9".repeat(64)}`,
configSha256: null,
runCreatedAtUtc: "2026-08-29T18:05:11.329061+00:00",
publishedAtUtc: "2026-08-30T12:00:00.000Z",
replayCapability: {
schemaVersion: "missioncore.observation-lab-replay-capability/v1",
kind: "canonical-recorded-rerun",
viewerProfile: "recorded-session",
timeline: "session_time",
activation: "explicit",
commandsEnabled: false,
},
provenance: canonicalProvenance(),
...overrides,
};
}
test("Observatory admits only the exact typed canonical recorded run", () => {
const binding = observatoryRecordedRunBinding(resultId, lab());
assert.deepEqual(binding, {
kind: "canonical-recorded-rerun",
evidenceSessionId: resultId,
sourceSessionId,
resultId,
viewerProfile: "recorded-session",
timeline: "session_time",
activation: "explicit",
});
assert.equal(
observatoryRecordedRunBinding(resultId, lab({ replayCapability: null })),
null,
);
assert.throws(
() => observatoryRecordedRunBinding("different-session", lab()),
ObservatoryRecordedRunContractError,
);
assert.throws(
() => observatoryRecordedRunBinding(
resultId,
lab({ sourceSessionId: "RAVNOVES004TREE" }),
),
ObservatoryRecordedRunContractError,
);
assert.throws(
() => observatoryRecordedRunBinding(
resultId,
lab({ configSha256: "a".repeat(64) }),
),
ObservatoryRecordedRunContractError,
);
assert.throws(
() => observatoryRecordedRunBinding(
resultId,
lab({ sourceResultId: "legacy-result" }),
),
ObservatoryRecordedRunContractError,
);
const invalidProvenance = canonicalProvenance();
invalidProvenance.method.components[0].identity_sha256 = "0".repeat(64);
assert.throws(
() => observatoryRecordedRunBinding(
resultId,
lab({ provenance: invalidProvenance }),
),
ObservatoryRecordedRunContractError,
);
});
test("Observatory rechecks the selected source and sealed review before mounting replay", () => {
const binding = observatoryRecordedRunBinding(resultId, lab());
const review = { sessionId: sourceSessionId, frameCount: 6830 };
assert.equal(
admitObservatoryRecordedRunReview(
binding,
sourceSessionId,
{ resultId, routeFullReview: review },
),
review,
);
assert.throws(
() => admitObservatoryRecordedRunReview(
binding,
"another-session",
{ resultId, routeFullReview: review },
),
ObservatoryRecordedRunContractError,
);
assert.throws(
() => admitObservatoryRecordedRunReview(
binding,
sourceSessionId,
{ resultId, routeFullReview: { ...review, sessionId: "another-session" } },
),
ObservatoryRecordedRunContractError,
);
});
test("Observatory run admission remains metadata-only until explicit UI activation", async () => {
const source = await readFile(
new URL("../src/core/observatory/recordedRun.ts", import.meta.url),
"utf8",
);
assert.match(source, /fetchVegetationShadowResultMetadata/);
assert.doesNotMatch(
source,
/fetchVegetationShadowResult\(|advanced-index|resolveObservationSessionReplay|resolveCanonicalLabReplay|RerunViewport|recording\.rrd/,
);
});
@@ -46,12 +46,25 @@ test("Observatory is the third independent Polygon workspace", () => {
assert.equal(productModel.workspaceById("lab-archive").kind, "lab-archive");
});
test("Observatory reads catalog evidence without inheriting replay or LAB composition", async () => {
const [app, workspaceHub, workspace, hook, viewerProfiles, styles] = await Promise.all([
test("Observatory mounts the one shared canonical replay only after explicit admission", async () => {
const [
app,
workspaceHub,
workspace,
hook,
recordedRun,
sharedReplay,
legacyReplayWrapper,
viewerProfiles,
styles,
] = await Promise.all([
read("App.tsx"),
read("workspaces/Workspaces.tsx"),
read("workspaces/observatory/ObservatoryWorkspace.tsx"),
read("core/observatory/useObservatoryCatalog.ts"),
read("core/observatory/recordedRun.ts"),
read("components/laboratory/CanonicalVegetationRerunReplay.tsx"),
read("workspaces/laboratory/CanonicalVegetationRerunReplay.tsx"),
read("core/observation/viewerProfile.ts"),
read("styles/observatory.css"),
]);
@@ -68,11 +81,30 @@ test("Observatory reads catalog evidence without inheriting replay or LAB compos
assert.match(workspace, /вне текущего загруженного среза/);
assert.match(workspace, /observatory-notice__copy/);
assert.match(workspace, /observatory-evidence-card/);
assert.match(workspace, /Открыть визуальный разбор/);
assert.match(workspace, /replay\.kind === "ready"[\s\S]*<CanonicalVegetationRerunReplay/);
assert.match(workspace, /Проверяем точную связь результата/);
assert.match(workspace, /role="alert"/);
assert.match(workspace, /Повторить/);
assert.match(workspace, /Закрыть разбор/);
assert.match(workspace, /const selectSession[\s\S]*closeReplay\(\);[\s\S]*setSelectedSessionId/);
assert.match(workspace, /data-observatory-authority="observation-only"/);
assert.doesNotMatch(workspace, /Нарушена связь|compactIdentity/);
assert.doesNotMatch(
`${workspace}\n${hook}`,
/RerunViewport|ObservationSessionSelect|resolveObservationSessionReplay|deleteObservationSession|setInterval|setTimeout/,
/RerunViewport|ObservationSessionSelect|resolveObservationSessionReplay|resolveCanonicalLabReplay|deleteObservationSession|setInterval|setTimeout|useObservationSessions|useAdvancedLaboratoryCatalog|advanced-index|prefetch|preload/,
);
assert.equal(sharedReplay.match(/<RerunViewport\b/g)?.length, 1);
assert.match(sharedReplay, /recordedSessionRerunProfile/);
assert.match(sharedReplay, /timelineStartSeconds/);
assert.doesNotMatch(sharedReplay, /live-acquisition|lab-recorded-evidence/);
assert.match(
legacyReplayWrapper,
/export \{ CanonicalVegetationRerunReplay \} from "\.\.\/\.\.\/components\/laboratory\/CanonicalVegetationRerunReplay"/,
);
assert.match(recordedRun, /fetchVegetationShadowResultMetadata/);
assert.doesNotMatch(recordedRun, /advanced-index|recording\.rrd|canonical-replay\.rrd/);
assert.doesNotMatch(workspace, /workspaces\/laboratory|LaboratoryRecordedClipPlayer|SimulationViewport/);
assert.match(viewerProfiles, /kind: "live-acquisition"/);
assert.match(viewerProfiles, /kind: "recorded-session"/);
assert.match(viewerProfiles, /kind: "lab-recorded-evidence"/);
@@ -470,7 +470,7 @@ test("vegetation realtime LAB uses one upstream Rerun clock and keeps archival r
"utf8",
),
readFile(
new URL("../src/workspaces/laboratory/CanonicalVegetationRerunReplay.tsx", import.meta.url),
new URL("../src/components/laboratory/CanonicalVegetationRerunReplay.tsx", import.meta.url),
"utf8",
),
]);