feat(observatory): admit canonical recorded replay

This commit is contained in:
DCCONSTRUCTIONS
2026-08-30 19:21:27 +03:00
parent e6a9846167
commit 023151c186
32 changed files with 4069 additions and 342 deletions
+76 -1
View File
@@ -12,9 +12,10 @@ from pathlib import Path
from typing import Any
import pytest
from fastapi import APIRouter, HTTPException, Request, Response
from fastapi import APIRouter, FastAPI, HTTPException, Request, Response
from fastapi.responses import FileResponse
from fastapi.routing import APIRoute
from fastapi.testclient import TestClient
import k1link.sessions.media as recorded_media_module
import k1link.web.session_api as session_api_module
@@ -22,6 +23,7 @@ from k1link.compute import RecordedPerceptionOverlayArtifact, RecordedPerception
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 (
LabReplayCapability,
MaterializedRecording,
RecordedMediaInspector,
RecordedMediaManifest,
@@ -347,6 +349,79 @@ def test_session_router_exposes_immutable_lab_provenance(tmp_path: Path) -> None
assert_no_local_paths((item, detail), repository)
def test_session_router_rolls_capability_projections_out_only_in_v2(
tmp_path: Path,
) -> None:
repository = tmp_path / "repo"
sessions = repository / "sessions"
source = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
store = SessionStore(repository, data_dir=tmp_path / "data")
store.reconcile_archive(xgrids_k1_archive_source(sessions))
legacy = store.publish_lab_instance(
session_id="lab-e21-legacy",
source_session_id=source.name,
display_name="LAB E21 · legacy",
lab_id="LAB E21",
result_kind="e21-realtime-envelope",
result_id="e21-realtime-envelope-" + "1" * 64,
run_created_at_utc="2026-07-23T15:55:15.548Z",
provenance={"method": lab_method()},
)
capability = LabReplayCapability(
schema_version="missioncore.observation-lab-replay-capability/v1",
kind="canonical-recorded-rerun",
viewer_profile="recorded-session",
timeline="session_time",
activation="explicit",
commands_enabled=False,
)
canonical = store.publish_lab_instance(
session_id="lab-v1-vegetation-shadow-" + "8" * 64,
source_session_id=source.name,
display_name="RAV004 · recorded",
lab_id="LAB V1",
result_kind="recorded-perception-qualification",
result_id="lab-v1-vegetation-shadow-" + "8" * 64,
run_created_at_utc="2026-08-29T18:05:11.329061+00:00",
replay_capability=capability,
provenance={
"replay_capability": capability.as_dict(),
"method": lab_method(),
},
)
router = build_session_router(store)
list_route = endpoint(router, "/api/v1/observation-sessions", "GET")
default_items = list_route(limit=20, cursor=None, scope="all")["items"]
assert {item["id"] for item in default_items} == {source.name, legacy.session_id}
default_legacy = next(item for item in default_items if item["id"] == legacy.session_id)
assert "replay_capability" not in default_legacy["lab"]
v1_labs = list_route(
limit=20,
cursor=None,
scope="laboratory",
lab_contract="v1",
)["items"]
assert [item["id"] for item in v1_labs] == [legacy.session_id]
v2_labs = list_route(
limit=20,
cursor=None,
scope="laboratory",
lab_contract="v2",
)["items"]
by_id = {item["id"]: item for item in v2_labs}
assert set(by_id) == {legacy.session_id, canonical.session_id}
assert by_id[legacy.session_id]["lab"]["replay_capability"] is None
assert by_id[canonical.session_id]["lab"]["replay_capability"] == capability.as_dict()
application = FastAPI()
application.include_router(router)
assert TestClient(application).get(
"/api/v1/observation-sessions?lab_contract=v3"
).status_code == 422
def test_delete_session_removes_evidence_and_cache_but_refuses_an_open_recording(
tmp_path: Path,
) -> None: