feat(lab): visualize dual evidence replay

This commit is contained in:
DCCONSTRUCTIONS
2026-08-05 19:18:14 +03:00
parent b0d0bc8d7f
commit de19229895
17 changed files with 1825 additions and 115 deletions
@@ -0,0 +1,187 @@
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 fetchM4ThreatReplayResult;
let fetchM4ThreatVisual;
let fetchM4ThreatVideoOverlay;
let selectM4ThreatVideoFrame;
const resultId = `m4-threat-replay-${"a".repeat(64)}`;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({
fetchM4ThreatReplayResult,
fetchM4ThreatVisual,
fetchM4ThreatVideoOverlay,
selectM4ThreatVideoFrame,
} = await server.ssrLoadModule("/src/core/laboratory/m4ReplayThreat.ts"));
});
after(async () => {
await server?.close();
});
function proposal(overrides = {}) {
return {
proposal_id: "proposal-1",
bbox_xyxy: [100, 120, 240, 360],
objectness: 0.91,
semantic_hint: "person",
occupied_support: false,
range_m: null,
threat_decision: "unknown",
threat_reason_codes: ["camera-only-no-metric-geometry"],
...overrides,
};
}
test("M4.6 decodes accepted dual-evidence result without physical authority", async () => {
const result = await fetchM4ThreatReplayResult({
fetcher: async () => new Response(JSON.stringify({
schema_version: "missioncore.m4-threat-replay-catalog/v1",
items: [{
schema_version: "missioncore.m4-threat-replay-view/v1",
result_id: resultId,
created_at_utc: "2026-08-05T15:36:01.553Z",
status: "accepted",
profile_id: "m4-ravnoves00-virtual-corridor/v1",
rig_profile_id: "virtual-handheld-body-1000x600/v1",
corridor_profile_id: "ravnoves00-forward-corridor-8m/v1",
source_result_ids: {
detector: `m4-detector-replay-${"b".repeat(64)}`,
geometry: `m4-geometry-replay-${"c".repeat(64)}`,
temporal: `m4-temporal-replay-${"d".repeat(64)}`,
},
metrics: {
decisions: { threat: 8010, "not-threat": 6610, unknown: 60832 },
evidence: { "camera-only": 10158, "current-metric": 27299, "stale-or-held": 37995 },
fixtures: { critical: 4, critical_false_not_threat: 0, passed: 9, total: 9 },
runtime: {
frames_per_second: 116.4,
provider_latency_p50_ms: 4.3,
provider_latency_p95_ms: 19.8,
provider_latency_max_ms: 194.3,
},
reason_counts: { "geometry-only-evidence": 21958 },
},
configuration: {
virtual_body_m: [1, 0.6],
nominal_sensor_height_m: 1.25,
forward_corridor_m: 8,
prediction_horizon_seconds: 5,
},
limitations: ["replay only"],
accepted: true,
authority: "replay-simulated",
physical_collision_accepted: false,
actuation_allowed: false,
}],
}), { status: 200 }),
});
assert.equal(result.resultId, resultId);
assert.equal(result.metrics.evidence.currentMetric, 27299);
assert.equal(result.metrics.fixtures.criticalFalseNotThreat, 0);
assert.deepEqual(result.configuration.virtualBodyM, [1, 0.6]);
});
test("M4.6 binds exact CAMERA and metric 3D evidence to one replay frame", async () => {
const frame = await fetchM4ThreatVisual(resultId, 1, {
fetcher: async () => new Response(JSON.stringify({
schema_version: "missioncore.perception-threat-visual-frame/v1",
result_id: resultId,
ordinal: 1,
sequence: 20,
frame_id: "frame-000020",
source_time_ns: 37421857292,
point_cloud_body_xyz_m: [[1, 0, 0.1], [2, 0.2, 0.3]],
point_cloud_source_count: 12000,
point_cloud_sample_count: 2,
metric_obstacles: [{
component_id: "temporal-20-1",
state: "current",
motion: "moving",
centroid_body_xyz_m: [2, 0.1, 0.4],
cell_centers_body_xyz_m: [[2, 0.1, 0.4]],
assessment: {
component_id: "temporal-20-1",
decision: "threat",
corridor_intersection: "intersects",
relative_speed_mps: 1.2,
closest_approach_m: 0.4,
ttc_seconds: 1.6,
reason_codes: ["geometry-only-evidence"],
},
}],
camera_proposals: [proposal()],
rig: { length_m: 1, width_m: 0.6, nominal_sensor_height_m: 1.25 },
corridor: {
forward_length_m: 8,
rear_margin_m: 0.5,
half_width_m: 0.5,
prediction_horizon_seconds: 5,
},
}), { status: 200 }),
});
assert.equal(frame.sequence, 20);
assert.equal(frame.metricObstacles[0].assessment.decision, "threat");
assert.equal(frame.cameraProposals[0].threatDecision, "unknown");
assert.equal(frame.pointCloudSampleCount, 2);
});
test("M4.6 full video preserves camera-only unknown and nearest-frame selection", async () => {
const overlay = await fetchM4ThreatVideoOverlay(resultId, {
fetcher: async () => new Response(JSON.stringify({
schema_version: "missioncore.m4-threat-video-overlay/v1",
result_id: resultId,
recorded_source: { session_id: "20260720T065719Z_viewer_live" },
image_width: 800,
image_height: 600,
timeline_start_seconds: 35.421857292,
timeline_end_seconds: 484.044857292,
frame_count: 4489,
frames: [
{
frame_index: 0,
session_seconds: 35.421857292,
source_available: true,
camera_proposals: [],
decision_counts: { threat: 0, "not-threat": 0, unknown: 0 },
},
{
frame_index: 1,
session_seconds: 35.521857292,
source_available: true,
camera_proposals: [proposal()],
decision_counts: { threat: 0, "not-threat": 0, unknown: 1 },
},
],
authority: "replay-simulated",
}), { status: 200 }),
});
assert.equal(overlay.frames[1].cameraProposals[0].rangeM, null);
assert.equal(selectM4ThreatVideoFrame(overlay.frames, 35.50).frameIndex, 1);
});
test("M4.6 viewer reuses shared video and metric evidence renderers", async () => {
const [visual, videoScene, metricScene] = await Promise.all([
readFile(new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url), "utf8"),
readFile(new URL("../src/components/laboratory/RecordedEvidenceVideoScene.tsx", import.meta.url), "utf8"),
readFile(new URL("../src/components/laboratory/LaboratoryMetricEvidenceScene.tsx", import.meta.url), "utf8"),
]);
assert.match(visual, /<RecordedEvidenceVideoScene/);
assert.match(visual, /<LaboratoryMetricEvidenceScene/);
assert.match(visual, /label: "VIDEO"/);
assert.match(visual, /label: "CAMERA"/);
assert.match(visual, /label: "3D"/);
assert.match(videoScene, /<RecordedFmp4Player/);
assert.match(metricScene, /OrbitControls/);
});