fix(lab): enforce canonical replay runtime

This commit is contained in:
DCCONSTRUCTIONS
2026-08-29 22:42:30 +03:00
parent 525ab74168
commit bd2892140f
17 changed files with 1765 additions and 507 deletions
@@ -847,8 +847,9 @@ test("recorded VIDEO clock cannot reverse an explicit operator pause", () => {
});
test("M4.6 viewer keeps media and spatial panes on one playback clock", async () => {
const [visual, visualCss, imageScene, videoScene, pointOverlay, metricScene] = await Promise.all([
const [visual, canonical, visualCss, imageScene, videoScene, pointOverlay, metricScene] = await Promise.all([
readFile(new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url), "utf8"),
readFile(new URL("../src/components/laboratory/CanonicalRecordedLabReplay.tsx", import.meta.url), "utf8"),
readFile(new URL("../src/styles/m4-replay-threat.css", import.meta.url), "utf8"),
readFile(new URL("../src/components/laboratory/RecordedEvidenceImageScene.tsx", import.meta.url), "utf8"),
readFile(new URL("../src/components/laboratory/RecordedEvidenceVideoScene.tsx", import.meta.url), "utf8"),
@@ -858,7 +859,8 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
assert.match(visual, /<RecordedEvidenceVideoScene/);
assert.match(visual, /<RecordedEvidenceImageScene/);
assert.match(visual, /<LaboratoryMetricEvidenceScene/);
assert.match(visual, /m4-replay-threat-visual__deck/);
assert.match(visual, /<CanonicalRecordedLabReplay/);
assert.match(canonical, /m4-replay-threat-visual__deck/);
assert.match(visual, /lastFrameRef/);
assert.match(visual, /lastSpatialFrameRef/);
assert.match(visual, /const spatialFrame = frame\?\.spatialAvailable/);
@@ -876,19 +878,32 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
assert.match(visual, /pointCloudOverlay=/);
assert.match(visual, /mediaMode/);
assert.match(visual, /spatialMode/);
assert.match(visual, /current === next \? null : next/);
assert.match(visual, /data-split=\{splitView \? "true" : undefined\}/);
assert.match(visual, /<SplitPane/);
assert.match(visual, /primarySize=\{splitView \? splitPrimarySize : mediaMode \? 100 : 0\}/);
assert.match(visual, /resizable=\{splitView\}/);
assert.match(visual, /separatorLabel="Изменить размер VIDEO\/CAMERA и 3D\/PLAN"/);
assert.match(visual, /secondaryMode=\{\{/);
assert.match(canonical, /current === next \? null : next/);
assert.match(canonical, /data-split=\{splitView \? "true" : undefined\}/);
assert.match(canonical, /<SplitPane/);
assert.match(canonical, /primary=\{mediaPane\}/);
assert.match(canonical, /secondary=\{spatialPane/);
assert.match(canonical, /primarySize=\{splitView \? splitPrimarySize : mediaMode !== "none" \? 100 : 0\}/);
assert.match(canonical, /resizable=\{splitView\}/);
assert.match(canonical, /separatorLabel="Изменить размер VIDEO\/CAMERA и 3D\/PLAN"/);
assert.match(canonical, /secondaryMode=\{\{/);
assert.match(visual, /playback=\{playbackController\.playback\}/);
assert.match(visual, /clock: mediaMode === "video" \? "external" : "animation"/);
assert.match(visual, /clock: "animation"/);
assert.match(visual, /useCanonicalRecordedLabReplayState/);
assert.match(canonical, /current === next \? null : next/);
assert.match(visual, /timelineFrame\.activeSequence \+ 1/);
assert.match(visual, /segmentCount=\{timeline\.frameCount\}/);
assert.match(visual, /onPlaybackChange=\{playbackController\.synchronize\}/);
assert.match(visual, /onPlayingRejected=\{\(\) => playbackController\.setPlaying\(false\)\}/);
assert.match(
await readFile(new URL("../src/components/laboratory/useRecordedEvidencePlayback.ts", import.meta.url), "utf8"),
/if \(clock === "animation"\) return;/,
);
assert.match(visual, /playbackAuthority="host"/);
assert.match(visual, /playbackTransport="epoch-stream"/);
assert.match(
await readFile(new URL("../src/components/RecordedFmp4Player.tsx", import.meta.url), "utf8"),
/if \(playbackAuthority === "host"\) return;/,
);
assert.match(visual, /currentSeconds: playbackController\.playback\.currentSeconds/);
assert.match(visualCss, /m4-replay-threat-visual__deck > \.nodedc-split-pane/);
assert.match(visualCss, /m4-replay-threat-visual__pane-toolbar\[data-pane-toolbar="media"\]/);
@@ -951,12 +966,18 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
});
test("M4.6 keeps the recorded VIDEO player mounted across media mode toggles", async () => {
const visual = await readFile(
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
"utf8",
);
assert.match(visual, /const mediaPane = \(/);
assert.match(visual, /hidden=\{!mediaMode\}/);
const [visual, canonical] = await Promise.all([
readFile(
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
"utf8",
),
readFile(
new URL("../src/components/laboratory/CanonicalRecordedLabReplay.tsx", import.meta.url),
"utf8",
),
]);
assert.match(canonical, /const mediaPane = \(/);
assert.match(canonical, /hidden=\{mediaMode === "none"\}/);
assert.match(visual, /data-media="video"/);
assert.match(visual, /hidden=\{mediaMode !== "video"\}/);
assert.match(visual, /\{videoSource \? \(/);
@@ -75,10 +75,16 @@ test("semantic point alignment follows the last qualified spatial increment", as
});
test("M4 keeps independent semantic controls in media and spatial panes", async () => {
const source = await readFile(
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
"utf8",
);
const [source, canonical] = await Promise.all([
readFile(
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
"utf8",
),
readFile(
new URL("../src/components/laboratory/CanonicalRecordedLabReplay.tsx", import.meta.url),
"utf8",
),
]);
assert.match(source, /showMediaSemantic/);
assert.match(source, /showSpatialSemantic/);
assert.match(source, /activeSpatialSemantic = spatialSemantic \?\? activeSemantic/);
@@ -89,9 +95,9 @@ test("M4 keeps independent semantic controls in media and spatial panes", async
assert.match(source, /\|\| !showSpatialSemantic/);
assert.match(source, /aria-label="Слои камеры и видео"/);
assert.match(source, /aria-label="Слои 3D и плана"/);
assert.match(source, /data-pane-mode="media"/);
assert.match(source, /data-pane-mode="spatial"/);
assert.match(source, /modeControlsVisible=\{!splitView\}/);
assert.match(canonical, /data-pane-mode="media"/);
assert.match(canonical, /data-pane-mode="spatial"/);
assert.match(canonical, /modeControlsVisible=\{!splitView\}/);
assert.match(source, /semanticOverlay=\{mediaMode === "video" \? semanticOverlay : undefined\}/);
});
@@ -6,7 +6,9 @@ import { createServer } from "vite";
let server;
let fetchVegetationBenchmarkResult;
let fetchCanonicalRecordedLabSpatialFrame;
let fetchVegetationShadowResult;
let fetchVegetationRouteTgsAnchor;
let vegetationFullRouteMaskUrl;
before(async () => {
@@ -17,7 +19,9 @@ before(async () => {
});
({
fetchVegetationBenchmarkResult,
fetchCanonicalRecordedLabSpatialFrame,
fetchVegetationShadowResult,
fetchVegetationRouteTgsAnchor,
vegetationFullRouteMaskUrl,
} = await server.ssrLoadModule(
"/src/core/laboratory/vegetationShadow.ts",
@@ -365,8 +369,68 @@ test("vegetation GOOSE benchmark opens through its separate archival endpoint",
assert.equal(result.validationCases.length, 12);
});
test("vegetation route TGS anchor keeps exact sealed metric shapes", async () => {
let requestedUrl = "";
const anchor = await fetchVegetationRouteTgsAnchor(resultId, 409, {
fetcher: async (url) => {
requestedUrl = String(url);
return new Response(JSON.stringify({
schema_version: "missioncore.lab-v1-route-tgs-anchor/v1",
source_sequence: 409,
slot: 1,
current_points_xyz_m: [[1, 2, 3], [4, 5, 6]],
costmap: {
cell_size_m: 0.45,
centers_xy_m: Array.from({ length: 2244 }, (_, index) => [index, -index]),
state_codes: Array.from({ length: 2244 }, (_, index) => index % 4),
z_bounds_m: Array.from({ length: 2244 }, () => [null, null]),
},
}), { status: 200, headers: { "Content-Type": "application/json" } });
},
});
assert.equal(
requestedUrl,
`/api/v1/laboratory/vegetation-shadow/${resultId}/route-tgs-anchor/409`,
);
assert.equal(anchor.sourceSequence, 409);
assert.equal(anchor.currentPointsXyzM.length, 2);
assert.equal(anchor.costmap.centersXyM.length, 2244);
assert.deepEqual(new Set(anchor.costmap.stateCodes), new Set([0, 1, 2, 3]));
});
test("canonical recorded LAB spatial frame keeps source, SLAM and body identity on one clock", async () => {
const generation = "e".repeat(64);
let requestedUrl = "";
const frame = await fetchCanonicalRecordedLabSpatialFrame("session-004", generation, 82_770_000_000, {
fetcher: async (url) => {
requestedUrl = String(url);
return new Response(JSON.stringify({
schema_version: "missioncore.canonical-recorded-lab-spatial-frame/v1",
target_time_ns: 82_770_000_000,
source_time_ns: 82_769_535_708,
pose_time_ns: 82_769_535_708,
trajectory_time_ns: 82_700_000_000,
source_point_count: 2,
source_points_body_xyz_m: [[1, 2, 3], [4, 5, 6]],
local_slam_body_xyz_m: [[0, 0, 0], [1, 0, 0]],
body_frame: {
origin_map_xyz_m: [33, 4, 1],
basis_map_from_body: [[1, 0, 0], [0, 1, 0], [0, 0, 1]],
},
}), { status: 200, headers: { "Content-Type": "application/json" } });
},
});
assert.equal(
requestedUrl,
`/api/v1/observation-sessions/session-004/canonical-lab/spatial-frame?generation=${generation}&time_ns=82770000000`,
);
assert.equal(frame.sourcePointCount, 2);
assert.equal(frame.localSlamBodyXyzM.length, 2);
assert.deepEqual(frame.bodyFrame.originMapXyzM, [33, 4, 1]);
});
test("vegetation realtime LAB and archival benchmark use separate admitted instruments", async () => {
const [resultSource, benchmarkSource, m49Source] = await Promise.all([
const [resultSource, benchmarkSource, m49Source, canonicalSource] = await Promise.all([
readFile(
new URL("../src/workspaces/laboratory/VegetationShadowResult.tsx", import.meta.url),
"utf8",
@@ -379,6 +443,10 @@ test("vegetation realtime LAB and archival benchmark use separate admitted instr
new URL("../src/workspaces/laboratory/M49TgsFullShadowEvidence.tsx", import.meta.url),
"utf8",
),
readFile(
new URL("../src/components/laboratory/CanonicalRecordedLabReplay.tsx", import.meta.url),
"utf8",
),
]);
assert.doesNotMatch(resultSource, /M48MaskComparisonVisual/);
assert.match(resultSource, /M49TgsFullShadowEvidence/);
@@ -389,12 +457,28 @@ test("vegetation realtime LAB and archival benchmark use separate admitted instr
assert.equal(resultSource.match(/<LaboratoryEvidence\b/g)?.length, 2);
assert.doesNotMatch(resultSource, /RAVNOVES004TREE mixed route review/);
assert.match(resultSource, /RAVNOVES004TREE full recorded review/);
assert.match(resultSource, /LaboratoryRecordedClipPlayer/);
assert.match(resultSource, /RerunViewport/);
assert.match(resultSource, /M48EvidenceModeRail/);
assert.match(resultSource, /CanonicalRecordedLabReplay/);
assert.match(resultSource, /RecordedEvidenceVideoScene/);
assert.match(resultSource, /LaboratoryMetricEvidenceScene/);
assert.doesNotMatch(resultSource, /RerunViewport/);
assert.match(resultSource, /fetchCanonicalRecordedLabSpatialFrame/);
assert.match(resultSource, /useCanonicalRecordedLabReplayState/);
assert.match(resultSource, /playbackTransport="epoch-stream"/);
assert.match(resultSource, /causalTgsCase/);
assert.match(resultSource, /latest causal of 10 sealed anchors/);
assert.doesNotMatch(resultSource, /LaboratoryRecordedClipPlayer|M48EvidenceModeRail/);
assert.doesNotMatch(resultSource, /assets\.tgs|<img/);
assert.match(resultSource, /SOURCE POINTS/);
assert.match(resultSource, /LOCAL SLAM/);
assert.match(resultSource, /TGS COSTMAP/);
assert.match(resultSource, /onClick=\{\(\) => setShowTgs\(\(visible\) => !visible\)\}/);
assert.match(resultSource, /showClassifiedCells=\{showTgs && Boolean\(packedTgsCells\)\}/);
assert.doesNotMatch(resultSource, /setShowTgs\(false\)/);
assert.doesNotMatch(resultSource, /setPlaying\(false\);[\s\S]{0,160}setShowTgs/);
assert.match(canonicalSource, /primary=\{mediaPane\}/);
assert.match(canonicalSource, /secondary=\{spatialPane/);
assert.match(canonicalSource, /missioncore\.canonical-recorded-lab-replay\/v1/);
assert.match(canonicalSource, /separatorLabel="Изменить размер VIDEO\/CAMERA и 3D\/PLAN"/);
assert.match(resultSource, /linked canonical M4\.9 TGS evidence/);
assert.match(resultSource, /linkedTgsResultId/);
assert.match(benchmarkSource, /M48MaskComparisonVisual/);