"""Camera/ego-motion evidence fused conservatively with LAB E25 LiDAR state.

LAB E26 does not infer metric velocity from a monocular box. It tests whether
the bottom-center rays of one detector track remain compatible with a single
static world point while the calibrated rig moves. A failed static hypothesis
is relative-motion evidence. LiDAR remains the metric range/occupancy source;
conflicting sources produce ``unknown`` rather than a blended answer.
"""

from __future__ import annotations

import hashlib
import json
import math
import os
import secrets
import shutil
import time
from collections import Counter, defaultdict, deque
from collections.abc import Mapping
from dataclasses import dataclass, field
from datetime import UTC, datetime
from pathlib import Path
from typing import Any

import numpy as np

from k1link.artifacts import write_json_atomic
from k1link.device_plugins.xgrids_k1.analyze.calibrated_projection import (
    CalibratedProjectionError,
    Kb4ProjectionProfile,
    quaternion_xyzw_to_rotation_matrix,
    unproject_pixels_kb4,
)
from k1link.sessions import SessionIntegrityError

from .integrated_perception import IntegratedPerceptionResult
from .jobs import CameraComputeJob
from .world_motion import (
    _artifact,
    _box_arrays,
    _canonical,
    _percentiles,
    _read_jsonl,
    _read_object,
    _rewrite_npz_boxes,
    _sha256,
    _write_jsonl,
)

PROFILE_SCHEMA = "missioncore.e26-camera-ego-motion-profile/v1"
BENCHMARK_SCHEMA = "missioncore.e26-motion-benchmark/v1"
PIPELINE_ID = "kb4-multiview-static-hypothesis-lidar-fusion/v1"


@dataclass(frozen=True, slots=True)
class _RayObservation:
    session_seconds: float
    origin_map: np.ndarray
    direction_map: np.ndarray
    detector_score: float
    bbox_diagonal_px: float


@dataclass(slots=True)
class _CameraTrack:
    source_track_id: int
    group: str
    observations: deque[_RayObservation] = field(default_factory=deque)
    motion_state: str = "unknown"
    dynamic_evidence: int = 0
    static_evidence: int = 0
    last_observed_seconds: float = 0.0


@dataclass(frozen=True, slots=True)
class _StaticHypothesis:
    point_map: np.ndarray
    median_angular_residual_degrees: float
    p80_angular_residual_degrees: float
    positive_depth_fraction: float
    median_range_m: float
    ego_baseline_m: float
    normal_matrix_condition: float
    median_detector_score: float
    median_bbox_diagonal_px: float


@dataclass(frozen=True, slots=True)
class CameraEgoMotionBuild:
    result_root: Path
    profile_sha256: str
    benchmark_sha256: str
    report: dict[str, Any]


