feat(lab): publish full TGS shadow evidence
This commit is contained in:
@@ -127,7 +127,7 @@ def test_product_registry_declares_every_advanced_evidence_source() -> None:
|
||||
repository_root / "config" / "laboratories"
|
||||
)
|
||||
|
||||
assert len(registry.definitions) == 41
|
||||
assert len(registry.definitions) == 42
|
||||
assert {item.work_id for item in registry.definitions} >= {
|
||||
"e31-source-binding",
|
||||
"e46j-raw-fisheye-realtime",
|
||||
@@ -145,6 +145,7 @@ def test_product_registry_declares_every_advanced_evidence_source() -> None:
|
||||
"m48s-fixed-class-detector",
|
||||
"m48t-risk-quality-temporal",
|
||||
"m49-tgs-fail-closed-evidence",
|
||||
"m49-tgs-full-shadow",
|
||||
}
|
||||
m48 = next(
|
||||
item for item in registry.definitions if item.work_id == "m48-object-centric-quality"
|
||||
|
||||
@@ -102,6 +102,7 @@ def test_repository_registry_classifies_every_evidence_definition() -> None:
|
||||
"m48s-fixed-class-detector",
|
||||
"m48t-risk-quality-temporal",
|
||||
"m49-tgs-fail-closed-evidence",
|
||||
"m49-tgs-full-shadow",
|
||||
}
|
||||
by_work_id = {row.work_id: row for row in execution.definitions}
|
||||
assert by_work_id["m48-small-static-passage-regression"].evidence_contract == (
|
||||
@@ -121,6 +122,8 @@ def test_repository_registry_classifies_every_evidence_definition() -> None:
|
||||
assert by_work_id["m48t-risk-quality-temporal"].isolation == "bounded-adapter"
|
||||
assert by_work_id["m49-tgs-fail-closed-evidence"].lifecycle == "experimental"
|
||||
assert by_work_id["m49-tgs-fail-closed-evidence"].isolation == "bounded-adapter"
|
||||
assert by_work_id["m49-tgs-full-shadow"].lifecycle == "experimental"
|
||||
assert by_work_id["m49-tgs-full-shadow"].isolation == "bounded-adapter"
|
||||
assert all(
|
||||
row.lifecycle == "canonical"
|
||||
for row in execution.definitions
|
||||
@@ -130,6 +133,7 @@ def test_repository_registry_classifies_every_evidence_definition() -> None:
|
||||
"m48s-fixed-class-detector",
|
||||
"m48t-risk-quality-temporal",
|
||||
"m49-tgs-fail-closed-evidence",
|
||||
"m49-tgs-full-shadow",
|
||||
}
|
||||
)
|
||||
assert len(execution.definitions) + len(execution.legacy_work_ids) == len(
|
||||
|
||||
@@ -80,7 +80,7 @@ def test_product_value_review_registry_covers_reviewed_laboratory_families() ->
|
||||
root / "config" / "laboratory-value-review.json"
|
||||
)
|
||||
|
||||
assert len(registry.entries) == 39
|
||||
assert len(registry.entries) == 40
|
||||
assert {entry.catalog_id for entry in registry.entries} >= {
|
||||
"e28-local-surface",
|
||||
"e46d-temporal-failure-audit",
|
||||
@@ -92,4 +92,5 @@ def test_product_value_review_registry_covers_reviewed_laboratory_families() ->
|
||||
"m48s-fixed-class-detector",
|
||||
"m48t-risk-quality-temporal",
|
||||
"m49-tgs-fail-closed-evidence",
|
||||
"m49-tgs-full-shadow",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
from k1link.web import m49_tgs_full_shadow_api as full_shadow_api
|
||||
|
||||
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
|
||||
WORKER_ROOT = REPOSITORY_ROOT / "experiments" / "perception" / "worker" / "m49_t3_travel"
|
||||
sys.path.insert(0, str(WORKER_ROOT))
|
||||
|
||||
EVIDENCE_SPEC = importlib.util.spec_from_file_location(
|
||||
"m49_tgs_full_shadow_evidence", WORKER_ROOT / "build_tgs_full_shadow_evidence.py"
|
||||
)
|
||||
assert EVIDENCE_SPEC and EVIDENCE_SPEC.loader
|
||||
EVIDENCE = importlib.util.module_from_spec(EVIDENCE_SPEC)
|
||||
EVIDENCE_SPEC.loader.exec_module(EVIDENCE)
|
||||
|
||||
ARTIFACT_SPEC = importlib.util.spec_from_file_location(
|
||||
"m49_tgs_full_shadow_artifact",
|
||||
REPOSITORY_ROOT / "scripts" / "build_m49_tgs_full_shadow_worker_artifact.py",
|
||||
)
|
||||
assert ARTIFACT_SPEC and ARTIFACT_SPEC.loader
|
||||
ARTIFACT = importlib.util.module_from_spec(ARTIFACT_SPEC)
|
||||
ARTIFACT_SPEC.loader.exec_module(ARTIFACT)
|
||||
|
||||
|
||||
def test_full_shadow_exact_multiset_and_costmap_priority() -> None:
|
||||
native = np.asarray(
|
||||
[[2.0, 0.0, 0.0, 0.0], [2.0, 0.0, 0.0, 0.0], [3.0, 0.0, 1.0, 0.0], [4.0, 0.0, 2.0, 0.0]],
|
||||
dtype=np.float32,
|
||||
)
|
||||
points, states = EVIDENCE.classify_exact_input(native, native[[0]], native[[1, 2]])
|
||||
assert sorted(states.tolist()) == [1, 2, 2, 3]
|
||||
grid = EVIDENCE.costmap_grid(12.0, 0.45)
|
||||
cell_states, _ = EVIDENCE.rasterize(points, states, grid, 0.45)
|
||||
assert np.count_nonzero(cell_states == 2) == 2
|
||||
|
||||
|
||||
def test_full_shadow_worker_artifact_is_deterministic_and_cpu_only(tmp_path: Path) -> None:
|
||||
revision = "a" * 40
|
||||
first = ARTIFACT.build("m49-tgs-full-test", tmp_path / "one", revision=revision)
|
||||
second = ARTIFACT.build("m49-tgs-full-test", tmp_path / "two", revision=revision)
|
||||
assert first["sha256"] == second["sha256"]
|
||||
import tarfile
|
||||
|
||||
with tarfile.open(first["artifact"], "r:gz") as archive:
|
||||
release = archive.extractfile("payload/release.json")
|
||||
runner = archive.extractfile("payload/Invoke-M49TgsFullShadow.ps1")
|
||||
assert release is not None and runner is not None
|
||||
release_text = release.read().decode()
|
||||
runner_text = runner.read().decode()
|
||||
assert '"candidate_id": "travel-tgs-full-shadow"' in release_text
|
||||
assert "--gpus" not in runner_text
|
||||
assert "gpu_requested = $false" in runner_text
|
||||
|
||||
|
||||
def test_full_shadow_chunk_contract_keeps_missing_lidar_unobserved(
|
||||
monkeypatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
frames = tuple(
|
||||
{
|
||||
"source_frame_index": index,
|
||||
"session_seconds": index / 10,
|
||||
"sample_available": index != 1,
|
||||
"eligible_point_count": 0 if index == 1 else 1,
|
||||
"ground_point_count": 0,
|
||||
"nonground_point_count": 0 if index == 1 else 1,
|
||||
"rejected_point_count": 0,
|
||||
"occupied_cell_count": 0 if index == 1 else 1,
|
||||
}
|
||||
for index in range(4489)
|
||||
)
|
||||
centers = np.zeros((2244, 2), dtype=np.float32)
|
||||
states = np.broadcast_to(np.zeros((1, 2244), dtype=np.uint8), (4489, 2244))
|
||||
z_bounds = np.broadcast_to(
|
||||
np.full((1, 2244, 2), np.nan, dtype=np.float32),
|
||||
(4489, 2244, 2),
|
||||
)
|
||||
|
||||
monkeypatch.setattr(full_shadow_api, "_frames", lambda *_args: frames)
|
||||
monkeypatch.setattr(
|
||||
full_shadow_api.np,
|
||||
"load",
|
||||
lambda path, **_kwargs: (
|
||||
centers if "centers" in str(path) else states if "states" in str(path) else z_bounds
|
||||
),
|
||||
)
|
||||
content = full_shadow_api._chunk_json_cached.__wrapped__(
|
||||
str(tmp_path),
|
||||
"m49-tgs-full-shadow-" + "a" * 64,
|
||||
0,
|
||||
2,
|
||||
(0, 0),
|
||||
)
|
||||
payload = json.loads(content)
|
||||
assert payload["schema_version"] == "missioncore.m49-tgs-full-shadow-spatial-chunk/v1"
|
||||
assert payload["count"] == 2
|
||||
assert len(payload["costmap"]["centers_xy_m"]) == 2244
|
||||
assert payload["frames"][1]["sample_available"] is False
|
||||
assert set(payload["frames"][1]["states"]) == {0}
|
||||
Reference in New Issue
Block a user