feat(perception): integrate calibrated operator pipeline

Add calibrated K1 projection, recorded and near-live perception qualification, unified Rerun operator layers, bounded replay admission, audited viewer controls, worker experiments, and lab evidence.
This commit is contained in:
DCCONSTRUCTIONS
2026-07-23 00:23:28 +03:00
parent ada2a55ee6
commit b53d6d5a45
221 changed files with 55923 additions and 1357 deletions
+925
View File
@@ -0,0 +1,925 @@
"""Validate and project accepted LAB E10 integrated perception results."""
from __future__ import annotations
import hashlib
import json
import os
import re
import shutil
import stat
import subprocess
import tempfile
import threading
from contextlib import suppress
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Protocol, TypeGuard
import numpy as np
import rerun as rr
from rerun.components import FillMode
from k1link.artifacts import write_json_atomic
from k1link.sessions import SessionIntegrityError
from .jobs import CameraComputeJob, validate_camera_compute_job
from .results import RecordedPerceptionOverlayError
RESULT_SCHEMA = "missioncore.e10-integrated-perception-result/v1"
IDENTITY_SCHEMA = "missioncore.e10-integrated-perception-identity/v1"
REPORT_SCHEMA = "missioncore.e10-integrated-perception-report/v1"
PACK_SCHEMA = "missioncore.e10-lidar-replay-pack/v1"
SEMANTIC_SCHEMA = "missioncore.e10-semantic-frame/v1"
FUSION_SCHEMA = "missioncore.e10-fusion-frame/v1"
WORLD_SCHEMA = "missioncore.live-perception-world-state/v1"
SESSION_TIMELINE = "session_time"
MAX_SCAN = 512
MAX_JSON_BYTES = 64 * 1024 * 1024
MAX_LINE_BYTES = 4 * 1024 * 1024
MAX_SOURCE_BYTES = 512 * 1024 * 1024
OVERLAY_RENDERER_VERSION = "4"
CUBOID_PRESENTATION_HOLD_NS = 500_000_000
_SAFE_RESULT_ID = re.compile(r"^e10-integrated-perception-[a-f0-9]{64}$")
_SAFE_PACK_ID = re.compile(r"^e10-lidar-pack-[a-f0-9]{64}$")
_SAFE_RECORDING_ID = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$")
_SHA256 = re.compile(r"^[a-f0-9]{64}$")
@dataclass(frozen=True, slots=True)
class IntegratedPerceptionResult:
result_id: str
result_root: Path
job: CameraComputeJob
pack_root: Path
created_at_utc: str
accepted: bool
publication_scope: str
source_start_frame_index: int
frame_count: int
timeline_start_seconds: float
timeline_end_seconds: float
semantic_path: Path
fusion_path: Path
world_path: Path
arrays_path: Path
report_path: Path
@dataclass(frozen=True, slots=True)
class _PresentedCuboid:
observed_ns: int
track_id: int
label: str
association_group: str
distance_m: float
support_points: int
center: np.ndarray
half_size: np.ndarray
quaternion: np.ndarray
color: np.ndarray
class _CuboidPresentationState:
"""Hold accepted cuboids briefly for operator presentation only.
The persisted world-state remains fail-closed and frame-exact. This bounded
latest-at projection only prevents one rejected LiDAR association from
visually clearing an otherwise stable tracked object for a single frame.
"""
def __init__(self, hold_ns: int = CUBOID_PRESENTATION_HOLD_NS) -> None:
if hold_ns <= 0:
raise ValueError("cuboid presentation hold must be positive")
self._hold_ns = hold_ns
self._latest: dict[int, _PresentedCuboid] = {}
def update(
self,
timestamp_ns: int,
objects: list[dict[str, Any]],
centers: np.ndarray,
half_sizes: np.ndarray,
quaternions: np.ndarray,
colors: np.ndarray,
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, list[str]] | None:
accepted = [
item
for item in objects
if str(item.get("cuboid_status", "")).startswith("accepted-")
]
if not (
len(accepted)
== len(centers)
== len(half_sizes)
== len(quaternions)
== len(colors)
):
raise RecordedPerceptionOverlayError(
"integrated perception cuboid presentation arrays are inconsistent"
)
for item, center, half_size, quaternion, color in zip(
accepted,
centers,
half_sizes,
quaternions,
colors,
strict=True,
):
track_id = item.get("track_id")
if not isinstance(track_id, int) or isinstance(track_id, bool):
raise RecordedPerceptionOverlayError(
"integrated perception cuboid track identity is invalid"
)
self._latest[track_id] = _PresentedCuboid(
observed_ns=timestamp_ns,
track_id=track_id,
label=str(item.get("label", "object")),
association_group=str(item.get("association_group", "object")),
distance_m=float(item["distance_smoothed_m"]),
support_points=int(item["clustered_points"]),
center=np.asarray(center).copy(),
half_size=np.asarray(half_size).copy(),
quaternion=np.asarray(quaternion).copy(),
color=np.asarray(color).copy(),
)
expired = [
track_id
for track_id, cuboid in self._latest.items()
if timestamp_ns - cuboid.observed_ns > self._hold_ns
]
for track_id in expired:
del self._latest[track_id]
if not self._latest:
return None
presented = sorted(self._latest.values(), key=lambda cuboid: cuboid.track_id)
presented_colors: list[np.ndarray] = []
labels: list[str] = []
for cuboid in presented:
age_ns = max(0, timestamp_ns - cuboid.observed_ns)
color = cuboid.color.copy()
if age_ns > 0 and color.shape == (4,):
fade = min(1.0, age_ns / self._hold_ns)
color[3] = max(24, round(float(color[3]) * (1.0 - 0.55 * fade)))
presented_colors.append(color)
age_label = "" if age_ns == 0 else f" · hold {age_ns / 1_000_000:.0f} ms"
labels.append(
f"{cuboid.association_group} #{cuboid.track_id} {cuboid.label} · "
f"{cuboid.distance_m:.1f} m · {cuboid.support_points} pts{age_label}"
)
return (
np.stack([cuboid.center for cuboid in presented]),
np.stack([cuboid.half_size for cuboid in presented]),
np.stack([cuboid.quaternion for cuboid in presented]),
np.stack(presented_colors),
labels,
)
class _OverlayProvider(Protocol):
def render(
self,
session_id: str,
*,
application_id: str,
recording_id: str,
) -> bytes | None: ...
def validate_integrated_perception_result(
job_root: Path,
result_root: Path,
lidar_packs_root: Path,
) -> IntegratedPerceptionResult:
job = validate_camera_compute_job(job_root)
root = result_root.expanduser().resolve(strict=True)
if not root.is_dir() or _SAFE_RESULT_ID.fullmatch(root.name) is None:
raise SessionIntegrityError("integrated perception root is invalid")
result = _read_object(root / "result.json", root)
identity = result.get("identity")
identity_sha256 = result.get("identity_sha256")
if (
result.get("schema_version") != RESULT_SCHEMA
or result.get("result_id") != root.name
or not isinstance(identity, dict)
or identity.get("schema_version") != IDENTITY_SCHEMA
or not isinstance(identity_sha256, str)
or _SHA256.fullmatch(identity_sha256) is None
or root.name != f"e10-integrated-perception-{identity_sha256}"
or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
or identity.get("job_id") != job.job_id
or identity.get("input_sha256") != job.input_sha256
or identity.get("session_id") != job.session_id
or identity.get("source_id") != job.source_id
or result.get("ground_truth") is not False
or result.get("publication_scope")
not in {
"recorded-integrated-realtime-qualification-only",
"recorded-integrated-semantic-loss-negative-control-only",
}
or result.get("acceptance_state") not in {"accepted", "rejected"}
):
raise SessionIntegrityError("integrated perception identity is inconsistent")
selection = identity.get("selection")
if not isinstance(selection, dict):
raise SessionIntegrityError("integrated perception selection is missing")
count = selection.get("frame_count")
start = selection.get("source_start_frame_index")
end = selection.get("source_end_frame_index")
timeline_start = selection.get("timeline_start_seconds")
timeline_end = selection.get("timeline_end_seconds")
if (
not isinstance(count, int)
or isinstance(count, bool)
or count < 2
or not isinstance(start, int)
or isinstance(start, bool)
or not isinstance(end, int)
or isinstance(end, bool)
or end - start + 1 != count
or start < 0
or end >= job.segment_count
or not _finite(timeline_start)
or not _finite(timeline_end)
or float(timeline_end) <= float(timeline_start)
or result.get("frames_processed") != count
):
raise SessionIntegrityError("integrated perception selection is invalid")
pack_id = identity.get("lidar_pack_id")
if not isinstance(pack_id, str) or _SAFE_PACK_ID.fullmatch(pack_id) is None:
raise SessionIntegrityError("integrated perception LiDAR pack binding is invalid")
pack_root = lidar_packs_root.expanduser().resolve(strict=True) / pack_id
_validate_pack(pack_root, job, identity, count, start, end)
artifacts = _validate_artifacts(root, result.get("artifacts"))
semantic_path = artifacts["e10-semantic-frames"]
fusion_path = artifacts["e10-fusion-frames"]
world_path = artifacts["e10-world-state"]
arrays_path = artifacts["e10-transient-perception"]
report_path = artifacts["e10-run-report"]
semantic_rows = _read_rows(semantic_path, root, SEMANTIC_SCHEMA)
fusion_rows = _read_rows(fusion_path, root, FUSION_SCHEMA)
world_rows = _read_rows(world_path, root, WORLD_SCHEMA)
if len(fusion_rows) != count or len(world_rows) != count or not semantic_rows:
raise SessionIntegrityError("integrated perception frame counts are incomplete")
for index, (fusion, world) in enumerate(zip(fusion_rows, world_rows, strict=True)):
source_index = start + index
if (
fusion.get("frame_index") != index
or fusion.get("source_frame_index") != source_index
or world.get("frame_index") != index
or world.get("source_frame_index") != source_index
or not isinstance(fusion.get("objects"), list)
or not isinstance(world.get("objects"), list)
or world.get("object_count") != len(world["objects"])
or not isinstance(world.get("delivery"), dict)
):
raise SessionIntegrityError("integrated perception frame identity changed")
semantic_indices: list[int] = []
for row in semantic_rows:
frame_index = row.get("frame_index")
if not isinstance(frame_index, int) or isinstance(frame_index, bool):
raise SessionIntegrityError("integrated perception semantic timeline is invalid")
semantic_indices.append(frame_index)
if (
semantic_indices != sorted(set(semantic_indices))
or semantic_indices[0] != 0
or semantic_indices[-1] >= count
):
raise SessionIntegrityError("integrated perception semantic timeline is invalid")
_validate_arrays(arrays_path, count, semantic_rows, fusion_rows)
report = _read_object(report_path, root)
acceptance = report.get("acceptance")
if (
report.get("schema_version") != REPORT_SCHEMA
or report.get("result_id") != root.name
or report.get("identity") != identity
or report.get("ground_truth") is not False
or not isinstance(acceptance, dict)
or acceptance.get("accepted") is not (result.get("acceptance_state") == "accepted")
or acceptance.get("navigation_or_safety_accepted") is not False
):
raise SessionIntegrityError("integrated perception report is inconsistent")
created = result.get("created_at_utc")
if not isinstance(created, str) or not 1 <= len(created) <= 64:
raise SessionIntegrityError("integrated perception creation time is invalid")
return IntegratedPerceptionResult(
result_id=root.name,
result_root=root,
job=job,
pack_root=pack_root,
created_at_utc=created,
accepted=result.get("acceptance_state") == "accepted",
publication_scope=str(result["publication_scope"]),
source_start_frame_index=start,
frame_count=count,
timeline_start_seconds=float(timeline_start),
timeline_end_seconds=float(timeline_end),
semantic_path=semantic_path,
fusion_path=fusion_path,
world_path=world_path,
arrays_path=arrays_path,
report_path=report_path,
)
class IntegratedPerceptionOverlayStore:
"""Prefer the newest accepted E10 result for a recorded session."""
def __init__(
self,
*,
jobs_root: Path,
results_root: Path,
lidar_packs_root: Path,
cache_root: Path,
ffmpeg_path: Path,
) -> None:
self.jobs_root = jobs_root.expanduser().absolute()
self.results_root = results_root.expanduser().absolute()
self.lidar_packs_root = lidar_packs_root.expanduser().absolute()
self.cache_root = cache_root.expanduser().absolute()
self.ffmpeg_path = ffmpeg_path.expanduser().absolute()
self._lock = threading.Lock()
def render(
self,
session_id: str,
*,
application_id: str,
recording_id: str,
) -> bytes | None:
if application_id != "nodedc_mission_core_recorded":
raise ValueError("integrated perception application id is invalid")
if (
_SAFE_RECORDING_ID.fullmatch(session_id) is None
or _SAFE_RECORDING_ID.fullmatch(recording_id) is None
):
raise ValueError("integrated perception recording id is invalid")
with self._lock:
result = self._latest(session_id)
if result is None:
return None
cache = _private_child(
_private_child(_private_directory(self.cache_root), session_id),
result.result_id,
)
output = cache / f"{recording_id}.rrd"
sidecar = output.with_suffix(".rrd.cache.json")
cached = _read_cache(output, sidecar, result, recording_id)
if cached is not None:
return cached
payload = _render(
result,
application_id=application_id,
recording_id=recording_id,
ffmpeg_path=self.ffmpeg_path,
temporary_root=cache,
)
temporary = output.with_name(f".{output.name}.{os.getpid()}.tmp")
try:
with temporary.open("xb") as stream:
stream.write(payload)
stream.flush()
os.fsync(stream.fileno())
os.chmod(temporary, 0o600)
os.replace(temporary, output)
write_json_atomic(
sidecar,
{
"schema_version": "missioncore.e10-overlay-cache/v1",
"renderer_version": OVERLAY_RENDERER_VERSION,
"result_id": result.result_id,
"recording_id": recording_id,
"byte_length": len(payload),
"sha256": hashlib.sha256(payload).hexdigest(),
},
)
finally:
temporary.unlink(missing_ok=True)
return payload
def _latest(self, session_id: str) -> IntegratedPerceptionResult | None:
try:
jobs = sorted(self.jobs_root.iterdir())
candidates = sorted(self.results_root.iterdir())
except FileNotFoundError:
return None
if len(jobs) > MAX_SCAN or len(candidates) > MAX_SCAN:
raise RecordedPerceptionOverlayError("integrated perception catalog is outside bounds")
matches = []
for job_root in jobs:
if job_root.is_symlink():
continue
try:
job = validate_camera_compute_job(job_root)
except (OSError, SessionIntegrityError):
continue
if job.session_id != session_id:
continue
for candidate in candidates:
if candidate.is_symlink() or _SAFE_RESULT_ID.fullmatch(candidate.name) is None:
continue
try:
value = validate_integrated_perception_result(
job_root,
candidate,
self.lidar_packs_root,
)
except (OSError, SessionIntegrityError):
continue
if (
value.accepted
and value.publication_scope == "recorded-integrated-realtime-qualification-only"
):
matches.append(value)
if not matches:
return None
return max(matches, key=lambda value: (value.created_at_utc, value.result_id))
def _render(
result: IntegratedPerceptionResult,
*,
application_id: str,
recording_id: str,
ffmpeg_path: Path,
temporary_root: Path,
) -> bytes:
fusion_rows = _read_rows(result.fusion_path, result.result_root, FUSION_SCHEMA)
with np.load(result.arrays_path, allow_pickle=False) as arrays:
frame_times = arrays["frame_times_ns"]
semantic_indices = arrays["semantic_frame_indices"]
semantic_masks = arrays["semantic_masks"]
semantic_by_frame = {
int(index): mask for index, mask in zip(semantic_indices, semantic_masks, strict=True)
}
support_offsets = arrays["support_offsets"]
support = arrays["support_points"]
support_colors = arrays["support_colors"]
box_offsets = arrays["box_offsets"]
centers = arrays["box_centers"]
half_sizes = arrays["box_half_sizes"]
quaternions = arrays["box_quaternions"]
box_colors = arrays["box_colors"]
cuboid_presentation = _CuboidPresentationState()
recording = rr.RecordingStream(application_id, recording_id=recording_id)
stream = rr.binary_stream(recording)
source_path: Path | None = None
proxy_path: Path | None = None
try:
recording.log("/world", rr.ViewCoordinates.RIGHT_HAND_Z_UP, static=True)
recording.log(
"/world/perception/contract",
rr.TextDocument(
"LAB E10 integrated source-paced replay. Generic AI and host-arrival "
"synchronization are diagnostic, not navigation or safety accepted."
),
static=True,
)
source_path = _camera_source_file(
result.job, result.source_start_frame_index + result.frame_count, temporary_root
)
source_end_frame_index = result.source_start_frame_index + result.frame_count - 1
proxy_path = _camera_proxy_file(
source_path,
result.source_start_frame_index,
source_end_frame_index,
ffmpeg_path,
temporary_root,
)
video = rr.AssetVideo(path=proxy_path)
video_timestamps = video.read_frame_timestamps_nanos()
if len(video_timestamps) != len(frame_times):
raise RecordedPerceptionOverlayError(
"integrated perception video frame count changed"
)
recording.log(
"/perception/camera/image",
video,
static=True,
)
for index, timestamp in enumerate(frame_times):
recording.set_time(SESSION_TIMELINE, duration=np.timedelta64(int(timestamp), "ns"))
recording.log(
"/perception/camera/image",
rr.VideoFrameReference(nanoseconds=int(video_timestamps[index])),
)
mask = semantic_by_frame.get(index)
if mask is not None:
recording.log(
"/perception/camera/segmentation",
rr.SegmentationImage(mask),
)
objects = fusion_rows[index]["objects"]
if objects:
recording.log(
"/perception/camera/detections",
rr.Boxes2D(
array=[item["bbox_xyxy"] for item in objects],
array_format=rr.Box2DFormat.XYXY,
labels=[
f"#{item['track_id']} {item['label']} · {float(item['score']):.0%}"
for item in objects
],
show_labels=True,
),
)
else:
recording.log("/perception/camera/detections", rr.Clear(recursive=False))
point_start, point_end = (
int(support_offsets[index]),
int(support_offsets[index + 1]),
)
if point_end > point_start:
recording.log(
"/world/perception/support",
rr.Points3D(
support[point_start:point_end],
colors=support_colors[point_start:point_end],
radii=rr.Radius.ui_points(3.0),
),
)
else:
recording.log("/world/perception/support", rr.Clear(recursive=False))
box_start, box_end = int(box_offsets[index]), int(box_offsets[index + 1])
presented_cuboids = cuboid_presentation.update(
int(timestamp),
objects,
centers[box_start:box_end],
half_sizes[box_start:box_end],
quaternions[box_start:box_end],
box_colors[box_start:box_end],
)
if presented_cuboids is not None:
(
presented_centers,
presented_half_sizes,
presented_quaternions,
presented_colors,
presented_labels,
) = presented_cuboids
recording.log(
"/world/perception/boxes3d",
rr.Boxes3D(
centers=presented_centers,
half_sizes=presented_half_sizes,
quaternions=presented_quaternions,
colors=presented_colors,
labels=presented_labels,
fill_mode=FillMode.Solid,
show_labels=True,
),
)
else:
recording.log("/world/perception/boxes3d", rr.Clear(recursive=False))
payload = stream.read(flush=True, flush_timeout_sec=300.0)
except RecordedPerceptionOverlayError:
raise
except Exception as exc:
raise RecordedPerceptionOverlayError(
"failed to serialize integrated perception"
) from exc
finally:
with suppress(Exception):
recording.disconnect()
if source_path is not None:
source_path.unlink(missing_ok=True)
if proxy_path is not None:
proxy_path.unlink(missing_ok=True)
if payload is None or not payload.startswith(b"RRF2"):
raise RecordedPerceptionOverlayError("integrated perception Rerun stream is invalid")
return payload
def _camera_source_file(job: CameraComputeJob, segment_count: int, root: Path) -> Path:
epoch = job.job_root / "input" / "camera" / job.source_id / f"epoch-{job.codec_epoch}"
paths = [epoch / "init.mp4"] + [
epoch / "segments" / f"{sequence}.m4s" for sequence in range(1, segment_count + 1)
]
total = sum(path.stat().st_size for path in paths)
if total <= 0 or total > MAX_SOURCE_BYTES:
raise RecordedPerceptionOverlayError(
"integrated perception camera source is outside bounds"
)
descriptor, name = tempfile.mkstemp(prefix=".e10-camera-", suffix=".mp4", dir=root)
path = Path(name)
try:
with os.fdopen(descriptor, "wb") as output:
for source in paths:
with source.open("rb") as stream:
shutil.copyfileobj(stream, output, length=1024 * 1024)
output.flush()
os.fsync(output.fileno())
return path
except BaseException:
path.unlink(missing_ok=True)
raise
def _camera_proxy_file(
source: Path,
start_frame_index: int,
end_frame_index: int,
ffmpeg_path: Path,
root: Path,
) -> Path:
descriptor, name = tempfile.mkstemp(prefix=".e10-camera-proxy-", suffix=".mp4", dir=root)
os.close(descriptor)
path = Path(name)
path.unlink(missing_ok=True)
frame_filter = (
f"select=between(n\\,{start_frame_index}\\,{end_frame_index}),setpts=N/(10*TB)"
)
try:
completed = subprocess.run(
[
str(ffmpeg_path),
"-hide_banner",
"-loglevel",
"error",
"-i",
str(source),
"-vf",
frame_filter,
"-an",
"-c:v",
"libx264",
"-preset",
"veryfast",
"-crf",
"28",
"-g",
"20",
"-keyint_min",
"20",
"-pix_fmt",
"yuv420p",
"-movflags",
"+faststart",
str(path),
],
check=False,
capture_output=True,
timeout=300,
)
if completed.returncode != 0 or not path.is_file() or path.stat().st_size <= 0:
raise RecordedPerceptionOverlayError(
f"integrated perception video proxy failed: {completed.stderr[-1000:]!r}"
)
os.chmod(path, 0o600)
return path
except BaseException:
path.unlink(missing_ok=True)
raise
def _validate_pack(
root: Path,
job: CameraComputeJob,
result_identity: dict[str, Any],
count: int,
start: int,
end: int,
) -> None:
if not root.is_dir() or _SAFE_PACK_ID.fullmatch(root.name) is None:
raise SessionIntegrityError("integrated perception LiDAR pack root is invalid")
manifest = _read_object(root / "manifest.json", root)
identity = manifest.get("identity")
identity_sha256 = manifest.get("identity_sha256")
arrays_path = root / "lidar-pack.npz"
artifact = manifest.get("artifact")
if (
manifest.get("schema_version") != PACK_SCHEMA
or manifest.get("pack_id") != root.name
or not isinstance(identity, dict)
or identity.get("schema_version") != PACK_SCHEMA
or identity.get("job_id") != job.job_id
or identity.get("input_sha256") != job.input_sha256
or identity.get("calibration_sha256")
!= result_identity["configuration"]["profile"]["source"]["calibration_sha256"]
or identity.get("frame_count") != count
or identity.get("source_start_frame_index") != start
or identity.get("source_end_frame_index") != end
or not isinstance(identity_sha256, str)
or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
or root.name != f"e10-lidar-pack-{identity_sha256}"
or not isinstance(artifact, dict)
or artifact.get("path") != arrays_path.name
or artifact.get("byte_length") != arrays_path.stat().st_size
or artifact.get("sha256") != _sha256(arrays_path)
):
raise SessionIntegrityError("integrated perception LiDAR pack is inconsistent")
def _validate_artifacts(root: Path, raw: object) -> dict[str, Path]:
expected = {
"e10-semantic-frames": ("semantic-frames.jsonl", SEMANTIC_SCHEMA),
"e10-fusion-frames": ("fusion-frames.jsonl", FUSION_SCHEMA),
"e10-world-state": ("world-state.jsonl", WORLD_SCHEMA),
"e10-transient-perception": ("transient-perception.npz", None),
"worker-gpu-telemetry": ("gpu-telemetry.jsonl", None),
"e10-run-report": ("run-report.json", REPORT_SCHEMA),
}
if not isinstance(raw, list) or len(raw) != len(expected):
raise SessionIntegrityError("integrated perception artifact set is incomplete")
result = {}
for value in raw:
kind = value.get("kind") if isinstance(value, dict) else None
if not isinstance(kind, str) or kind not in expected or kind in result:
raise SessionIntegrityError("integrated perception artifact descriptor is invalid")
name, schema = expected[kind]
path = root / name
metadata = _confined_file(path, root)
if (
value.get("path") != name
or value.get("schema_version") != schema
or value.get("byte_length") != metadata.st_size
or value.get("sha256") != _sha256(path)
):
raise SessionIntegrityError("integrated perception artifact identity changed")
result[kind] = path
return result
def _validate_arrays(
path: Path,
count: int,
semantic_rows: list[dict[str, Any]],
fusion_rows: list[dict[str, Any]],
) -> None:
with np.load(path, allow_pickle=False) as arrays:
required = {
"frame_times_ns",
"semantic_frame_indices",
"semantic_masks",
"support_offsets",
"support_points",
"support_colors",
"box_offsets",
"box_centers",
"box_half_sizes",
"box_quaternions",
"box_colors",
}
if set(arrays.files) != required:
raise SessionIntegrityError("integrated perception array set changed")
times = arrays["frame_times_ns"]
semantic_indices = arrays["semantic_frame_indices"]
masks = arrays["semantic_masks"]
support_offsets = arrays["support_offsets"]
support = arrays["support_points"]
support_colors = arrays["support_colors"]
box_offsets = arrays["box_offsets"]
centers = arrays["box_centers"]
half_sizes = arrays["box_half_sizes"]
quaternions = arrays["box_quaternions"]
colors = arrays["box_colors"]
expected_boxes = sum(
sum(
str(item.get("cuboid_status", "")).startswith("accepted-")
for item in row["objects"]
)
for row in fusion_rows
)
if (
times.dtype != np.int64
or times.shape != (count,)
or np.any(np.diff(times) <= 0)
or semantic_indices.dtype != np.int64
or semantic_indices.shape != (len(semantic_rows),)
or not np.array_equal(semantic_indices, [row["frame_index"] for row in semantic_rows])
or masks.dtype != np.uint8
or masks.shape != (len(semantic_rows), 600, 800)
or support_offsets.shape != (count + 1,)
or support.shape[1:] != (3,)
or support_colors.shape != support.shape
or box_offsets.shape != (count + 1,)
or centers.shape != (expected_boxes, 3)
or half_sizes.shape != centers.shape
or quaternions.shape != (expected_boxes, 4)
or colors.shape != (expected_boxes, 4)
or int(support_offsets[-1]) != support.shape[0]
or int(box_offsets[-1]) != expected_boxes
or np.any(np.diff(support_offsets) < 0)
or np.any(np.diff(box_offsets) < 0)
or not np.isfinite(support).all()
or not np.isfinite(centers).all()
or not np.isfinite(half_sizes).all()
or np.any(half_sizes <= 0)
):
raise SessionIntegrityError("integrated perception arrays are inconsistent")
def _read_rows(path: Path, root: Path, schema: str) -> list[dict[str, Any]]:
_confined_file(path, root)
rows = []
with path.open(encoding="utf-8") as stream:
for line in stream:
if len(line.encode()) > MAX_LINE_BYTES:
raise SessionIntegrityError("integrated perception row is oversized")
value = json.loads(line)
if not isinstance(value, dict) or value.get("schema_version") != schema:
raise SessionIntegrityError("integrated perception row schema changed")
rows.append(value)
return rows
def _read_cache(
output: Path,
sidecar: Path,
result: IntegratedPerceptionResult,
recording_id: str,
) -> bytes | None:
try:
value = _read_object(sidecar, sidecar.parent)
payload = output.read_bytes()
except (OSError, SessionIntegrityError):
return None
if (
value.get("schema_version") != "missioncore.e10-overlay-cache/v1"
or value.get("renderer_version") != OVERLAY_RENDERER_VERSION
or value.get("result_id") != result.result_id
or value.get("recording_id") != recording_id
or value.get("byte_length") != len(payload)
or value.get("sha256") != hashlib.sha256(payload).hexdigest()
or not payload.startswith(b"RRF2")
):
return None
return payload
def _read_object(path: Path, root: Path) -> dict[str, Any]:
metadata = _confined_file(path, root)
if not 0 < metadata.st_size <= MAX_JSON_BYTES:
raise SessionIntegrityError("integrated perception JSON is outside bounds")
try:
value = json.loads(path.read_text(encoding="utf-8-sig"))
except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:
raise SessionIntegrityError("integrated perception JSON is unavailable") from exc
if not isinstance(value, dict):
raise SessionIntegrityError("integrated perception JSON is not an object")
return value
def _confined_file(path: Path, root: Path) -> os.stat_result:
try:
resolved_root = root.resolve(strict=True)
resolved = path.resolve(strict=True)
metadata = path.lstat()
except OSError as exc:
raise SessionIntegrityError("integrated perception artifact is unavailable") from exc
if (
stat.S_ISLNK(metadata.st_mode)
or not stat.S_ISREG(metadata.st_mode)
or not resolved.is_relative_to(resolved_root)
):
raise SessionIntegrityError("integrated perception artifact is not confined")
return metadata
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while chunk := stream.read(1024 * 1024):
digest.update(chunk)
return digest.hexdigest()
def _canonical_json(value: object) -> bytes:
return json.dumps(
value,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
allow_nan=False,
).encode()
def _finite(value: object) -> TypeGuard[int | float]:
return (
isinstance(value, int | float)
and not isinstance(value, bool)
and bool(np.isfinite(value))
)
def _private_directory(path: Path) -> Path:
path.mkdir(mode=0o700, parents=True, exist_ok=True)
if path.is_symlink() or not path.is_dir():
raise RecordedPerceptionOverlayError("integrated perception cache root is invalid")
with suppress(OSError):
os.chmod(path, 0o700)
return path.resolve(strict=True)
def _private_child(root: Path, name: str) -> Path:
child = root / name
child.mkdir(mode=0o700, exist_ok=True)
if child.is_symlink() or not child.is_dir() or child.resolve(strict=True).parent != root:
raise RecordedPerceptionOverlayError("integrated perception cache child is invalid")
with suppress(OSError):
os.chmod(child, 0o700)
return child.resolve(strict=True)