class CameraEgoMotionTracker:
    """Bounded per-detector-track static-world-hypothesis evaluator."""

    def __init__(
        self,
        profile: dict[str, Any],
        projection: Kb4ProjectionProfile,
    ) -> None:
        self.profile = profile
        self.projection = projection
        transform = np.asarray(projection.t_camera_from_lidar, dtype=np.float64)
        if transform.shape != (4, 4) or not np.isfinite(transform).all():
            raise SessionIntegrityError("LAB E26 camera transform is invalid")
        self.rotation_camera_from_lidar = transform[:3, :3]
        self.camera_origin_lidar = (
            -self.rotation_camera_from_lidar.T @ transform[:3, 3]
        )
        self.tracks: dict[int, _CameraTrack] = {}
        self.created_tracks = 0
        self.peak_tracks = 0
        self.current_hypotheses = 0
        self.published_states: Counter[str] = Counter()
        self.conflicts = 0
        self.invalid_camera_rays = 0

    def observe(
        self,
        *,
        source_track_id: int,
        group: str,
        session_seconds: float,
        bbox_xyxy: list[float],
        detector_score: float,
        position_map_xyz: np.ndarray,
        orientation_map_from_lidar_xyzw: np.ndarray,
    ) -> dict[str, Any]:
        self._prune(session_seconds)
        try:
            ray = self._ray_map(
                bbox_xyxy,
                position_map_xyz,
                orientation_map_from_lidar_xyzw,
            )
        except CalibratedProjectionError:
            self.invalid_camera_rays += 1
            self.published_states["unknown"] += 1
            return _camera_evidence(None, "unknown", 0.0)
        track = self.tracks.get(source_track_id)
        if track is None:
            track = _CameraTrack(
                source_track_id=source_track_id,
                group=group,
                last_observed_seconds=session_seconds,
            )
            self.tracks[source_track_id] = track
            self.created_tracks += 1
        config = self.profile["camera_evidence"]
        diagonal = math.hypot(
            float(bbox_xyxy[2]) - float(bbox_xyxy[0]),
            float(bbox_xyxy[3]) - float(bbox_xyxy[1]),
        )
        track.observations.append(
            _RayObservation(
                session_seconds=session_seconds,
                origin_map=ray[0],
                direction_map=ray[1],
                detector_score=detector_score,
                bbox_diagonal_px=diagonal,
            )
        )
        track.last_observed_seconds = session_seconds
        self._trim_observations(track, session_seconds)
        hypothesis = self._static_hypothesis(track)
        if hypothesis is None:
            self.published_states["unknown"] += 1
            self.peak_tracks = max(self.peak_tracks, len(self.tracks))
            return _camera_evidence(None, "unknown", 0.0)
        self.current_hypotheses += 1
        raw_state = self._raw_state(track.group, hypothesis)
        decay = int(config["evidence_decay_frames"])
        if raw_state == "dynamic":
            track.dynamic_evidence += 1
            track.static_evidence = max(0, track.static_evidence - decay)
        elif raw_state == "static":
            track.static_evidence += 1
            track.dynamic_evidence = max(0, track.dynamic_evidence - decay)
        else:
            track.dynamic_evidence = max(0, track.dynamic_evidence - decay)
            track.static_evidence = max(0, track.static_evidence - decay)
        if track.dynamic_evidence >= int(config["dynamic_confirmation_frames"]):
            track.motion_state = "dynamic"
        elif track.static_evidence >= int(config["static_confirmation_frames"]):
            track.motion_state = "static"
        elif raw_state == "unknown":
            track.motion_state = "unknown"
        confidence = _camera_confidence(
            track,
            hypothesis,
            config,
        )
        self.published_states[track.motion_state] += 1
        self.peak_tracks = max(self.peak_tracks, len(self.tracks))
        return _camera_evidence(hypothesis, track.motion_state, confidence)

    def snapshot(self) -> dict[str, Any]:
        return {
            "active_tracks": len(self.tracks),
            "created_tracks": self.created_tracks,
            "peak_tracks": self.peak_tracks,
            "current_hypotheses": self.current_hypotheses,
            "published_camera_motion_states": dict(self.published_states),
            "fusion_conflicts": self.conflicts,
            "invalid_camera_rays": self.invalid_camera_rays,
        }

    def note_conflict(self) -> None:
        self.conflicts += 1

    def _ray_map(
        self,
        bbox_xyxy: list[float],
        position_map_xyz: np.ndarray,
        orientation_map_from_lidar_xyzw: np.ndarray,
    ) -> tuple[np.ndarray, np.ndarray]:
        if (
            len(bbox_xyxy) != 4
            or not np.isfinite(np.asarray(bbox_xyxy, dtype=np.float64)).all()
            or not np.isfinite(position_map_xyz).all()
            or not np.isfinite(orientation_map_from_lidar_xyzw).all()
        ):
            raise SessionIntegrityError("LAB E26 camera observation is invalid")
        x1, y1, x2, y2 = (float(value) for value in bbox_xyxy)
        if not x1 < x2 or not y1 < y2:
            raise SessionIntegrityError("LAB E26 detector box is invalid")
        inset = float(self.profile["camera_evidence"]["footpoint_inset_fraction"])
        pixel = np.asarray(
            [[(x1 + x2) * 0.5, y2 - inset * (y2 - y1)]],
            dtype=np.float64,
        )
        direction_camera = unproject_pixels_kb4(
            pixel,
            profile=self.projection,
        )[0]
        direction_lidar = self.rotation_camera_from_lidar.T @ direction_camera
        rotation_map_from_lidar = quaternion_xyzw_to_rotation_matrix(
            (
                float(orientation_map_from_lidar_xyzw[0]),
                float(orientation_map_from_lidar_xyzw[1]),
                float(orientation_map_from_lidar_xyzw[2]),
                float(orientation_map_from_lidar_xyzw[3]),
            )
        )
        origin_map = (
            np.asarray(position_map_xyz, dtype=np.float64)
            + rotation_map_from_lidar @ self.camera_origin_lidar
        )
        direction_map = rotation_map_from_lidar @ direction_lidar
        direction_map /= np.linalg.norm(direction_map)
        return origin_map, direction_map

    def _static_hypothesis(
        self,
        track: _CameraTrack,
    ) -> _StaticHypothesis | None:
        config = self.profile["camera_evidence"]
        observations = list(track.observations)
        if (
            len(observations) < int(config["minimum_observations"])
            or observations[-1].session_seconds - observations[0].session_seconds
            < float(config["minimum_span_seconds"])
        ):
            return None
        baseline = max(
            float(
                np.linalg.norm(
                    observations[-1].origin_map - observation.origin_map
                )
            )
            for observation in observations
        )
        if baseline < float(config["minimum_ego_baseline_m"]):
            return None
        identity = np.eye(3, dtype=np.float64)
        normal = np.zeros((3, 3), dtype=np.float64)
        right = np.zeros(3, dtype=np.float64)
        for observation in observations:
            projector = identity - np.outer(
                observation.direction_map,
                observation.direction_map,
            )
            normal += projector
            right += projector @ observation.origin_map
        condition = float(np.linalg.cond(normal))
        if (
            not math.isfinite(condition)
            or condition > float(config["maximum_normal_matrix_condition"])
        ):
            return None
        try:
            point = np.linalg.solve(normal, right)
        except np.linalg.LinAlgError:
            return None
        ranges = np.asarray(
            [
                float(
                    observation.direction_map
                    @ (point - observation.origin_map)
                )
                for observation in observations
            ],
            dtype=np.float64,
        )
        perpendicular = np.asarray(
            [
                float(
                    np.linalg.norm(
                        np.cross(
                            observation.direction_map,
                            point - observation.origin_map,
                        )
                    )
                )
                for observation in observations
            ],
            dtype=np.float64,
        )
        angular = np.degrees(
            np.arctan2(
                perpendicular,
                np.maximum(ranges, 1e-6),
            )
        )
        return _StaticHypothesis(
            point_map=point,
            median_angular_residual_degrees=float(np.median(angular)),
            p80_angular_residual_degrees=float(np.percentile(angular, 80)),
            positive_depth_fraction=float(np.mean(ranges > 0.0)),
            median_range_m=float(np.median(ranges)),
            ego_baseline_m=baseline,
            normal_matrix_condition=condition,
            median_detector_score=float(
                np.median(
                    [observation.detector_score for observation in observations]
                )
            ),
            median_bbox_diagonal_px=float(
                np.median(
                    [observation.bbox_diagonal_px for observation in observations]
                )
            ),
        )

    def _raw_state(
        self,
        group: str,
        hypothesis: _StaticHypothesis,
    ) -> str:
        config = self.profile["camera_evidence"]
        large_enough = (
            hypothesis.median_bbox_diagonal_px
            >= float(config["minimum_bbox_diagonal_px"])
        )
        negative_depth_dynamic = (
            large_enough
            and hypothesis.positive_depth_fraction
            < float(config["negative_depth_dynamic_fraction"])
            and hypothesis.median_detector_score
            >= float(config["minimum_negative_depth_detector_score"])
        )
        residual_dynamic = (
            large_enough
            and hypothesis.positive_depth_fraction
            >= float(config["minimum_valid_positive_depth_fraction"])
            and hypothesis.median_range_m
            >= float(config["minimum_static_hypothesis_range_m"])
            and hypothesis.median_detector_score
            >= float(config["minimum_median_detector_score"])
            and hypothesis.median_angular_residual_degrees
            > _group_value(
                config["dynamic_median_angular_residual_degrees"],
                group,
            )
            and hypothesis.p80_angular_residual_degrees
            > _group_value(
                config["dynamic_p80_angular_residual_degrees"],
                group,
            )
        )
        if negative_depth_dynamic or residual_dynamic:
            return "dynamic"
        static = (
            hypothesis.positive_depth_fraction >= 0.9
            and float(config["minimum_static_hypothesis_range_m"])
            <= hypothesis.median_range_m
            <= float(config["maximum_static_hypothesis_range_m"])
            and hypothesis.median_angular_residual_degrees
            < _group_value(
                config["static_median_angular_residual_degrees"],
                group,
            )
            and hypothesis.p80_angular_residual_degrees
            < _group_value(
                config["static_p80_angular_residual_degrees"],
                group,
            )
        )
        return "static" if static else "unknown"

    def _trim_observations(
        self,
        track: _CameraTrack,
        session_seconds: float,
    ) -> None:
        config = self.profile["camera_evidence"]
        history_seconds = float(config["history_seconds"])
        while (
            track.observations
            and session_seconds - track.observations[0].session_seconds
            > history_seconds
        ):
            track.observations.popleft()
        maximum = int(config["maximum_observations_per_track"])
        while len(track.observations) > maximum:
            track.observations.popleft()

    def _prune(self, session_seconds: float) -> None:
        maximum_idle = float(
            self.profile["bounds"]["maximum_track_idle_seconds"]
        )
        expired = [
            track_id
            for track_id, track in self.tracks.items()
            if session_seconds - track.last_observed_seconds > maximum_idle
        ]
        for track_id in expired:
            del self.tracks[track_id]
        maximum_tracks = int(self.profile["bounds"]["maximum_tracks"])
        if len(self.tracks) <= maximum_tracks:
            return
        overflow = len(self.tracks) - maximum_tracks
        for track in sorted(
            self.tracks.values(),
            key=lambda value: (
                value.last_observed_seconds,
                value.source_track_id,
            ),
        )[:overflow]:
            del self.tracks[track.source_track_id]


