feat(lab): seal native risk review evidence

This commit is contained in:
DCCONSTRUCTIONS
2026-08-26 10:15:49 +03:00
parent c05db1fbe0
commit f9a76fed0e
7 changed files with 975 additions and 76 deletions
@@ -0,0 +1,471 @@
"""Seal native raw-fisheye M4.8Q risk review evidence as a terminal LAB phase."""
from __future__ import annotations
import hashlib
import json
import re
import shutil
import tempfile
from dataclasses import dataclass
from datetime import UTC, datetime
from pathlib import Path
from typing import Any, Final
from k1link.perception.fixed_class_detector_tournament import (
canonical_json,
false_authority,
sha256_path,
)
LAB_SCHEMA: Final = "missioncore.m48q-native-risk-quality-lab/v1"
REPORT_SCHEMA: Final = "missioncore.m48q-native-risk-quality-report/v1"
CATALOG_SCHEMA: Final = "missioncore.m48q-native-risk-review-catalog/v1"
CASE_SCHEMA: Final = "missioncore.m48q-native-risk-review-case/v1"
RESULT_PREFIX: Final = "m48q-native-risk-quality-lab-"
PROFILE_RELATIVE_PATH: Final = Path("config/perception/m48q-native-risk-case-mining-v1.json")
DETECTOR_PROFILE_RELATIVE_PATH: Final = Path(
"config/perception/rf-detr-large-native-kb4-risk-shadow-v0.json"
)
WORKER_RELATIVE_ROOT: Final = Path(
".runtime/worker-results/m48q-native-risk-case-mining/ravnoves00-native-raw-review-v3"
)
EXPECTED_PROFILE_SHA256: Final = "c455055e63578d505edc80b66d67e795916a3d0297cc18bfee5a6af7b032ceda"
EXPECTED_DETECTOR_PROFILE_SHA256: Final = (
"dbf4da5dbad6c3c22b1280b46ffcad81719bd183c81c263a4859847d829019b6"
)
EXPECTED_WORKER_RESULT_SHA256: Final = (
"a8f98d6d68abd6fd627caa05aaa3f048d69279a989b07fc2552b508af909a623"
)
EXPECTED_CASES_SHA256: Final = "9cea2a4a4558d761bc76b0d70474673ff07210473f53bd32cf178e8e0c8e179c"
EXPECTED_REPORT_IDENTITY_SHA256: Final = (
"b744775c0e08d18d728f04021cd2acf9b1ed6fcacf1520352ee04e06a6d5d324"
)
CASE_ID: Final = re.compile(r"^[0-9]{6}$")
class M48QNativeRiskQualityLabError(RuntimeError):
"""Raised when native M4.8Q evidence cannot be sealed honestly."""
@dataclass(frozen=True, slots=True)
class M48QNativeRiskQualityLabResult:
result_root: Path
result_id: str
manifest: dict[str, Any]
def build_m48q_native_risk_quality_lab(
*,
repository_root: Path,
output_root: Path,
) -> M48QNativeRiskQualityLabResult:
repository = repository_root.expanduser().resolve(strict=True)
profile_path = repository / PROFILE_RELATIVE_PATH
detector_profile_path = repository / DETECTOR_PROFILE_RELATIVE_PATH
worker_root = repository / WORKER_RELATIVE_ROOT
worker_result_path = worker_root / "result.json"
cases_path = worker_root / "cases.jsonl"
images_root = worker_root / "cases"
for path in (
profile_path,
detector_profile_path,
worker_result_path,
cases_path,
):
if path.is_symlink() or not path.is_file():
raise M48QNativeRiskQualityLabError(f"required M4.8Q evidence is missing: {path.name}")
if images_root.is_symlink() or not images_root.is_dir():
raise M48QNativeRiskQualityLabError("M4.8Q image evidence is missing")
expected_hashes = {
profile_path: EXPECTED_PROFILE_SHA256,
detector_profile_path: EXPECTED_DETECTOR_PROFILE_SHA256,
worker_result_path: EXPECTED_WORKER_RESULT_SHA256,
cases_path: EXPECTED_CASES_SHA256,
}
if any(sha256_path(path) != expected for path, expected in expected_hashes.items()):
raise M48QNativeRiskQualityLabError("M4.8Q source evidence identity changed")
profile = _read_object(profile_path)
detector_profile = _read_object(detector_profile_path)
worker_result = _read_object(worker_result_path)
cases = _read_cases(cases_path)
_validate_inputs(
profile=profile,
detector_profile=detector_profile,
worker_result=worker_result,
cases=cases,
images_root=images_root,
)
method = _method(profile, detector_profile, worker_result)
identity = {
"schema_version": LAB_SCHEMA,
"profile": {
"profile_id": profile["profile_id"],
"sha256": EXPECTED_PROFILE_SHA256,
},
"detector_profile": {
"profile_id": detector_profile["profile_id"],
"sha256": EXPECTED_DETECTOR_PROFILE_SHA256,
},
"source": {
"source_id": "RAVNOVES00",
"video_sha256": profile["source"]["video_sha256"],
"graph_result_sha256": worker_result["source"]["graph_result_sha256"],
"graph_frames_sha256": worker_result["source"]["graph_frames_sha256"],
"comparison_result_sha256": worker_result["source"]["comparison_result_sha256"],
"comparison_frames_sha256": worker_result["source"]["comparison_frames_sha256"],
"worker_result_sha256": EXPECTED_WORKER_RESULT_SHA256,
"cases_sha256": EXPECTED_CASES_SHA256,
},
"method": method,
"authority": false_authority(),
}
identity_sha256 = hashlib.sha256(canonical_json(identity)).hexdigest()
result_id = RESULT_PREFIX + identity_sha256
root = output_root.expanduser().absolute()
root.mkdir(mode=0o700, parents=True, exist_ok=True)
destination = root / result_id
if destination.exists():
manifest = _read_object(destination / "manifest.json")
if (
manifest.get("schema_version") != LAB_SCHEMA
or manifest.get("identity_sha256") != identity_sha256
or manifest.get("result_id") != result_id
):
raise M48QNativeRiskQualityLabError("existing M4.8Q LAB identity conflicts")
return M48QNativeRiskQualityLabResult(destination, result_id, manifest)
created_at_utc = datetime.now(UTC).isoformat(timespec="microseconds").replace("+00:00", "Z")
temporary = Path(tempfile.mkdtemp(prefix=".m48q-native-risk-lab-", dir=root))
try:
(temporary / "cases").mkdir(mode=0o700)
shutil.copyfile(profile_path, temporary / "profile.json")
shutil.copyfile(detector_profile_path, temporary / "detector-profile.json")
shutil.copyfile(worker_result_path, temporary / "worker-result.json")
shutil.copyfile(cases_path, temporary / "cases.jsonl")
catalog_cases: list[dict[str, object]] = []
for case in cases:
image = case["image"]
source_image = worker_root / image["path"]
destination_image = temporary / image["path"]
shutil.copyfile(source_image, destination_image)
catalog_cases.append(
{
"case_id": case["case_id"],
"sequence": case["sequence"],
"frame_id": case["frame_id"],
"evidence_time_ns": case["evidence_time_ns"],
"path": image["path"],
"media_type": "image/jpeg",
"width": 800,
"height": 600,
"byte_length": destination_image.stat().st_size,
"sha256": sha256_path(destination_image),
"geometric_resampling": False,
"selection_buckets": case["selection_buckets"],
"comparison": case["comparison"],
"proposals": case["proposals"],
}
)
catalog = {
"schema_version": CATALOG_SCHEMA,
"result_id": result_id,
"case_count": len(catalog_cases),
"source_raster": {"width": 800, "height": 600},
"overlay": {
"client_rendered": True,
"toggleable": True,
"box_coordinates": "source-pixel-xyxy",
"class_names": True,
"scores": True,
},
"ground_truth": False,
"cases": catalog_cases,
}
catalog_path = temporary / "catalog.json"
catalog_path.write_bytes(canonical_json(catalog) + b"\n")
graph_qualification = detector_profile["qualification"][
"full_ravnoves00_integrated_reference_graph"
]
decision = {
"review_ready": True,
"quality_evaluated": False,
"ground_truth": False,
"candidate_accepted": False,
"production_accepted": False,
"next_action": "operator-adjudication-in-existing-m48-review-instrument",
}
report = {
"schema_version": REPORT_SCHEMA,
"result_id": result_id,
"source": {
**profile["source"],
"graph_result_sha256": worker_result["source"]["graph_result_sha256"],
"graph_frames_sha256": worker_result["source"]["graph_frames_sha256"],
"independent_route_truth_available": False,
},
"configuration": {
"candidate": profile["candidate"],
"selection": profile["selection"],
},
"method": method,
"execution": {
"worker": worker_result["worker"],
"full_graph_frames": graph_qualification["frame_count"],
"requested_source_rate_hz": graph_qualification["requested_source_rate_hz"],
"effective_world_state_fps": graph_qualification["effective_world_state_fps"],
"world_state_completion_p95_ms": graph_qualification[
"world_state_completion_p95_ms"
],
"detector_total_p95_ms": graph_qualification["detector_total_p95_ms"],
"gpu_utilization_p95_percent": graph_qualification["gpu_utilization_p95_percent"],
"gpu_memory_used_maximum_mib": graph_qualification["gpu_memory_used_maximum_mib"],
"additional_inference_passes": 0,
},
"metrics": {
"selection": worker_result["selection"],
"runtime": {
"delivery_ratio": graph_qualification["delivery_ratio"],
"integrated_runtime_gate_passed": graph_qualification[
"integrated_runtime_gate_passed"
],
"operating_target_gate_passed": graph_qualification[
"operating_target_gate_passed"
],
},
"native_tensor_parity": detector_profile["qualification"][
"native_pytorch_tensorrt_parity"
],
"native_vs_legacy_704": detector_profile["qualification"][
"full_ravnoves00_native_vs_legacy_704"
],
},
"acceptance": {
"review_ready": True,
"integrated_runtime_gate_passed": True,
"independent_quality_evaluated": False,
"semantic_candidate_accepted": False,
},
"decision": decision,
"limitations": worker_result["limitations"],
"authority": false_authority(),
"visual_evidence": {
"kind": "native-raw-fisheye-risk-case-review",
"case_count": 24,
"source_raster": "800x600",
"geometric_resampling": False,
"boxes_baked_into_images": False,
"ground_truth": False,
},
}
report_path = temporary / "report.json"
report_path.write_bytes(canonical_json(report) + b"\n")
artifacts = _artifact_manifest(temporary)
manifest = {
"schema_version": LAB_SCHEMA,
"result_id": result_id,
"identity_sha256": identity_sha256,
"identity": identity,
"created_at_utc": created_at_utc,
"status": "complete-review-ready-quality-not-adjudicated",
"completed": True,
"bounded_question_accepted": True,
"ground_truth": False,
"method": method,
"metrics": report["metrics"],
"decision": decision,
"limitations": worker_result["limitations"],
"authority": false_authority(),
"artifacts": artifacts,
}
(temporary / "manifest.json").write_bytes(canonical_json(manifest) + b"\n")
temporary.replace(destination)
except BaseException:
shutil.rmtree(temporary, ignore_errors=True)
raise
return M48QNativeRiskQualityLabResult(destination, result_id, manifest)
def _validate_inputs(
*,
profile: dict[str, Any],
detector_profile: dict[str, Any],
worker_result: dict[str, Any],
cases: list[dict[str, Any]],
images_root: Path,
) -> None:
if (
profile.get("schema_version") != "missioncore.m48q-native-risk-case-mining-profile/v1"
or profile.get("source", {}).get("geometric_resampling") is not False
or profile.get("source", {}).get("raster_width") != 800
or profile.get("source", {}).get("raster_height") != 600
or profile.get("authority") != false_authority()
or detector_profile.get("schema_version")
!= "missioncore.rf-detr-native-risk-shadow-profile/v0"
or detector_profile.get("preprocessing", {}).get("resize") is not False
or detector_profile.get("preprocessing", {}).get("geometric_resampling") is not False
or detector_profile.get("status", {}).get("integrated_world_state_gate_passed") is not True
or worker_result.get("schema_version")
!= "missioncore.m48q-native-risk-case-mining-result/v1"
or worker_result.get("status") != "complete-review-ready-quality-not-adjudicated"
or worker_result.get("completed") is not True
or worker_result.get("report_identity_sha256") != EXPECTED_REPORT_IDENTITY_SHA256
or worker_result.get("artifacts", {}).get("cases", {}).get("sha256")
!= EXPECTED_CASES_SHA256
or worker_result.get("selection", {}).get("case_count") != 24
or worker_result.get("decision", {}).get("quality_evaluated") is not False
or worker_result.get("authority") != false_authority()
or len(cases) != 24
or len({case.get("case_id") for case in cases}) != 24
):
raise M48QNativeRiskQualityLabError("M4.8Q evidence contract changed")
for case in cases:
image = case.get("image")
proposals = case.get("proposals")
if (
case.get("schema_version") != CASE_SCHEMA
or not isinstance(case.get("case_id"), str)
or CASE_ID.fullmatch(case["case_id"]) is None
or case.get("case_id") != f"{case.get('sequence'):06d}"
or case.get("frame_id") != f"frame-{case.get('sequence'):06d}"
or case.get("ground_truth") is not False
or case.get("quality_evaluated") is not False
or case.get("authority") != false_authority()
or not isinstance(image, dict)
or image.get("path") != f"cases/frame-{case['case_id']}.jpg"
or image.get("width") != 800
or image.get("height") != 600
or image.get("geometric_resampling") is not False
or not isinstance(proposals, list)
or not proposals
):
raise M48QNativeRiskQualityLabError("M4.8Q review case contract changed")
image_path = images_root.parent / image["path"]
if (
image_path.is_symlink()
or not image_path.is_file()
or image_path.stat().st_size != image.get("byte_length")
or sha256_path(image_path) != image.get("sha256")
):
raise M48QNativeRiskQualityLabError("M4.8Q review image proof changed")
def _method(
profile: dict[str, Any],
detector_profile: dict[str, Any],
worker_result: dict[str, Any],
) -> dict[str, object]:
return {
"schema_version": "missioncore.laboratory-method/v1",
"completeness": "complete",
"execution_class": "hybrid",
"pipeline_id": "m48q-native-raw-fisheye-risk-case-review/v1",
"components": [
{
"kind": "source",
"name": "RAVNOVES00 raw KB4 video",
"version": "800x600 immutable recording",
"role": "unrectified review raster",
"identity_sha256": profile["source"]["video_sha256"],
},
{
"kind": "model",
"name": "RF-DETR-L native KB4 TensorRT",
"version": profile["candidate"]["model_id"],
"role": "fixed-class behavior-risk shadow proposals",
"identity_sha256": profile["candidate"]["engine_sha256"],
},
{
"kind": "runtime",
"name": "M4.7 native reference graph",
"version": "full RAVNOVES00 at recorded 12 FPS",
"role": "proposal and realtime evidence source",
"identity_sha256": worker_result["source"]["graph_result_sha256"],
},
{
"kind": "algorithm",
"name": "bounded diagnostic case miner",
"version": profile["profile_id"],
"role": "deterministic risk-family and edge-case sampling",
"identity_sha256": worker_result["identity"]["runner_sha256"],
},
{
"kind": "tool",
"name": "M4.8 existing image-case review instrument",
"version": "client-rendered source-pixel overlay/v1",
"role": "operator review without baked boxes",
"identity_sha256": EXPECTED_CASES_SHA256,
},
],
}
def _artifact_manifest(root: Path) -> list[dict[str, object]]:
artifacts: list[dict[str, object]] = []
for path in sorted(item for item in root.rglob("*") if item.is_file()):
relative = path.relative_to(root).as_posix()
if relative == "manifest.json":
continue
media_type = "application/json"
schema_version: str | None = None
role = "supporting-evidence"
if relative == "report.json":
role = "laboratory-report"
schema_version = REPORT_SCHEMA
elif relative == "catalog.json":
role = "visual-evidence-catalog"
schema_version = CATALOG_SCHEMA
elif relative == "profile.json":
role = "predeclared-native-risk-review-profile"
schema_version = "missioncore.m48q-native-risk-case-mining-profile/v1"
elif relative == "detector-profile.json":
role = "qualified-native-detector-profile"
schema_version = "missioncore.rf-detr-native-risk-shadow-profile/v0"
elif relative == "worker-result.json":
role = "upstream-worker-case-mining-result"
schema_version = "missioncore.m48q-native-risk-case-mining-result/v1"
elif relative == "cases.jsonl":
media_type = "application/x-ndjson"
role = "native-risk-review-case-ledger"
schema_version = CASE_SCHEMA
elif relative.endswith(".jpg"):
media_type = "image/jpeg"
role = "visual-evidence-native-raw-fisheye-frame"
artifacts.append(
{
"role": role,
"path": relative,
"byte_length": path.stat().st_size,
"sha256": sha256_path(path),
"media_type": media_type,
"schema_version": schema_version,
}
)
return artifacts
def _read_object(path: Path) -> dict[str, Any]:
try:
value: object = json.loads(path.read_text("utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise M48QNativeRiskQualityLabError(f"invalid JSON evidence: {path.name}") from exc
if not isinstance(value, dict):
raise M48QNativeRiskQualityLabError(f"JSON evidence must be an object: {path.name}")
return value
def _read_cases(path: Path) -> list[dict[str, Any]]:
cases: list[dict[str, Any]] = []
try:
with path.open("r", encoding="utf-8") as stream:
for line in stream:
value: object = json.loads(line)
if not isinstance(value, dict):
raise M48QNativeRiskQualityLabError("M4.8Q case ledger row is not an object")
cases.append(value)
except (OSError, json.JSONDecodeError) as exc:
raise M48QNativeRiskQualityLabError("M4.8Q case ledger cannot be read") from exc
return cases