fix(lab): restore semantic overlay in M4.7

This commit is contained in:
DCCONSTRUCTIONS
2026-08-23 22:40:07 +03:00
parent 34ed8a0f5f
commit a55ef475d9
11 changed files with 289 additions and 32 deletions
+40 -4
View File
@@ -12,11 +12,17 @@ from pathlib import Path
from typing import Final
from k1link.perception.reference_graph_result import read_reference_graph_result
from k1link.perception.semantic_slam_replay import (
SEMANTIC_SLAM_MANIFEST_NAME,
SEMANTIC_SLAM_REPORT_NAME,
SEMANTIC_SLAM_TAXONOMY_NAME,
read_semantic_slam_replay_result,
)
from k1link.perception.threat_replay import read_threat_replay_result
M47_REFERENCE_GRAPH_LAB_SCHEMA: Final = "missioncore.reference-perception-graph-lab/v1"
M47_REFERENCE_GRAPH_LAB_SCHEMA: Final = "missioncore.reference-perception-graph-lab/v2"
M47_REFERENCE_GRAPH_LAB_REPORT_SCHEMA: Final = (
"missioncore.reference-perception-graph-lab-report/v1"
"missioncore.reference-perception-graph-lab-report/v2"
)
M47_REFERENCE_GRAPH_LAB_PREFIX: Final = "m47-reference-graph-lab-"
@@ -37,10 +43,12 @@ def publish_m47_reference_graph_lab(
*,
graph_result_root: Path,
visual_result_root: Path,
semantic_result_root: Path,
output_root: Path,
) -> M47ReferenceGraphLab:
graph = read_reference_graph_result(graph_result_root)
visual = read_threat_replay_result(visual_result_root)
semantic = read_semantic_slam_replay_result(semantic_result_root)
if not graph.accepted or not visual.accepted:
raise M47ReferenceGraphLabError("both graph and visual replay must be accepted")
graph_report = graph.report
@@ -49,6 +57,9 @@ def publish_m47_reference_graph_lab(
parity = _object(graph_report.get("accepted_parity"), "graph parity")
mismatches = _object(parity.get("mismatch_counts"), "graph parity mismatches")
visual_identity = _object(visual.manifest.get("identity"), "visual identity")
semantic_identity = _object(semantic.manifest.get("identity"), "semantic identity")
semantic_frames = _object(semantic_identity.get("counts"), "semantic counts")
semantic_frame_counts = _object(semantic_frames.get("frames"), "semantic frame counts")
if (
parity.get("accepted") is not True
or parity.get("expected_frames") != 4489
@@ -68,6 +79,13 @@ def publish_m47_reference_graph_lab(
or parity.get("temporal_frames_sha256") != visual_identity.get("temporal_frames_sha256")
):
raise M47ReferenceGraphLabError("graph-to-visual parity proof changed")
if (
semantic_identity.get("base_m4_result_id") != visual.result_id
or semantic_identity.get("source_session_id") != visual_identity.get("source_session_id")
or semantic_frame_counts.get("total") != 4489
or semantic_frame_counts.get("mask_available") != 4489
):
raise M47ReferenceGraphLabError("semantic-to-visual binding proof changed")
terminal = _object(graph_report.get("terminal_outcomes"), "terminal outcomes")
queues = _object(graph_report.get("queue_high_watermarks"), "queue high watermarks")
execution = _object(graph_report.get("execution"), "graph execution")
@@ -81,23 +99,30 @@ def publish_m47_reference_graph_lab(
}
visual_evidence = {
"linked_result_id": visual.result_id,
"semantic_result_id": semantic.result_id,
"binding": "exact-threat-and-temporal-ledger-parity",
"semantic_binding": "exact-sequence-and-session-time",
"timeline_frames": 4489,
"shared_recorded_clock": True,
"video_camera_3d_plan_available": True,
"camera_semantic_overlay_available": True,
"regression_sequences": [138, 274, 1880, 2584],
"independent_ground_truth": False,
}
identity: dict[str, object] = {
"schema_version": M47_REFERENCE_GRAPH_LAB_SCHEMA,
"binding_id": "m47-reference-graph-visual-binding/v1",
"binding_id": "m47-reference-graph-visual-binding/v2",
"source": {
"source_id": "RAVNOVES00",
"source_session_id": visual_identity.get("source_session_id"),
"graph_result_id": graph.result_id,
"visual_result_id": visual.result_id,
"semantic_result_id": semantic.result_id,
"temporal_frames_sha256": parity.get("temporal_frames_sha256"),
"threat_frames_sha256": parity.get("threat_frames_sha256"),
"semantic_frames_sha256": semantic_identity.get("semantic_frames_sha256"),
"semantic_masks_sha256": semantic_identity.get("semantic_masks_sha256"),
"semantic_taxonomy_sha256": semantic_identity.get("taxonomy_sha256"),
},
"method": {
"graph_id": graph_manifest.get("graph_id"),
@@ -179,6 +204,9 @@ def publish_m47_reference_graph_lab(
"graph-runtime.json": graph.result_root / "runtime.json",
"visual-manifest.json": visual.result_root / "manifest.json",
"visual-report.json": visual.result_root / "report.json",
"semantic-manifest.json": semantic.result_root / SEMANTIC_SLAM_MANIFEST_NAME,
"semantic-report.json": semantic.result_root / SEMANTIC_SLAM_REPORT_NAME,
"semantic-taxonomy.json": semantic.result_root / SEMANTIC_SLAM_TAXONOMY_NAME,
}
for name, source in sources.items():
shutil.copyfile(source, staging / name)
@@ -190,6 +218,9 @@ def publish_m47_reference_graph_lab(
"graph-runtime.json": "m47-runtime",
"visual-manifest.json": "linked-visual-manifest",
"visual-report.json": "linked-visual-report",
"semantic-manifest.json": "linked-semantic-manifest",
"semantic-report.json": "linked-semantic-report",
"semantic-taxonomy.json": "linked-semantic-taxonomy",
}
schemas = {
"graph-manifest.json": graph_manifest.get("schema_version"),
@@ -197,6 +228,11 @@ def publish_m47_reference_graph_lab(
"graph-runtime.json": graph_runtime.get("schema_version"),
"visual-manifest.json": visual.manifest.get("schema_version"),
"visual-report.json": visual.report.get("schema_version"),
"semantic-manifest.json": semantic.manifest.get("schema_version"),
"semantic-report.json": semantic.report.get("schema_version"),
"semantic-taxonomy.json": _read_json(
semantic.result_root / SEMANTIC_SLAM_TAXONOMY_NAME
).get("schema_version"),
"report.json": M47_REFERENCE_GRAPH_LAB_REPORT_SCHEMA,
}
artifacts = [_artifact(staging / name, role, schemas[name]) for name, role in roles.items()]
@@ -247,7 +283,7 @@ def read_m47_reference_graph_lab(result_root: Path) -> M47ReferenceGraphLab:
):
raise M47ReferenceGraphLabError("M4.7 LAB identity changed")
artifacts = manifest.get("artifacts")
if not isinstance(artifacts, list) or len(artifacts) != 6:
if not isinstance(artifacts, list) or len(artifacts) != 9:
raise M47ReferenceGraphLabError("M4.7 LAB artifact inventory changed")
for value in artifacts:
descriptor = _object(value, "LAB artifact")
+4
View File
@@ -137,6 +137,10 @@ def build_e47_semantic_slam_router(
"access": "read-only-diagnostic-shadow",
}
@router.get("/results/{result_id}")
def get_result(result_id: str) -> dict[str, object]:
return _project_result(result(result_id))
@router.get("/results/{result_id}/timeline/chunk")
def get_timeline_chunk(
result_id: str,