def read_camera_ego_motion_profile(
    path: Path,
) -> tuple[dict[str, Any], str]:
    resolved = path.expanduser().resolve(strict=True)
    profile = _read_object(resolved)
    camera = profile.get("camera_evidence")
    bounds = profile.get("bounds")
    if (
        profile.get("schema_version") != PROFILE_SCHEMA
        or profile.get("mode") != "recorded-streaming-qualification"
        or profile.get("authority")
        != {"commands_enabled": False, "navigation_or_safety_accepted": False}
        or not isinstance(camera, dict)
        or not isinstance(bounds, dict)
        or not 0.1 <= float(camera.get("history_seconds", 0.0)) <= 5.0
        or not 3 <= int(camera.get("minimum_observations", 0)) <= 32
        or not 1 <= int(camera.get("maximum_observations_per_track", 0)) <= 64
        or not 1 <= int(bounds.get("maximum_tracks", 0)) <= 512
        or float(camera.get("negative_depth_dynamic_fraction", 1.0))
        >= float(camera.get("minimum_valid_positive_depth_fraction", 0.0))
    ):
        raise SessionIntegrityError("LAB E26 camera/ego-motion profile is invalid")
    return profile, _sha256(resolved)


def read_camera_ego_motion_benchmark(
    path: Path,
) -> tuple[dict[str, Any], str]:
    resolved = path.expanduser().resolve(strict=True)
    benchmark = _read_object(resolved)
    events = benchmark.get("events")
    if (
        benchmark.get("schema_version") != BENCHMARK_SCHEMA
        or benchmark.get("source_session_id")
        != "20260720T065719Z_viewer_live"
        or not isinstance(events, list)
        or not events
    ):
        raise SessionIntegrityError("LAB E26 motion benchmark is invalid")
    identifiers: set[str] = set()
    for event in events:
        if (
            not isinstance(event, dict)
            or not isinstance(event.get("id"), str)
            or event["id"] in identifiers
            or event.get("kind") not in {"target-motion", "static-control"}
            or event.get("expected_motion") not in {"static", "dynamic"}
            or event.get("class_group")
            not in {
                "person",
                "vehicle",
                "bicycle",
                "vulnerable_road_user",
            }
            or not isinstance(event.get("window_seconds"), list)
            or len(event["window_seconds"]) != 2
            or float(event["window_seconds"][0])
            >= float(event["window_seconds"][1])
        ):
            raise SessionIntegrityError("LAB E26 benchmark event is invalid")
        if event["kind"] == "target-motion":
            targets = event.get("target_source_track_ids")
            if (
                not isinstance(targets, list)
                or not targets
                or not all(
                    isinstance(value, int)
                    and not isinstance(value, bool)
                    and value > 0
                    for value in targets
                )
            ):
                raise SessionIntegrityError("LAB E26 target binding is invalid")
        identifiers.add(event["id"])
    return benchmark, _sha256(resolved)


