feat(lab): publish fail-closed TGS evidence
This commit is contained in:
@@ -7,6 +7,7 @@ let server;
|
||||
let fetchAdvancedLaboratoryResults;
|
||||
let fetchAdvancedLaboratoryIndex;
|
||||
let fetchAdvancedLaboratoryResult;
|
||||
let fetchM49TgsAnchorSpatial;
|
||||
let AdvancedLaboratoryContractError;
|
||||
let buildLaboratoryCatalog;
|
||||
let buildLaboratoryProfiles;
|
||||
@@ -836,6 +837,77 @@ function e40() {
|
||||
};
|
||||
}
|
||||
|
||||
function m49View() {
|
||||
const anchors = [171, 306, 368, 402, 450, 509, 525, 744, 1122, 1856];
|
||||
return {
|
||||
schema_version: "missioncore.m49-tgs-fail-closed-view/v1",
|
||||
result_id: `m49-tgs-fail-closed-${"2".repeat(64)}`,
|
||||
created_at_utc: "2026-08-26T17:09:43Z",
|
||||
source: {
|
||||
source_id: "RAVNOVES00",
|
||||
source_session_id: "20260720T065719Z_viewer_live",
|
||||
source_pack_sha256: "3".repeat(64),
|
||||
linked_visual_result_id: `m4-threat-replay-${"4".repeat(64)}`,
|
||||
anchor_frame_indices: anchors,
|
||||
},
|
||||
configuration: {
|
||||
profile_id: "m49-ravnoves00-tgs-fail-closed-evidence/v1",
|
||||
config_sha256: "5".repeat(64),
|
||||
coordinate_frame: "map-gravity-local",
|
||||
primary_profile: "causal_rolling_1s",
|
||||
cell_size_m: 0.45,
|
||||
radius_m: 12,
|
||||
},
|
||||
execution: {
|
||||
worker: "Worker 006",
|
||||
device: "cpu",
|
||||
gpu_used: false,
|
||||
wrapper_elapsed_seconds: 12.1,
|
||||
},
|
||||
metrics: {
|
||||
anchor_count: 10,
|
||||
anchor_profile_count: 20,
|
||||
all_eligible_points_accounted: true,
|
||||
costmap_cell_count: 2244,
|
||||
process_wall_current_p50_ms: 20,
|
||||
process_wall_current_max_ms: 30,
|
||||
process_wall_rolling_p50_ms: 30,
|
||||
process_wall_rolling_max_ms: 40,
|
||||
process_max_rss_kib: 9292,
|
||||
primary: anchors.map((anchor, slot) => ({
|
||||
anchor_frame_index: anchor,
|
||||
slot,
|
||||
profile_id: "causal_rolling_1s",
|
||||
point_count: 3,
|
||||
ground_point_count: 1,
|
||||
nonground_point_count: 1,
|
||||
rejected_point_count: 1,
|
||||
ground_cell_count: 1,
|
||||
nonground_cell_count: 1,
|
||||
rejected_cell_count: 1,
|
||||
unobserved_cell_count: 2241,
|
||||
all_points_accounted: true,
|
||||
})),
|
||||
},
|
||||
acceptance: {
|
||||
representation_complete: true,
|
||||
all_points_accounted: true,
|
||||
aos_absent: true,
|
||||
gpu_absent: true,
|
||||
visual_quality_accepted: false,
|
||||
traversability_accepted: false,
|
||||
},
|
||||
decision: {
|
||||
state: "visual-review-required",
|
||||
candidate_retained: true,
|
||||
next_action: "Review the ten anchors.",
|
||||
},
|
||||
limitations: ["bounded diagnostic evidence"],
|
||||
ground_truth: false,
|
||||
access: "read-only",
|
||||
};
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
@@ -850,6 +922,9 @@ before(async () => {
|
||||
fetchAdvancedLaboratoryIndex,
|
||||
fetchAdvancedLaboratoryResult,
|
||||
} = await server.ssrLoadModule("/src/core/laboratory/advancedIndex.ts"));
|
||||
({ fetchM49TgsAnchorSpatial } = await server.ssrLoadModule(
|
||||
"/src/core/laboratory/m49TgsFailClosed.ts",
|
||||
));
|
||||
({
|
||||
buildLaboratoryCatalog,
|
||||
buildLaboratoryProfiles,
|
||||
@@ -1596,6 +1671,62 @@ test("selected advanced LAB fetches only its own strict catalog", async () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test("selected M49 LAB preserves the sealed fail-closed contract", async () => {
|
||||
const payload = m49View();
|
||||
const requests = [];
|
||||
const decoded = await fetchAdvancedLaboratoryResult(
|
||||
"m49-tgs-fail-closed-evidence",
|
||||
{
|
||||
resultId: payload.result_id,
|
||||
fetcher: async (input, init) => {
|
||||
requests.push({ input: String(input), method: init?.method });
|
||||
return new Response(JSON.stringify(payload), { status: 200 });
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
assert.equal(decoded.m49Tgs.metrics.anchorCount, 10);
|
||||
assert.equal(decoded.m49Tgs.metrics.costmapCellCount, 2244);
|
||||
assert.equal(decoded.m49Tgs.acceptance.visualQualityAccepted, false);
|
||||
assert.deepEqual(requests, [{
|
||||
input: `/api/v1/laboratory/m49/tgs-fail-closed/${payload.result_id}`,
|
||||
method: "GET",
|
||||
}]);
|
||||
});
|
||||
|
||||
test("M49 anchor fetch keeps every point and all four costmap states", async () => {
|
||||
const resultId = m49View().result_id;
|
||||
const centers = Array.from({ length: 2244 }, (_, index) => [index * 0.45, 0]);
|
||||
const states = Array.from({ length: 2244 }, (_, index) => index % 4);
|
||||
const zBounds = states.map((state) => state === 0 ? [null, null] : [0, 0.2]);
|
||||
const decoded = await fetchM49TgsAnchorSpatial(resultId, 171, "causal_rolling_1s", {
|
||||
fetcher: async () => new Response(JSON.stringify({
|
||||
schema_version: "missioncore.m49-tgs-anchor-spatial/v1",
|
||||
result_id: resultId,
|
||||
anchor_frame_index: 171,
|
||||
source_sequence: 171,
|
||||
profile: "causal_rolling_1s",
|
||||
coordinate_frame: "map-gravity-local",
|
||||
points_xyz_m: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
|
||||
point_states: [1, 2, 3],
|
||||
costmap: {
|
||||
cell_size_m: 0.45,
|
||||
radius_m: 12,
|
||||
centers_xy_m: centers,
|
||||
states,
|
||||
z_bounds_m: zBounds,
|
||||
},
|
||||
all_points_accounted: true,
|
||||
aos_used: false,
|
||||
access: "read-only",
|
||||
}), { status: 200 }),
|
||||
});
|
||||
|
||||
assert.deepEqual(decoded.pointStates, [1, 2, 3]);
|
||||
assert.equal(decoded.costmap.states.length, 2244);
|
||||
assert.deepEqual(new Set(decoded.costmap.states), new Set([0, 1, 2, 3]));
|
||||
});
|
||||
|
||||
test("keeps valid LAB catalogs available when one transport endpoint fails", async () => {
|
||||
const decoded = await fetchAdvancedLaboratoryResults({
|
||||
fetcher: async (input) => {
|
||||
|
||||
@@ -799,7 +799,23 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
|
||||
assert.match(metricScene, /OrbitControls/);
|
||||
assert.match(visual, /LOCAL SLAM/);
|
||||
assert.match(visual, /showLocalSurface/);
|
||||
assert.match(visual, /pointCloudBodyXyzM=\{spatialFrame\.pointCloudBodyXyzM\}/);
|
||||
assert.match(
|
||||
visual,
|
||||
/pointCloudBodyXyzM=\{classifiedSpatialFrame[\s\S]*\? classifiedPointsBody[\s\S]*: spatialFrame\.pointCloudBodyXyzM\}/,
|
||||
);
|
||||
assert.match(
|
||||
visual,
|
||||
/const classifiedSpatialFrame = !displayingBufferedFrame[\s\S]*classifiedSpatialLayer\?\.frame\?\.sourceSequence === frame\?\.sequence[\s\S]*spatialFrame\?\.sequence === frame\?\.sequence/,
|
||||
);
|
||||
assert.match(
|
||||
visual,
|
||||
/mapGravityLocalSensorToBodyGround[\s\S]*rotated\[2\] \+ nominalSensorHeightM/,
|
||||
);
|
||||
assert.match(
|
||||
visual,
|
||||
/zBoundsM: \[[\s\S]*minimumSensorRelativeZ \+ nominalSensorHeightM[\s\S]*maximumSensorRelativeZ \+ nominalSensorHeightM/,
|
||||
);
|
||||
assert.match(visual, /classifiedCells=\{classifiedCellsBody\}/);
|
||||
assert.match(metricScene, /Локальная SLAM-поверхность/);
|
||||
assert.match(visual, /showJumpToEnd=\{false\}/);
|
||||
assert.doesNotMatch(visual, /Назад на 5 секунд/);
|
||||
|
||||
Reference in New Issue
Block a user