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
@@ -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",
]);
});