def evaluate_camera_ego_motion_benchmark(
    source_rows: list[dict[str, Any]],
    fusion_rows: list[dict[str, Any]],
    benchmark: dict[str, Any],
) -> dict[str, Any]:
    outcomes: list[dict[str, Any]] = []
    for event in benchmark["events"]:
        start, end = (float(value) for value in event["window_seconds"])
        targets = {
            int(value) for value in event.get("target_source_track_ids", [])
        }
        source_keys: set[tuple[int, int]] = set()
        for row in source_rows:
            timestamp = float(row["session_seconds"])
            if not start <= timestamp <= end:
                continue
            for item in row["objects"]:
                source_id = int(item.get("source_track_id", item["track_id"]))
                if _event_class_matches(item, event) and (
                    event["kind"] == "static-control"
                    or source_id in targets
                ):
                    source_keys.add((int(row["frame_index"]), source_id))
        evidence: dict[tuple[int, int], tuple[float, dict[str, Any]]] = {}
        duplicates = 0
        for row in fusion_rows:
            timestamp = float(row["session_seconds"])
            if not start <= timestamp <= end:
                continue
            for item in row["objects"]:
                source_id = item.get("source_track_id")
                if (
                    isinstance(source_id, int)
                    and item.get("camera_evidence_current") is True
                    and _event_class_matches(item, event)
                    and (
                        event["kind"] == "static-control"
                        or source_id in targets
                    )
                ):
                    key = (int(row["frame_index"]), source_id)
                    if key in evidence:
                        duplicates += 1
                    evidence[key] = (timestamp, item)
        matched = sorted(evidence.values(), key=lambda value: value[0])
        source_observations = len(source_keys)
        coverage = len(matched) / max(1, source_observations)
        if event["kind"] == "static-control":
            counts = Counter(
                str(item["motion_state"]) for _, item in matched
            )
            classified = counts["static"] + counts["dynamic"]
            classified_fraction = classified / max(1, len(matched))
            false_dynamic_fraction = counts["dynamic"] / max(1, len(matched))
            passed = (
                source_observations
                >= int(event["minimum_source_observations"])
                and coverage >= float(event["minimum_coverage_fraction"])
                and classified_fraction
                >= float(event["minimum_classified_fraction"])
                and false_dynamic_fraction
                <= float(event["maximum_false_dynamic_fraction"])
            )
            outcomes.append(
                {
                    "id": event["id"],
                    "kind": event["kind"],
                    "expected_motion": event["expected_motion"],
                    "class_group": event["class_group"],
                    "window_seconds": [start, end],
                    "passed": passed,
                    "source_observations": source_observations,
                    "evidence_observations": len(matched),
                    "duplicate_evidence_observations": duplicates,
                    "coverage_fraction": coverage,
                    "classified_fraction": classified_fraction,
                    "false_dynamic_fraction": false_dynamic_fraction,
                    "state_counts": dict(counts),
                }
            )
            continue
        by_source: dict[int, list[float]] = defaultdict(list)
        for timestamp, item in matched:
            if item.get("motion_state") == event["expected_motion"]:
                by_source[int(item["source_track_id"])].append(timestamp)
        best_source: int | None = None
        best_hits = 0
        best_span = 0.0
        for source_id, timestamps in by_source.items():
            span = max(timestamps) - min(timestamps)
            if (len(timestamps), span) > (best_hits, best_span):
                best_source = source_id
                best_hits = len(timestamps)
                best_span = span
        passed = (
            coverage >= float(event["minimum_coverage_fraction"])
            and best_hits >= int(event["minimum_hits"])
            and best_span >= float(event["minimum_span_seconds"])
        )
        outcomes.append(
            {
                "id": event["id"],
                "kind": event["kind"],
                "expected_motion": event["expected_motion"],
                "class_group": event["class_group"],
                "target_source_track_ids": sorted(targets),
                "window_seconds": [start, end],
                "passed": passed,
                "source_observations": source_observations,
                "evidence_observations": len(matched),
                "duplicate_evidence_observations": duplicates,
                "coverage_fraction": coverage,
                "best_source_track_id": best_source,
                "best_hits": best_hits,
                "best_span_seconds": best_span,
            }
        )
    return {
        "schema_version": "missioncore.e26-motion-benchmark-result/v1",
        "passed": all(item["passed"] for item in outcomes),
        "passed_events": sum(item["passed"] for item in outcomes),
        "total_events": len(outcomes),
        "events": outcomes,
    }


