Files
NODEDC_MISSION_CORE/tests/test_vegetation_shadow_lab.py
T

856 lines
31 KiB
Python

from __future__ import annotations
import hashlib
import io
import json
import shutil
import struct
import zipfile
from pathlib import Path
from types import SimpleNamespace
import numpy as np
from fastapi import FastAPI
from fastapi.testclient import TestClient
from PIL import Image
import k1link.laboratory.canonical_rerun_overlay as canonical_overlay_module
import k1link.laboratory.vegetation_policy_review as policy_review_module
import k1link.laboratory.vegetation_policy_video as policy_video_module
import k1link.laboratory.vegetation_shadow_lab as vegetation_lab_module
import k1link.web.vegetation_shadow_lab_api as vegetation_api_module
from k1link.laboratory import LaboratoryEvidenceRegistry
from k1link.laboratory.canonical_rerun_overlay import (
CanonicalLabOverlayArtifact,
CanonicalLabReplayArtifact,
_artifact_is_regular,
_encoded_semantic_png,
_localized_semantic_label,
_optimize_overlay,
_semantic_palette,
_video_reference_timestamps,
canonical_lab_replay,
)
from k1link.laboratory.evidence_report import verify_laboratory_evidence_result
from k1link.laboratory.vegetation_policy_review import seal_vegetation_policy_review
from k1link.laboratory.vegetation_shadow_lab import seal_vegetation_shadow_lab
from k1link.web.vegetation_shadow_lab_api import (
_canonical_route_playback_chunk_descriptor,
_mask_component_boxes,
_route_tgs_anchor_payload,
build_vegetation_shadow_lab_router,
)
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
def test_semantic_component_boxes_keep_distinct_objects_separate() -> None:
mask = np.zeros((20, 30), dtype=np.uint8)
mask[2:10, 3:8] = 4
mask[4:12, 18:24] = 4
mask[15:17, 3:5] = 4
assert _mask_component_boxes(mask, 4, minimum_pixels=20) == [
(18, 4, 24, 12, 48),
(3, 2, 8, 10, 40),
]
_, labels = canonical_overlay_module.semantic_component_boxes(mask, 0)
assert labels == [
"автомобиль · 50%",
"автомобиль · 50%",
]
def test_canonical_overlay_localizes_current_taxonomies() -> None:
assert _localized_semantic_label("high_grass") == "высокая трава"
assert _localized_semantic_label("tree_trunk") == "ствол дерева"
assert _localized_semantic_label("future_class") == "future_class"
def test_canonical_video_references_hold_only_missing_source_samples() -> None:
session_times = np.arange(10, dtype=np.int64) * 100_000_000 + 39_000_000_000
video_times = np.array(
[0, 100, 200, 300, 400, 500, 600, 700, 900],
dtype=np.int64,
) * 1_000_000
references = _video_reference_timestamps(video_times, session_times)
assert references.tolist() == [
0,
100_000_000,
200_000_000,
300_000_000,
400_000_000,
500_000_000,
600_000_000,
700_000_000,
700_000_000,
900_000_000,
]
def test_canonical_overlay_memory_cache_rejects_same_size_tampering(
tmp_path: Path,
) -> None:
path = tmp_path / "overlay.rrd"
path.write_bytes(b"RRF2-original")
artifact = CanonicalLabOverlayArtifact(
path=path,
byte_length=path.stat().st_size,
sha256=_sha256(path),
)
assert _artifact_is_regular(artifact)
path.write_bytes(b"RRF2-tampered")
assert path.stat().st_size == artifact.byte_length
assert not _artifact_is_regular(artifact)
def test_canonical_overlay_keeps_semantics_as_palette_encoded_png() -> None:
mask = np.zeros((600, 800), dtype=np.uint8)
mask[120:420, 200:600] = 7
palette = _semantic_palette(
[
{"class_id": 0, "color_rgb": [0, 0, 0]},
{"class_id": 7, "color_rgb": [255, 47, 128]},
]
)
encoded = _encoded_semantic_png(mask, palette)
assert len(encoded) < mask.nbytes // 20
with Image.open(io.BytesIO(encoded)) as image:
assert image.mode == "P"
assert image.getpixel((0, 0)) == 0
assert image.getpixel((300, 300)) == 7
assert image.getpalette()[7 * 3 : 7 * 3 + 3] == [255, 47, 128]
def test_canonical_overlay_compacts_chunks_before_cache_publication(
tmp_path: Path,
monkeypatch,
) -> None:
source = tmp_path / "source.rrd"
source.write_bytes(b"RRF2-source")
def optimize(command: list[str], **options: object) -> SimpleNamespace:
assert command[:4] == [
canonical_overlay_module.sys.executable,
"-m",
"rerun",
"rrd",
]
assert command[4:13] == [
"optimize",
"--profile",
"object-store",
"--max-size",
"4MiB",
"--max-rows",
"512",
"--num-pass",
"20",
]
assert command[13] == str(source)
assert command[14] == "-o"
Path(command[15]).write_bytes(b"RRF2-optimized")
assert options == {"check": False, "capture_output": True, "timeout": 120}
return SimpleNamespace(returncode=0, stderr=b"")
monkeypatch.setattr(canonical_overlay_module.subprocess, "run", optimize)
_optimize_overlay(source)
assert source.read_bytes() == b"RRF2-optimized"
def test_canonical_replay_merges_base_and_overlay_once(
tmp_path: Path,
monkeypatch,
) -> None:
base = tmp_path / "base.rrd"
base.write_bytes(b"RRF2-base")
overlay_path = tmp_path / "overlay.rrd"
overlay_path.write_bytes(b"RRF2-overlay")
overlay = CanonicalLabOverlayArtifact(
path=overlay_path,
byte_length=overlay_path.stat().st_size,
sha256=_sha256(overlay_path),
)
calls = 0
def optimize(command: list[str], **options: object) -> SimpleNamespace:
nonlocal calls
calls += 1
assert command[13:15] == [str(base), str(overlay_path)]
assert command[15] == "-o"
Path(command[16]).write_bytes(b"RRF2-merged")
assert options == {"check": False, "capture_output": True, "timeout": 180}
return SimpleNamespace(returncode=0, stderr=b"")
monkeypatch.setattr(canonical_overlay_module.subprocess, "run", optimize)
monkeypatch.setattr(
canonical_overlay_module,
"canonical_recording_id",
lambda _path: "recording-001",
)
result_id = f"lab-v1-vegetation-shadow-{'e' * 64}"
first = canonical_lab_replay(
base,
base_generation_sha256=_sha256(base),
overlay=overlay,
result_id=result_id,
recording_id="recording-001",
cache_root=tmp_path / "cache",
)
second = canonical_lab_replay(
base,
base_generation_sha256=_sha256(base),
overlay=overlay,
result_id=result_id,
recording_id="recording-001",
cache_root=tmp_path / "cache",
)
assert first == second
assert first.path.read_bytes() == b"RRF2-merged"
assert calls == 1
def test_canonical_overlay_get_is_generation_bound_and_range_streamable(
tmp_path: Path,
monkeypatch,
) -> None:
result_id = f"lab-v1-vegetation-shadow-{'a' * 64}"
result_root = tmp_path / result_id
result_root.mkdir()
base = tmp_path / "base.rrd"
base.write_bytes(b"RRF2-base")
overlay = tmp_path / "overlay.rrd"
overlay.write_bytes(b"RRF2-overlay")
replay = tmp_path / "replay.rrd"
replay.write_bytes(b"RRF2-replay")
generation = "b" * 64
recording_id = "recording-001"
artifact = CanonicalLabOverlayArtifact(
path=overlay,
byte_length=overlay.stat().st_size,
sha256=_sha256(overlay),
)
replay_artifact = CanonicalLabReplayArtifact(
path=replay,
byte_length=replay.stat().st_size,
sha256=_sha256(replay),
)
monkeypatch.setattr(
vegetation_api_module,
"_resolve_candidate",
lambda *_args, **_kwargs: result_root,
)
monkeypatch.setattr(
vegetation_api_module,
"_read_verified",
lambda *_args, **_kwargs: {},
)
monkeypatch.setattr(
vegetation_api_module,
"_full_route_context",
lambda *_args, **_kwargs: ({"session_id": "session-001"}, ()),
)
monkeypatch.setattr(
vegetation_api_module,
"canonical_recording_id",
lambda _path: recording_id,
)
monkeypatch.setattr(
vegetation_api_module,
"canonical_lab_overlay",
lambda *_args, **_kwargs: artifact,
)
monkeypatch.setattr(
vegetation_api_module,
"canonical_lab_replay",
lambda *_args, **_kwargs: replay_artifact,
)
ffmpeg = tmp_path / "ffmpeg"
ffmpeg.write_bytes(b"fixture")
ffmpeg.chmod(0o700)
app = FastAPI()
app.include_router(
build_vegetation_shadow_lab_router(
root_provider=lambda: tmp_path,
canonical_recording_provider=lambda _session_id: (base, generation),
jobs_root=tmp_path,
rerun_overlay_cache_root=tmp_path / "cache",
ffmpeg_path=ffmpeg,
)
)
client = TestClient(app)
endpoint = f"/api/v1/laboratory/vegetation-shadow/{result_id}/canonical-overlay.rrd"
descriptor = client.head(
endpoint,
params={
"application_id": "nodedc_mission_core_recorded",
"recording_id": recording_id,
"generation": generation,
},
)
assert descriptor.status_code == 200
assert descriptor.content == b""
assert descriptor.headers["content-length"] == str(artifact.byte_length)
assert descriptor.headers["etag"] == f'"{artifact.sha256}"'
assert descriptor.headers["x-rerun-format"] == "RRF2"
assert descriptor.headers["cache-control"] == "private, no-store"
response = client.get(
endpoint,
params={
"application_id": "nodedc_mission_core_recorded",
"recording_id": recording_id,
"generation": generation,
"overlay_generation": artifact.sha256,
},
headers={"Range": "bytes=0-3"},
)
assert response.status_code == 206
assert response.content == b"RRF2"
assert response.headers["content-range"] == f"bytes 0-3/{artifact.byte_length}"
assert response.headers["etag"] == f'"{artifact.sha256}"'
assert response.headers["cache-control"].endswith("immutable")
stale = client.head(
endpoint,
params={
"application_id": "nodedc_mission_core_recorded",
"recording_id": recording_id,
"generation": "c" * 64,
},
)
assert stale.status_code == 412
stale_overlay = client.get(
endpoint,
params={
"application_id": "nodedc_mission_core_recorded",
"recording_id": recording_id,
"generation": generation,
"overlay_generation": "d" * 64,
},
)
assert stale_overlay.status_code == 412
replay_endpoint = (
f"/api/v1/laboratory/vegetation-shadow/{result_id}/canonical-replay.rrd"
)
replay_descriptor = client.head(
replay_endpoint,
params={"base_generation": generation},
)
assert replay_descriptor.status_code == 200
assert replay_descriptor.headers["content-length"] == str(replay_artifact.byte_length)
assert replay_descriptor.headers["etag"] == f'"{replay_artifact.sha256}"'
assert replay_descriptor.headers["x-rerun-format"] == "RRF2"
replay_response = client.get(
replay_endpoint,
params={"generation": replay_artifact.sha256},
headers={"Range": "bytes=0-3"},
)
assert replay_response.status_code == 206
assert replay_response.content == b"RRF2"
assert replay_response.headers["etag"] == f'"{replay_artifact.sha256}"'
stale_replay = client.get(
replay_endpoint,
params={"generation": "f" * 64},
)
assert stale_replay.status_code == 412
def test_route_playback_chunk_descriptor_seals_only_requested_binary_window() -> None:
points = np.arange(18, dtype="<f4").reshape(6, 3)
descriptor = _canonical_route_playback_chunk_descriptor(
"/api/v1/laboratory/vegetation-shadow",
f"lab-v1-vegetation-shadow-{'a' * 64}",
memoryview(points).cast("B"),
(0, 1, 1, 3, 6),
0,
)
assert descriptor is not None
assert descriptor["start"] == 0
assert descriptor["count"] == 4
assert descriptor["point_count"] == 6
assert descriptor["bytes"] == points.nbytes
assert descriptor["shape"] == [6, 3]
assert len(str(descriptor["sha256"])) == 64
def test_route_tgs_anchor_payload_preserves_metric_evidence(tmp_path: Path) -> None:
path = tmp_path / "tgs-evidence.npz"
point_counts = np.arange(1, 11, dtype=np.int64)
offsets = np.concatenate(([0], np.cumsum(point_counts)))
points = np.arange(int(offsets[-1]) * 3, dtype=np.float32).reshape(-1, 3)
centers = np.arange(2244 * 2, dtype=np.float32).reshape(2244, 2) * 0.45
states = np.tile(np.arange(2244, dtype=np.uint16) % 4, (10, 1)).astype(np.uint8)
z_bounds = np.zeros((10, 2244, 2), dtype=np.float32)
z_bounds[..., 0] = np.nan
z_bounds[..., 1] = 1.25
np.savez(
path,
source_frame_indices=np.array(
[20, 408, 789, 1189, 1609, 1992, 2380, 3190, 4810, 6381],
dtype=np.int64,
),
current_increment_point_offsets=offsets,
current_increment_points_xyz_m=points,
costmap_cell_centers_xy_m=centers,
causal_rolling_1s_costmap_states=states,
causal_rolling_1s_costmap_z_bounds_m=z_bounds,
)
payload = _route_tgs_anchor_payload(path, 409)
assert payload["schema_version"] == "missioncore.lab-v1-route-tgs-anchor/v1"
assert payload["source_sequence"] == 409
assert payload["slot"] == 1
assert len(payload["current_points_xyz_m"]) == 2
assert len(payload["costmap"]["centers_xy_m"]) == 2244
assert set(payload["costmap"]["state_codes"]) == {0, 1, 2, 3}
assert payload["costmap"]["z_bounds_m"][0] == [None, 1.25]
def test_coarse_policy_masks_mark_every_outside_fov_pixel_undefined(
tmp_path: Path,
monkeypatch,
) -> None:
monkeypatch.setattr(policy_video_module, "FRAME_COUNT", 1)
monkeypatch.setattr(
policy_video_module,
"fine_to_policy_lut",
lambda _taxonomy, _provider_map: np.full(256, 4, dtype=np.uint8),
)
source = tmp_path / "fine.zip"
fine_buffer = io.BytesIO()
Image.new("L", (800, 600), color=1).save(fine_buffer, format="PNG")
with zipfile.ZipFile(source, "w") as archive:
archive.writestr("masks/frame-000001.png", fine_buffer.getvalue())
valid_fov = np.zeros((600, 800), dtype=np.uint8)
valid_fov[:, :400] = 255
valid_fov_path = tmp_path / "valid-fov.png"
Image.fromarray(valid_fov, mode="L").save(valid_fov_path)
destination = tmp_path / "coarse.zip"
counts = policy_video_module.build_policy_mask_archive(
source_archive=source,
destination_archive=destination,
fine_taxonomy={},
provider_label_map={},
valid_fov_mask=valid_fov_path,
)
with (
zipfile.ZipFile(destination) as archive,
Image.open(io.BytesIO(archive.read("masks/frame-000001.png"))) as image,
):
coarse = np.asarray(image.convert("L"))
assert np.all(coarse[:, :400] == 4)
assert np.all(coarse[:, 400:] == 9)
assert counts[4] == 600 * 400
assert counts[9] == 600 * 400
def _sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def _worker_result(root: Path, *, candidate: str, mode: str, vegetation_iou: float) -> None:
root.mkdir(parents=True)
visual_cases = []
for index in range(12):
case_id = f"case-{index:02d}"
case_root = root / "cases" / case_id
case_root.mkdir(parents=True)
keys = ["source", "prediction_semantic", "policy_urban", "policy_rural", "policy_offroad"]
if mode == "goose":
keys.extend(("truth_semantic", "vegetation_material_error"))
files = {}
for key in keys:
path = case_root / f"{key}.png"
path.write_bytes(b"\x89PNG\r\n\x1a\n" + f"{candidate}:{mode}:{case_id}:{key}".encode())
files[key] = {
"relative_path": path.relative_to(root).as_posix(),
"sha256": _sha256(path),
}
visual_cases.append(
{
"case_id": case_id,
"source_width": 800 if mode == "ravnoves" else 512,
"source_height": 600 if mode == "ravnoves" else 512,
"center_crop_xyxy": [100, 0, 700, 600] if mode == "ravnoves" else [0, 0, 512, 512],
"outside_crop_state": "undefined" if mode == "ravnoves" else "not-applicable",
"focus": {
"class_name": "high_grass",
"label_id": 51,
"truth_pixels": 16384,
"truth_fraction": 0.0625,
"stratum_rank": index + 1,
} if mode == "goose" else None,
"files": files,
}
)
payload = {
"schema_version": "missioncore.lab-v1-goose-vegetation-run/v1",
"result_id": f"lab-v1-{mode}-{candidate}-fixture",
"mode": mode,
"candidate": {
"candidate_key": candidate,
"loaded_model_name": "ddrnet_39" if candidate == "ddrnet" else "pp_lite_t_seg",
"checkpoint_sha256": ("a" if candidate == "ddrnet" else "b") * 64,
},
"metrics": {
"mean_iou_percent": 44.0 + vegetation_iou,
"published_mean_iou_percent": 46.53 if candidate == "ddrnet" else 45.09,
"vegetation_mean_iou": vegetation_iou,
},
"timing": {
"latency_ms_p95": 20.0 if candidate == "ddrnet" else 15.0,
"throughput_fps_from_mean_inference": 55.0,
},
"resource": {
"peak_reserved_vram_bytes": 2_000_000_000,
"gpu_name": "fixture RTX 4090",
},
"visual_cases": visual_cases,
"authority": {
"navigation_accepted": False,
"safety_accepted": False,
"actuation_accepted": False,
"camera_semantics_can_clear_rigid_geometry": False,
},
}
(root / "result.json").write_text(json.dumps(payload), encoding="utf-8")
def _video_worker_result(root: Path) -> None:
root.mkdir(parents=True)
archive = root / "semantic-masks.zip"
mask = b"\x89PNG\r\n\x1a\n"
with zipfile.ZipFile(archive, "x", compression=zipfile.ZIP_STORED) as frozen:
for sequence in range(4489):
frozen.writestr(f"masks/frame-{sequence + 1:06d}.png", mask)
taxonomy = {
"schema_version": "missioncore.lab-v1-vegetation-taxonomy/v1",
"classes": [
{
"class_id": class_id,
"label": "undefined" if class_id == 0 else f"class-{class_id}",
"color_rgb": [class_id, class_id, class_id],
"disposition": "undefined" if class_id == 0 else "prediction",
}
for class_id in range(64)
],
}
payload = {
"schema_version": "missioncore.lab-v1-goose-vegetation-run/v1",
"result_id": f"lab-v1-ravnoves-video-ddrnet-{'e' * 64}",
"mode": "ravnoves-video",
"candidate": {"candidate_key": "ddrnet"},
"source": {
"input_count": 4489,
"ground_truth_available": False,
},
"video_semantics": {
"base_m4_result_id": f"m4-threat-replay-{'f' * 64}",
"mask_archive": {
"path": "semantic-masks.zip",
"sha256": _sha256(archive),
"byte_length": archive.stat().st_size,
"frame_count": 4489,
"width": 800,
"height": 600,
"encoding": "uint8-class-id-png",
"media_type": "application/zip",
"sequence_binding": "sequence-0-to-masks/frame-000001.png",
},
"taxonomy": taxonomy,
"aggregate_prediction_pixels": [4489 * 800 * 600, *([0] * 63)],
"center_crop_xyxy": [100, 0, 700, 600],
"outside_crop_state": "undefined",
},
"authority": {
"navigation_accepted": False,
"safety_accepted": False,
"actuation_accepted": False,
"camera_semantics_can_clear_rigid_geometry": False,
},
}
(root / "result.json").write_text(json.dumps(payload), encoding="utf-8")
def test_vegetation_shadow_lab_seals_autonomous_visual_evidence(
tmp_path: Path,
monkeypatch,
) -> None:
roots = {}
for candidate, vegetation_iou in (("ddrnet", 0.64), ("ppliteseg", 0.61)):
for mode in ("goose", "ravnoves"):
root = tmp_path / "worker" / f"{candidate}-{mode}"
_worker_result(root, candidate=candidate, mode=mode, vegetation_iou=vegetation_iou)
roots[(candidate, mode)] = root
video_root = tmp_path / "worker" / "ddrnet-ravnoves-video"
_video_worker_result(video_root)
m47_root = tmp_path / f"m47-reference-graph-lab-{'a' * 64}"
m47_root.mkdir()
monkeypatch.setattr(
vegetation_lab_module,
"read_m47_reference_graph_lab",
lambda _root: SimpleNamespace(
result_id=m47_root.name,
report={
"source": {"source_id": "RAVNOVES00"},
"visual_evidence": {
"linked_result_id": f"m4-threat-replay-{'f' * 64}",
"timeline_frames": 4489,
},
},
),
)
result_root = seal_vegetation_shadow_lab(
ddrnet_goose_root=roots[("ddrnet", "goose")],
ppliteseg_goose_root=roots[("ppliteseg", "goose")],
ddrnet_ravnoves_root=roots[("ddrnet", "ravnoves")],
ppliteseg_ravnoves_root=roots[("ppliteseg", "ravnoves")],
output_root=tmp_path / "results",
ddrnet_ravnoves_video_root=video_root,
m47_reference_graph_lab_root=m47_root,
)
manifest = json.loads((result_root / "result.json").read_text("utf-8"))
assert manifest["decision"]["selected_candidate"] == "ddrnet"
assert manifest["ground_truth"] is False
assert manifest["authority"]["commands_enabled"] is False
assert manifest["authority"]["navigation_or_safety_accepted"] is False
assert len(manifest["catalogs"]["ravnoves"]) == 0
assert len(manifest["catalogs"]["goose"]) == 12
assert len(manifest["artifacts"]) == 78
assert manifest["route_video"]["frame_count"] == 4489
assert manifest["route_video"]["outside_crop_state"] == "undefined"
assert manifest["catalogs"]["goose"][0]["focus"]["class_name"] == "high_grass"
assert "ddrnet_error" in manifest["catalogs"]["goose"][0]["assets"]
assert "ppliteseg_error" in manifest["catalogs"]["goose"][0]["assets"]
assert "all_classes" not in manifest["metrics"]["candidates"]["ddrnet"]["validation_metrics"]
assert (result_root / "result.json").stat().st_size <= 64 * 1024
registry = LaboratoryEvidenceRegistry.from_directory(REPOSITORY_ROOT / "config/laboratories")
definition = next(
row for row in registry.definitions if row.work_id == "lab-v1-vegetation-shadow"
)
proof = verify_laboratory_evidence_result(definition, result_root)
assert proof["result_id"] == result_root.name
assert proof["artifact_count"] == 78
app = FastAPI()
app.include_router(build_vegetation_shadow_lab_router(root_provider=lambda: result_root.parent))
client = TestClient(app)
response = client.get(f"/api/v1/laboratory/vegetation-shadow/{result_root.name}")
assert response.status_code == 200
assert response.json()["access"] == "read-only"
asset_path = manifest["catalogs"]["goose"][0]["assets"]["ddrnet_error"]["path"]
asset = client.get(
f"/api/v1/laboratory/vegetation-shadow/{result_root.name}/assets/{asset_path}"
)
assert asset.status_code == 200
assert asset.headers["cache-control"].endswith("immutable")
mask = client.get(f"/api/v1/laboratory/vegetation-shadow/{result_root.name}/masks/0")
assert mask.status_code == 200
assert mask.content == b"\x89PNG\r\n\x1a\n"
assert mask.headers["cache-control"].endswith("immutable")
full_archive_payloads = (b"\x89PNG\r\n\x1a\ncity", b"\x89PNG\r\n\x1a\nvegetation")
full_timeline_payload = struct.pack("<2Q", 1_000_000_000, 1_100_000_000)
full_identity = dict(manifest["identity"])
full_route = {
"frame_count": 2,
"timeline": {
"path": "video/frame-source-times-ns.bin",
"sha256": hashlib.sha256(full_timeline_payload).hexdigest(),
"byte_length": len(full_timeline_payload),
"encoding": "uint64-le-nanoseconds",
"frame_count": 2,
},
"layers": {
layer: {"mask_archive": {"path": "video/full-route-masks.zip"}}
for layer in ("city", "vegetation")
},
}
full_identity["route_full_review"] = full_route
full_identity_sha = hashlib.sha256(
json.dumps(
full_identity,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
).encode("utf-8")
).hexdigest()
full_result_id = f"lab-v1-vegetation-shadow-{full_identity_sha}"
full_root = result_root.parent / full_result_id
shutil.copytree(result_root, full_root)
full_archive = full_root / "video" / "full-route-masks.zip"
full_archive.parent.mkdir(exist_ok=True)
with zipfile.ZipFile(full_archive, "x", compression=zipfile.ZIP_STORED) as frozen:
for sequence, payload in enumerate(full_archive_payloads, start=1):
frozen.writestr(f"masks/frame-{sequence:06d}.png", payload)
full_timeline = full_root / "video" / "frame-source-times-ns.bin"
full_timeline.write_bytes(full_timeline_payload)
full_manifest = dict(manifest)
full_manifest["result_id"] = full_result_id
full_manifest["identity"] = full_identity
full_manifest["identity_sha256"] = full_identity_sha
full_manifest["route_full_review"] = full_route
full_manifest["artifacts"] = [
*manifest["artifacts"],
{
"role": "full-route-mask-fixture",
"path": "video/full-route-masks.zip",
"byte_length": full_archive.stat().st_size,
"sha256": _sha256(full_archive),
"media_type": "application/zip",
},
{
"role": "full-route-frame-timeline",
"path": "video/frame-source-times-ns.bin",
"byte_length": full_timeline.stat().st_size,
"sha256": _sha256(full_timeline),
"media_type": "application/octet-stream",
},
]
(full_root / "result.json").write_text(
json.dumps(full_manifest, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
+ "\n",
encoding="utf-8",
)
for layer, sequence, expected in (
("city", 0, full_archive_payloads[0]),
("vegetation", 1, full_archive_payloads[1]),
):
response = client.get(
f"/api/v1/laboratory/vegetation-shadow/{full_result_id}"
f"/route-masks/{layer}/{sequence}"
)
assert response.status_code == 200
assert response.content == expected
assert response.headers["cache-control"].endswith("immutable")
assert client.get(
f"/api/v1/laboratory/vegetation-shadow/{full_result_id}/route-masks/city/2"
).status_code == 404
timeline = client.get(
f"/api/v1/laboratory/vegetation-shadow/{full_result_id}/route-timeline"
)
assert timeline.status_code == 200
assert timeline.content == full_timeline_payload
assert timeline.headers["cache-control"].endswith("immutable")
(result_root / asset_path).write_bytes(b"tampered")
assert (
client.get(f"/api/v1/laboratory/vegetation-shadow/{result_root.name}").status_code
== 503
)
def test_policy_review_reuses_sealed_video_and_links_yolox_tgs(
tmp_path: Path,
monkeypatch,
) -> None:
roots = {}
for candidate, vegetation_iou in (("ddrnet", 0.64), ("ppliteseg", 0.61)):
for mode in ("goose", "ravnoves"):
root = tmp_path / "worker" / f"{candidate}-{mode}"
_worker_result(root, candidate=candidate, mode=mode, vegetation_iou=vegetation_iou)
roots[(candidate, mode)] = root
video_root = tmp_path / "worker" / "ddrnet-ravnoves-video"
_video_worker_result(video_root)
m47_root = tmp_path / f"m47-reference-graph-lab-{'a' * 64}"
m47_root.mkdir()
base_m4_result_id = f"m4-threat-replay-{'f' * 64}"
monkeypatch.setattr(
vegetation_lab_module,
"read_m47_reference_graph_lab",
lambda _root: SimpleNamespace(
result_id=m47_root.name,
report={
"source": {"source_id": "RAVNOVES00"},
"visual_evidence": {
"linked_result_id": base_m4_result_id,
"timeline_frames": 4489,
},
},
),
)
base_root = seal_vegetation_shadow_lab(
ddrnet_goose_root=roots[("ddrnet", "goose")],
ppliteseg_goose_root=roots[("ppliteseg", "goose")],
ddrnet_ravnoves_root=roots[("ddrnet", "ravnoves")],
ppliteseg_ravnoves_root=roots[("ppliteseg", "ravnoves")],
output_root=tmp_path / "results",
ddrnet_ravnoves_video_root=video_root,
m47_reference_graph_lab_root=m47_root,
)
tgs_result_id = f"m49-tgs-full-shadow-{'9' * 64}"
monkeypatch.setattr(
policy_review_module,
"read_m49_tgs_full_shadow",
lambda _root: SimpleNamespace(
result_id=tgs_result_id,
report={
"source": {
"source_id": "RAVNOVES00",
"linked_visual_result_id": base_m4_result_id,
},
"timeline": {"frame_count": 4489},
},
),
)
def fake_policy_archive(**kwargs) -> list[int]:
shutil.copyfile(kwargs["source_archive"], kwargs["destination_archive"])
assert kwargs["valid_fov_mask"].is_file()
return [4489 * 800 * 600, *([0] * 9)]
monkeypatch.setattr(policy_review_module, "build_policy_mask_archive", fake_policy_archive)
valid_fov_mask = tmp_path / "valid-fov-mask.png"
Image.new("L", (800, 600), color=255).save(valid_fov_mask)
result_root = seal_vegetation_policy_review(
base_lab_root=base_root,
mission_policy_path=REPOSITORY_ROOT
/ "config/perception/lab-v1-vegetation-mission-policy-v1.json",
provider_label_map_path=REPOSITORY_ROOT
/ "config/perception/lab-v1-vegetation-provider-label-map-v1.json",
m49_tgs_full_shadow_root=tmp_path / "sealed-tgs",
valid_fov_mask_path=valid_fov_mask,
output_root=tmp_path / "results",
created_at_utc="2026-08-28T08:00:00+00:00",
)
manifest = json.loads((result_root / "result.json").read_text("utf-8"))
route = manifest["route_video"]
assert route["view_kind"] == "coarse-material-policy-review"
assert route["linked_tgs_result_id"] == tgs_result_id
assert route["fusion"]["pixel_raster_fusion"] is False
assert route["fusion"]["camera_semantic_temporal_filter"] == "none"
assert route["taxonomy"]["schema_version"] == (
"missioncore.lab-v1-terrain-policy-taxonomy/v1"
)
assert len(route["taxonomy"]["classes"]) == 10
assert route["valid_fov"]["outside_valid_fov_class_id"] == 9
assert len(manifest["artifacts"]) == 80
assert manifest["authority"]["commands_enabled"] is False
assert manifest["decision"]["multilayer_policy_review_ready"] is True
app = FastAPI()
app.include_router(build_vegetation_shadow_lab_router(root_provider=lambda: result_root.parent))
response = TestClient(app).get(
f"/api/v1/laboratory/vegetation-shadow/{result_root.name}/masks/0"
)
assert response.status_code == 200
assert response.content == b"\x89PNG\r\n\x1a\n"