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
+233 -17
View File
@@ -12,10 +12,11 @@ from pathlib import Path
from typing import Any
import pytest
from fastapi import APIRouter, HTTPException, Response
from fastapi import APIRouter, HTTPException, Request, Response
from fastapi.routing import APIRoute
import k1link.sessions.media as recorded_media_module
from k1link.compute import RecordedPerceptionVideo
from k1link.device_plugins.xgrids_k1 import xgrids_k1_archive_source
from k1link.device_plugins.xgrids_k1.mqtt.capture import FRAME_HEADER, RAW_MAGIC
from k1link.sessions import (
@@ -166,9 +167,24 @@ async def render_file_response(
*,
range_header: bytes | None,
) -> tuple[dict[str, Any], bytes]:
body_iterator = getattr(response, "body_iterator", None)
if body_iterator is not None:
chunks = [chunk async for chunk in body_iterator]
return {
"status": response.status_code,
"headers": response.raw_headers,
}, b"".join(
chunk.encode("utf-8") if isinstance(chunk, str) else chunk
for chunk in chunks
)
sent: list[dict[str, Any]] = []
request_delivered = False
async def receive() -> dict[str, Any]:
nonlocal request_delivered
if request_delivered:
return {"type": "http.disconnect"}
request_delivered = True
return {"type": "http.request", "body": b"", "more_body": False}
async def send(message: dict[str, Any]) -> None:
@@ -1069,6 +1085,11 @@ def test_recorded_blueprint_endpoint_is_small_strict_and_session_scoped(
palette="custom",
custom_color="#112233",
active_view="perception",
view_reset_generation=1,
unified_perception=True,
show_detections_2d=True,
show_segmentation=True,
show_cuboids_3d=True,
),
)
)
@@ -1083,6 +1104,11 @@ def test_recorded_blueprint_endpoint_is_small_strict_and_session_scoped(
assert observed_settings[0].show_points is False
assert observed_settings[0].show_trajectory is True
assert observed_kwargs[0]["active_view"] == "perception"
assert observed_kwargs[0]["view_reset_generation"] == 1
assert observed_kwargs[0]["unified_perception"] is True
assert observed_kwargs[0]["show_detections_2d"] is True
assert observed_kwargs[0]["show_segmentation"] is True
assert observed_kwargs[0]["show_cuboids_3d"] is True
with pytest.raises(ValueError):
RecordedBlueprintRequest.model_validate(
@@ -1234,6 +1260,12 @@ def test_session_router_exposes_opaque_recorded_media_manifest_and_ranges(
"epochs/{epoch_ordinal}/segments/{segment_sequence}.m4s",
"GET",
)
stream_route = endpoint(
router,
"/api/v1/observation-sessions/{session_id}/media/{artifact_id}/"
"epochs/{epoch_ordinal}/recording.mp4",
"GET",
)
replay = asyncio.run(replay_route(session_id=session.name, request=None))
source = replay["launch"]["media_sources"][0]
@@ -1271,39 +1303,66 @@ def test_session_router_exposes_opaque_recorded_media_manifest_and_ranges(
if_match=f'"sha256:{source["manifest_generation_sha256"]}"',
)
manifest = json.loads(manifest_response.body)
assert manifest["schema_version"] == "missioncore.observation-recorded-media/v2"
assert manifest["schema_version"] == "missioncore.observation-recorded-media/v3"
assert manifest["source_id"] == source["id"]
assert manifest["generation_sha256"] == source["manifest_generation_sha256"]
assert manifest["byte_length"] == source["byte_length"]
assert manifest["timeline_start_seconds"] == source["timeline_start_seconds"]
assert manifest["timeline_end_seconds"] == source["timeline_end_seconds"]
assert manifest_response.headers["etag"] == (f'"sha256:{manifest["generation_sha256"]}"')
init_sha256 = hashlib.sha256(init).hexdigest()
segment_sha256 = hashlib.sha256(segment).hexdigest()
generation = manifest["generation_sha256"]
assert manifest["epochs"] == [
{
"ordinal": 1,
"timeline_start_seconds": 0.0,
"timeline_end_seconds": 0.5,
"media_type": 'video/mp4; codecs="avc1.640028"',
"init_url": manifest["epochs"][0]["init_url"],
"init_byte_length": len(init),
"init_sha256": init_sha256,
"segment_count": 1,
"segment_url_prefix": manifest["epochs"][0]["segment_url_prefix"],
"segments": [
{
"sequence": 1,
"url": manifest["epochs"][0]["segments"][0]["url"],
"byte_length": len(segment),
"sha256": segment_sha256,
}
],
"byte_length": len(init) + len(segment),
"stream_url": (
f"{source['manifest_url'].removesuffix('/manifest')}/epochs/1/recording.mp4"
f"?generation={generation}"
),
}
]
assert "sensor.camera.private-left" not in json.dumps(manifest)
assert_no_local_paths(manifest, repository)
request = Request({"type": "http", "method": "GET", "headers": []})
with pytest.raises(HTTPException) as stale_stream_generation:
stream_route(
request=request,
session_id=session.name,
artifact_id=artifact_id,
epoch_ordinal=1,
generation="0" * 64,
range_header="bytes=0-5",
)
assert stale_stream_generation.value.status_code == 412
stream_response = stream_route(
request=request,
session_id=session.name,
artifact_id=artifact_id,
epoch_ordinal=1,
generation=generation,
range_header=f"bytes={len(init) - 2}-{len(init) + 3}",
)
stream_start, stream_body = asyncio.run(
render_file_response(stream_response, range_header=None)
)
stream_headers = {
key.decode("latin-1"): value.decode("latin-1")
for key, value in stream_start["headers"]
}
assert stream_start["status"] == 206
assert stream_body == init[-2:] + segment[:4]
assert stream_headers["content-range"] == (
f"bytes {len(init) - 2}-{len(init) + 3}/{len(init) + len(segment)}"
)
assert stream_headers["content-length"] == "6"
assert stream_headers["accept-ranges"] == "bytes"
assert stream_headers["etag"] == f'"generation:{generation}:epoch:1"'
with pytest.raises(HTTPException) as missing_init_generation:
init_route(
session_id=session.name,
@@ -1313,6 +1372,9 @@ def test_session_router_exposes_opaque_recorded_media_manifest_and_ranges(
)
assert missing_init_generation.value.status_code == 428
init_sha256 = hashlib.sha256(init).hexdigest()
segment_sha256 = hashlib.sha256(segment).hexdigest()
init_response = init_route(
session_id=session.name,
artifact_id=artifact_id,
@@ -1375,6 +1437,160 @@ def test_session_router_exposes_opaque_recorded_media_manifest_and_ranges(
assert confined.value.status_code == 409
def test_replay_exposes_generation_bound_perception_video_with_native_ranges(
tmp_path: Path,
) -> None:
repository = tmp_path / "repo"
sessions = repository / "sessions"
session = make_legacy_session(sessions, "20260720T065719Z_viewer_live")
store = SessionStore(repository, data_dir=tmp_path / "data")
store.reconcile_archive(xgrids_k1_archive_source(sessions))
recording_payload = b"recording"
def export_recording(source: Path, destination: Path) -> dict[str, object]:
destination.write_bytes(recording_payload)
return {
"source_sha256": hashlib.sha256(source.read_bytes()).hexdigest(),
"rrd_sha256": hashlib.sha256(recording_payload).hexdigest(),
"rrd_bytes": len(recording_payload),
"timeline": "session_time",
"timeline_start_ns": 0,
"timeline_end_ns": 5_000_000_000,
}
video_payload = b"sealed-panoptic-video"
video_path = tmp_path / "perception.mp4"
video_path.write_bytes(video_payload)
video_sha256 = hashlib.sha256(video_payload).hexdigest()
result_id = f"result-{'d' * 64}"
video = RecordedPerceptionVideo(
result_id=result_id,
session_id=session.name,
source_id="sensor.camera.right",
public_source_id="recorded.perception.right",
label="Сегментация · камера right",
path=video_path,
media_type='video/mp4; codecs="avc1.640028"',
byte_length=len(video_payload),
sha256=video_sha256,
timeline_start_seconds=0.5,
timeline_end_seconds=4.5,
)
class Provider:
def __init__(self) -> None:
self.calls: list[tuple[str, str | None]] = []
def video(
self,
session_id: str,
requested_result_id: str | None = None,
) -> RecordedPerceptionVideo | None:
self.calls.append((session_id, requested_result_id))
if session_id != video.session_id:
return None
if requested_result_id is not None and requested_result_id != video.result_id:
return None
return video
provider = Provider()
router = build_session_router(
store,
recording_materializer=SessionRecordingMaterializer(
store.data_dir,
exporter=export_recording,
),
perception_media_provider=provider,
allow_synchronous_recording_fallback=True,
)
replay_route = endpoint(
router,
"/api/v1/observation-sessions/{session_id}/replay",
"POST",
)
manifest_route = endpoint(
router,
"/api/v1/observation-sessions/{session_id}/perception-media/"
"{result_id}/manifest",
"GET",
)
stream_route = endpoint(
router,
"/api/v1/observation-sessions/{session_id}/perception-media/"
"{result_id}/recording.mp4",
"GET",
)
replay = asyncio.run(replay_route(session_id=session.name, request=None))
# Perception is loaded through the on-demand RRD overlay and no longer
# blocks replay launch by hashing a duplicate pre-rendered video.
assert replay["launch"]["media_sources"] == []
assert provider.calls == []
with pytest.raises(HTTPException) as missing_generation:
manifest_route(session_id=session.name, result_id=result_id)
assert missing_generation.value.status_code == 428
manifest_response = manifest_route(
session_id=session.name,
result_id=result_id,
if_match=f'"sha256:{video_sha256}"',
)
assert provider.calls == [
(session.name, result_id),
(session.name, result_id),
]
manifest = json.loads(manifest_response.body)
assert manifest == {
"schema_version": "missioncore.observation-recorded-media/v3",
"source_id": "recorded.perception.right",
"generation_sha256": video_sha256,
"byte_length": len(video_payload),
"timeline_start_seconds": 0.5,
"timeline_end_seconds": 4.5,
"synchronization": "host-arrival-best-effort",
"epochs": [
{
"ordinal": 1,
"timeline_start_seconds": 0.5,
"timeline_end_seconds": 4.5,
"media_type": 'video/mp4; codecs="avc1.640028"',
"byte_length": len(video_payload),
"stream_url": (
f"/api/v1/observation-sessions/{session.name}/perception-media/"
f"{result_id}/recording.mp4?generation={video_sha256}"
),
}
],
}
request = Request({"type": "http", "method": "GET", "headers": []})
with pytest.raises(HTTPException) as stale_generation:
stream_route(
request=request,
session_id=session.name,
result_id=result_id,
generation="0" * 64,
range_header=None,
)
assert stale_generation.value.status_code == 412
response = stream_route(
request=request,
session_id=session.name,
result_id=result_id,
generation=video_sha256,
range_header="bytes=7-14",
)
start, body = asyncio.run(render_file_response(response, range_header=b"bytes=7-14"))
headers = {
key.decode("latin-1"): value.decode("latin-1") for key, value in start["headers"]
}
assert start["status"] == 206
assert body == video_payload[7:15]
assert headers["content-range"] == f"bytes 7-14/{len(video_payload)}"
assert headers["accept-ranges"] == "bytes"
assert headers["etag"] == f'"sha256:{video_sha256}"'
def test_ready_launch_uses_background_prepared_camera_manifest_without_rescan(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,