def build_camera_ego_motion_result(
    *,
    lidar_source: IntegratedPerceptionResult,
    camera_source: IntegratedPerceptionResult,
    lab_job: CameraComputeJob,
    lab_pack: Path,
    results_root: Path,
    profile_path: Path,
    benchmark_path: Path,
) -> CameraEgoMotionBuild:
    """Build one immutable E26 result without rerunning model inference."""

    if not lidar_source.accepted or not camera_source.accepted:
        raise SessionIntegrityError("LAB E26 source result is not accepted")
    profile, profile_sha256 = read_camera_ego_motion_profile(profile_path)
    benchmark, benchmark_sha256 = read_camera_ego_motion_benchmark(
        benchmark_path
    )
    if camera_source.job.session_id != benchmark["source_session_id"]:
        raise SessionIntegrityError("LAB E26 benchmark source session differs")
    lidar_document = _read_object(lidar_source.result_root / "result.json")
    camera_document = _read_object(camera_source.result_root / "result.json")
    lidar_configuration = lidar_document["identity"].get("configuration")
    if (
        not isinstance(lidar_configuration, dict)
        or lidar_configuration.get("source_result_id")
        != camera_source.result_id
    ):
        raise SessionIntegrityError(
            "LAB E26 LiDAR result is not derived from the camera source"
        )
    camera_rows = _read_jsonl(camera_source.fusion_path)
    lidar_rows = _read_jsonl(lidar_source.fusion_path)
    lidar_world_rows = _read_jsonl(lidar_source.world_path)
    if not (
        len(camera_rows)
        == len(lidar_rows)
        == len(lidar_world_rows)
        == camera_source.frame_count
    ):
        raise SessionIntegrityError("LAB E26 source timelines are incomplete")

    with np.load(lab_pack / "lidar-pack.npz", allow_pickle=False) as arrays:
        pose_positions = np.asarray(
            arrays["pose_positions_map"],
            dtype=np.float64,
        ).copy()
        pose_quaternions = np.asarray(
            arrays["pose_quaternions_map_from_lidar"],
            dtype=np.float64,
        ).copy()
        projection = Kb4ProjectionProfile(
            source_id=lab_job.source_id,
            calibration_slot=str(profile["source"]["calibration_slot"]),
            width=800,
            height=600,
            intrinsic_fx_fy_cx_cy=(
                float(arrays["intrinsic_fx_fy_cx_cy"][0]),
                float(arrays["intrinsic_fx_fy_cx_cy"][1]),
                float(arrays["intrinsic_fx_fy_cx_cy"][2]),
                float(arrays["intrinsic_fx_fy_cx_cy"][3]),
            ),
            distortion_kb4=(
                float(arrays["distortion_kb4"][0]),
                float(arrays["distortion_kb4"][1]),
                float(arrays["distortion_kb4"][2]),
                float(arrays["distortion_kb4"][3]),
            ),
            t_camera_from_lidar=np.asarray(
                arrays["t_camera_from_lidar"],
                dtype=np.float64,
            ).copy(),
        )
    if (
        pose_positions.shape != (camera_source.frame_count, 3)
        or pose_quaternions.shape != (camera_source.frame_count, 4)
    ):
        raise SessionIntegrityError("LAB E26 pose timeline shape changed")

    tracker = CameraEgoMotionTracker(profile, projection)
    fusion_rows: list[dict[str, Any]] = []
    world_rows: list[dict[str, Any]] = []
    frame_ms: list[float] = []
    pose_unavailable_frames = 0
    camera_observations = 0
    for index, (camera_row, lidar_row, lidar_world_row) in enumerate(
        zip(camera_rows, lidar_rows, lidar_world_rows, strict=True)
    ):
        started = time.perf_counter()
        if (
            camera_row["frame_index"] != lidar_row["frame_index"]
            or camera_row["source_frame_index"]
            != lidar_row["source_frame_index"]
        ):
            raise SessionIntegrityError("LAB E26 source timelines diverged")
        position = pose_positions[index]
        quaternion = pose_quaternions[index]
        pose_available = bool(
            np.isfinite(position).all() and np.isfinite(quaternion).all()
        )
        if not pose_available:
            pose_unavailable_frames += 1
        lidar_by_source = _lidar_objects_by_source(lidar_row["objects"])
        normalized_objects: list[dict[str, Any]] = []
        for camera_object in camera_row["objects"]:
            source_track_id = int(
                camera_object.get(
                    "source_track_id",
                    camera_object["track_id"],
                )
            )
            evidence = _camera_evidence(None, "unknown", 0.0)
            if pose_available:
                evidence = tracker.observe(
                    source_track_id=source_track_id,
                    group=str(camera_object["association_group"]),
                    session_seconds=float(camera_row["session_seconds"]),
                    bbox_xyxy=[
                        float(value)
                        for value in camera_object["bbox_xyxy"]
                    ],
                    detector_score=float(camera_object["score"]),
                    position_map_xyz=position,
                    orientation_map_from_lidar_xyzw=quaternion,
                )
                camera_observations += 1
            normalized_objects.append(
                _fuse_camera_lidar_object(
                    camera_object,
                    lidar_by_source.get(source_track_id),
                    evidence,
                    profile,
                    tracker,
                )
            )
        normalized_fusion = json.loads(json.dumps(camera_row))
        normalized_fusion["objects"] = normalized_objects
        normalized_fusion["world_motion"] = {
            "schema_version": "missioncore.e26-camera-ego-motion-frame/v1",
            "coordinate_frame": "k1-map",
            "lookahead_frames": 0,
            "camera_measurement": "kb4-multiview-static-world-hypothesis",
            "metric_measurement": "e25-persistent-lidar-support",
            "unknown_is_occupied": True,
        }
        normalized_world = json.loads(json.dumps(lidar_world_row))
        normalized_world["objects"] = _update_world_objects(
            normalized_world["objects"],
            normalized_objects,
        )
        normalized_world["object_count"] = len(normalized_world["objects"])
        elapsed = (time.perf_counter() - started) * 1000.0
        delivery = normalized_world.setdefault("delivery", {})
        delivery["world_motion"] = "e26-camera-ego-lidar-conservative-fusion"
        delivery["world_motion_processing_ms"] = elapsed
        fusion_rows.append(normalized_fusion)
        world_rows.append(normalized_world)
        frame_ms.append(elapsed)

    benchmark_result = evaluate_camera_ego_motion_benchmark(
        camera_rows,
        fusion_rows,
        benchmark,
    )
    runtime = _percentiles(frame_ms)
    tracker_metrics = tracker.snapshot()
    checks = {
        "source_payloads_immutable": True,
        "diagnostic_authority_only": True,
        "single_pass_no_lookahead": True,
        "track_state_bound": tracker_metrics["peak_tracks"]
        <= int(profile["acceptance"]["maximum_tracks_observed"]),
        "processing_p95_ms": runtime["p95"]
        <= float(profile["acceptance"]["maximum_processing_p95_ms"]),
    }
    accepted = all(checks.values())
    camera_identity = camera_document["identity"]
    result_configuration = {
        "pipeline": PIPELINE_ID,
        "profile_sha256": profile_sha256,
        "profile": profile,
        "implementation_sha256": _sha256(Path(__file__).resolve()),
        "benchmark_sha256": benchmark_sha256,
        "benchmark": benchmark,
        "lidar_source_result_id": lidar_source.result_id,
        "lidar_source_result_sha256": _sha256(
            lidar_source.result_root / "result.json"
        ),
        "source_result_id": camera_source.result_id,
        "source_result_sha256": _sha256(
            camera_source.result_root / "result.json"
        ),
        "source_session_id": camera_source.job.session_id,
        "processing": "single-pass-bounded-state-no-lookahead",
    }
    identity = {
        "schema_version": "missioncore.e10-integrated-perception-identity/v1",
        "job_id": lab_job.job_id,
        "input_sha256": lab_job.input_sha256,
        "session_id": lab_job.session_id,
        "source_id": lab_job.source_id,
        "lidar_pack_id": lab_pack.name,
        "selection": json.loads(json.dumps(camera_identity["selection"])),
        "configuration": result_configuration,
        "models": camera_identity["models"],
    }
    identity_sha256 = hashlib.sha256(_canonical(identity)).hexdigest()
    result_id = f"e10-integrated-perception-{identity_sha256}"
    destination = results_root / result_id
    created_at = (
        datetime.now(UTC)
        .isoformat(timespec="milliseconds")
        .replace("+00:00", "Z")
    )
    report = {
        "schema_version": "missioncore.e10-integrated-perception-report/v1",
        "result_id": result_id,
        "created_at_utc": created_at,
        "state": "accepted" if accepted else "rejected",
        "ground_truth": False,
        "identity": identity,
        "acceptance": {
            "accepted": accepted,
            "navigation_or_safety_accepted": False,
            "checks": checks,
        },
        "metrics": {
            "runtime": {
                "camera_ego_motion_frame_processing_ms": runtime,
                "camera_observations": camera_observations,
                "pose_unavailable_frames": pose_unavailable_frames,
                **tracker_metrics,
            },
            "benchmark": benchmark_result,
        },
        "runtime": {
            "executor": "local-deterministic-postprocessor",
            "numpy": np.__version__,
            "streaming_equivalent": True,
            "lookahead_frames": 0,
        },
        "limitations": [
            "Recorded diagnostic qualification only; no navigation or command authority.",
            (
                "Operator timestamps and detector-track bindings are reviewed "
                "annotations, not independent ground truth."
            ),
            (
                "Camera-only dynamic is relative-motion evidence and does not "
                "create a metric velocity or free-space claim."
            ),
            (
                "LiDAR/camera disagreement is explicit unknown; unknown remains "
                "occupied for planner-facing consumers."
            ),
            (
                "Raw LiDAR, ground returns, camera media, calibration and model "
                "outputs are unchanged."
            ),
        ],
    }
    if destination.exists():
        existing = _read_object(destination / "result.json")
        if existing.get("identity") != identity:
            raise SessionIntegrityError("LAB E26 result id collides")
        return CameraEgoMotionBuild(
            destination,
            profile_sha256,
            benchmark_sha256,
            _read_object(destination / "run-report.json"),
        )

    results_root.mkdir(mode=0o700, parents=True, exist_ok=True)
    staging = results_root / f".{result_id}.{secrets.token_hex(12)}.tmp"
    staging.mkdir(mode=0o700)
    try:
        semantic_path = staging / "semantic-frames.jsonl"
        fusion_path = staging / "fusion-frames.jsonl"
        world_path = staging / "world-state.jsonl"
        arrays_path = staging / "transient-perception.npz"
        gpu_path = staging / "gpu-telemetry.jsonl"
        report_path = staging / "run-report.json"
        os.link(camera_source.semantic_path, semantic_path, follow_symlinks=False)
        _write_jsonl(fusion_path, fusion_rows)
        _write_jsonl(world_path, world_rows)
        box_offsets, centers, half_sizes, quaternions, box_colors = _box_arrays(
            fusion_rows
        )
        _rewrite_npz_boxes(
            lidar_source.arrays_path,
            arrays_path,
            {
                "box_offsets": box_offsets,
                "box_centers": centers,
                "box_half_sizes": half_sizes,
                "box_quaternions": quaternions,
                "box_colors": box_colors,
            },
        )
        os.link(
            camera_source.result_root / "gpu-telemetry.jsonl",
            gpu_path,
            follow_symlinks=False,
        )
        write_json_atomic(report_path, report)
        artifacts = [
            _artifact(
                "e10-semantic-frames",
                semantic_path,
                "missioncore.e10-semantic-frame/v1",
            ),
            _artifact(
                "e10-fusion-frames",
                fusion_path,
                "missioncore.e10-fusion-frame/v1",
            ),
            _artifact(
                "e10-world-state",
                world_path,
                "missioncore.live-perception-world-state/v1",
            ),
            _artifact("e10-transient-perception", arrays_path, None),
            _artifact("worker-gpu-telemetry", gpu_path, None),
            _artifact(
                "e10-run-report",
                report_path,
                "missioncore.e10-integrated-perception-report/v1",
            ),
        ]
        write_json_atomic(
            staging / "result.json",
            {
                "schema_version": "missioncore.e10-integrated-perception-result/v1",
                "result_id": result_id,
                "identity_sha256": identity_sha256,
                "identity": identity,
                "created_at_utc": created_at,
                "ground_truth": False,
                "publication_scope": (
                    "recorded-integrated-realtime-qualification-only"
                ),
                "acceptance_state": "accepted" if accepted else "rejected",
                "frames_processed": camera_source.frame_count,
                "artifacts": artifacts,
            },
        )
        os.replace(staging, destination)
    finally:
        if staging.exists():
            shutil.rmtree(staging)
    return CameraEgoMotionBuild(
        destination,
        profile_sha256,
        benchmark_sha256,
        report,
    )


def _lidar_objects_by_source(
    objects: list[dict[str, Any]],
) -> dict[int, dict[str, Any]]:
    result: dict[int, dict[str, Any]] = {}
    for item in objects:
        source_id = item.get("source_track_id")
        if not isinstance(source_id, int):
            continue
        previous = result.get(source_id)
        if previous is None or _lidar_rank(item) > _lidar_rank(previous):
            result[source_id] = item
    return result


def _lidar_rank(item: dict[str, Any]) -> tuple[int, int, float, int]:
    return (
        int(item.get("occupancy_evidence_current") is True),
        int(item.get("occupancy_cell_count", 0)),
        float(item.get("motion_confidence", 0.0)),
        -int(item.get("track_id", 0)),
    )


def _fuse_camera_lidar_object(
    camera_object: dict[str, Any],
    lidar_object: dict[str, Any] | None,
    camera_evidence: dict[str, Any],
    profile: dict[str, Any],
    tracker: CameraEgoMotionTracker,
) -> dict[str, Any]:
    item: dict[str, Any] = json.loads(
        json.dumps(lidar_object if lidar_object is not None else camera_object)
    )
    source_track_id = int(
        camera_object.get("source_track_id", camera_object["track_id"])
    )
    for key in (
        "association_group",
        "bbox_xyxy",
        "label",
        "score",
    ):
        item[key] = json.loads(json.dumps(camera_object[key]))
    item["source_track_id"] = source_track_id
    item.update(camera_evidence)
    lidar_state = (
        str(lidar_object.get("motion_state", "unknown"))
        if lidar_object is not None
        else "unknown"
    )
    lidar_confidence = (
        float(lidar_object.get("motion_confidence", 0.0))
        if lidar_object is not None
        else 0.0
    )
    camera_state = str(camera_evidence["camera_motion_state"])
    camera_confidence = float(camera_evidence["camera_motion_confidence"])
    item["lidar_motion_state"] = lidar_state
    item["lidar_motion_confidence"] = lidar_confidence
    if (
        camera_state in {"static", "dynamic"}
        and lidar_state in {"static", "dynamic"}
        and camera_state != lidar_state
    ):
        item["motion_state"] = str(profile["fusion"]["conflict_state"])
        item["motion_confidence"] = 0.0
        item["motion_status"] = "e26-explicit-camera-lidar-conflict"
        item["speed_mps"] = None
        item["velocity_map_mps"] = None
        tracker.note_conflict()
    elif (
        camera_state in {"static", "dynamic"}
        and camera_state == lidar_state
    ):
        item["motion_state"] = camera_state
        item["motion_confidence"] = min(
            camera_confidence,
            lidar_confidence,
        )
        item["motion_status"] = "e26-camera-lidar-agree"
    elif camera_state in {"static", "dynamic"}:
        item["motion_state"] = camera_state
        item["motion_confidence"] = (
            camera_confidence
            * float(profile["fusion"]["camera_only_confidence_scale"])
        )
        item["motion_status"] = "e26-camera-relative-only-no-metric-velocity"
        item["speed_mps"] = None
        item["velocity_map_mps"] = None
    elif lidar_state in {"static", "dynamic"}:
        item["motion_state"] = lidar_state
        item["motion_confidence"] = lidar_confidence
        item["motion_status"] = "e26-lidar-only"
    else:
        item["motion_state"] = "unknown"
        item["motion_confidence"] = 0.0
        item["motion_status"] = "e26-insufficient-independent-evidence"
        item["speed_mps"] = None
        item["velocity_map_mps"] = None
    item["unknown_is_occupied"] = True
    item["camera_only_metric_velocity_valid"] = False
    item["navigation_or_safety_accepted"] = False
    return item


def _update_world_objects(
    world_objects: list[dict[str, Any]],
    fusion_objects: list[dict[str, Any]],
) -> list[dict[str, Any]]:
    by_track = {
        int(item["track_id"]): item
        for item in fusion_objects
        if isinstance(item.get("track_id"), int)
        and item.get("cuboid_status")
    }
    result: list[dict[str, Any]] = []
    for source in world_objects:
        item = json.loads(json.dumps(source))
        fusion = by_track.get(int(item["track_id"]))
        if fusion is None:
            result.append(item)
            continue
        for key in (
            "motion_state",
            "motion_confidence",
            "motion_status",
            "speed_mps",
            "velocity_map_mps",
            "camera_motion_state",
            "camera_motion_confidence",
            "camera_evidence_current",
            "camera_static_residual_median_degrees",
            "camera_static_residual_p80_degrees",
            "camera_static_positive_depth_fraction",
            "camera_static_hypothesis_range_m",
            "camera_ego_baseline_m",
            "camera_lidar_evidence_relation",
            "lidar_motion_state",
            "lidar_motion_confidence",
            "unknown_is_occupied",
            "camera_only_metric_velocity_valid",
            "navigation_or_safety_accepted",
        ):
            if key in fusion:
                item[key] = fusion[key]
        item["velocity_status"] = fusion["motion_status"]
        result.append(item)
    return result


def _camera_evidence(
    hypothesis: _StaticHypothesis | None,
    motion_state: str,
    confidence: float,
) -> dict[str, Any]:
    if hypothesis is None:
        return {
            "camera_motion_state": "unknown",
            "camera_motion_confidence": 0.0,
            "camera_evidence_current": False,
            "camera_static_residual_median_degrees": None,
            "camera_static_residual_p80_degrees": None,
            "camera_static_positive_depth_fraction": None,
            "camera_static_hypothesis_range_m": None,
            "camera_ego_baseline_m": None,
            "camera_normal_matrix_condition": None,
        }
    return {
        "camera_motion_state": motion_state,
        "camera_motion_confidence": confidence,
        "camera_evidence_current": True,
        "camera_static_residual_median_degrees": (
            hypothesis.median_angular_residual_degrees
        ),
        "camera_static_residual_p80_degrees": (
            hypothesis.p80_angular_residual_degrees
        ),
        "camera_static_positive_depth_fraction": (
            hypothesis.positive_depth_fraction
        ),
        "camera_static_hypothesis_range_m": hypothesis.median_range_m,
        "camera_ego_baseline_m": hypothesis.ego_baseline_m,
        "camera_normal_matrix_condition": hypothesis.normal_matrix_condition,
        "camera_median_detector_score": hypothesis.median_detector_score,
        "camera_median_bbox_diagonal_px": (
            hypothesis.median_bbox_diagonal_px
        ),
    }


def _camera_confidence(
    track: _CameraTrack,
    hypothesis: _StaticHypothesis,
    config: Mapping[str, Any],
) -> float:
    if track.motion_state == "dynamic":
        confirmed = track.dynamic_evidence / max(
            1,
            int(config["dynamic_confirmation_frames"]),
        )
        residual = hypothesis.p80_angular_residual_degrees / max(
            1e-6,
            _group_value(
                config["dynamic_p80_angular_residual_degrees"],
                track.group,
            ),
        )
        return min(1.0, 0.5 * confirmed + 0.5 * min(1.0, residual))
    if track.motion_state == "static":
        confirmed = track.static_evidence / max(
            1,
            int(config["static_confirmation_frames"]),
        )
        residual_limit = _group_value(
            config["static_p80_angular_residual_degrees"],
            track.group,
        )
        quality = max(
            0.0,
            1.0 - hypothesis.p80_angular_residual_degrees / residual_limit,
        )
        return min(1.0, 0.6 * confirmed + 0.4 * quality)
    return 0.0


def _event_class_matches(
    item: dict[str, Any],
    event: dict[str, Any],
) -> bool:
    group = str(
        item.get(
            "association_group",
            item.get("class", item.get("label", "object")),
        )
    )
    if event["class_group"] == "vulnerable_road_user":
        return group in {"person", "bicycle", "motorcycle"}
    return group == str(event["class_group"])


def _group_value(values: Mapping[str, Any], group: str) -> float:
    return float(values.get(group, values["default"]))
