feat(perception): qualify E35 degradation recovery

This commit is contained in:
DCCONSTRUCTIONS
2026-07-27 17:53:59 +03:00
parent 621084fcd6
commit b894945344
21 changed files with 3985 additions and 17 deletions
+106
View File
@@ -29,6 +29,11 @@ from k1link.compute.e34_temporal_occupied_replay import (
E34TemporalOccupiedReplayError,
read_e34_temporal_occupied_replay,
)
from k1link.compute.e35_degradation_replay import (
E35DegradationReplay,
E35DegradationReplayError,
read_e35_degradation_replay,
)
LABORATORY_ADVANCED_CATALOG_SCHEMA: Final = (
"missioncore.laboratory-advanced-catalog/v1"
@@ -38,6 +43,7 @@ _E31_RESULT_ID = re.compile(r"^e31-source-qualification-[a-f0-9]{64}$")
_E32_RESULT_ID = re.compile(r"^e32-track-geometry-[a-f0-9]{64}$")
_E33_RESULT_ID = re.compile(r"^e33-worker-shadow-[a-f0-9]{64}$")
_E34_RESULT_ID = re.compile(r"^e34-temporal-occupied-[a-f0-9]{64}$")
_E35_RESULT_ID = re.compile(r"^e35-degradation-recovery-[a-f0-9]{64}$")
RootProvider = Callable[[], Path | None]
@@ -88,6 +94,15 @@ def _read_e34_cached(
return read_e34_temporal_occupied_replay(Path(root_text))
@lru_cache(maxsize=16)
def _read_e35_cached(
root_text: str,
signature: tuple[int, ...],
) -> E35DegradationReplay:
del signature
return read_e35_degradation_replay(Path(root_text))
def _configured_root(provider: RootProvider) -> Path | None:
value = provider()
if value is None:
@@ -416,6 +431,61 @@ def _project_e34(result: E34TemporalOccupiedReplay) -> dict[str, object]:
}
def _project_e35(result: E35DegradationReplay) -> dict[str, object]:
identity = _object(result.manifest.get("identity"), "E35 identity")
profile = _object(identity.get("profile"), "E35 profile")
acceptance_profile = _object(
profile.get("acceptance"),
"E35 acceptance profile",
)
metrics = _object(result.report.get("metrics"), "E35 metrics")
accounting = _object(metrics.get("accounting"), "E35 accounting")
runtime = _object(metrics.get("runtime"), "E35 runtime")
processing = _object(
runtime.get("variant_frame_processing_ms"),
"E35 processing",
)
acceptance = _object(result.report.get("acceptance"), "E35 acceptance")
if acceptance.get("accepted") is not True:
raise ValueError("E35 result is not accepted")
return {
"result_id": result.result_id,
"created_at_utc": result.manifest.get("created_at_utc"),
"source_session_id": identity.get("source_session_id"),
"status": result.manifest.get("acceptance_state"),
"e32_result_id": identity.get("e32_result_id"),
"e33_result_id": identity.get("e33_result_id"),
"e34_result_id": identity.get("e34_result_id"),
"profile_id": profile.get("profile_id"),
"pipeline_id": identity.get("pipeline"),
"coordinate_frame": identity.get("coordinate_frame"),
"configuration": {
"maximum_recovery_seconds": acceptance_profile.get(
"maximum_recovery_seconds"
),
"scenario_count": acceptance_profile.get(
"expected_scenario_count"
),
},
"metrics": {
"source_frames": accounting.get("source_frames"),
"variant_count": accounting.get("variant_count"),
"variant_frame_outcomes": accounting.get(
"variant_frame_outcomes"
),
"injection_records": accounting.get("injection_records"),
"variant_frame_processing_p95_ms": processing.get("p95"),
"build_elapsed_ms": runtime.get("build_elapsed_ms"),
},
"scenarios": copy.deepcopy(metrics.get("scenarios")),
"review": copy.deepcopy(result.review),
"acceptance": copy.deepcopy(acceptance),
"decision": copy.deepcopy(result.report.get("decision")),
"authority": copy.deepcopy(result.report.get("authority")),
"access": "read-only",
}
def _empty_catalog(configured: bool) -> dict[str, object]:
return {
"schema_version": LABORATORY_ADVANCED_CATALOG_SCHEMA,
@@ -433,6 +503,7 @@ def build_advanced_laboratory_router(
e32_root_provider: RootProvider = lambda: None,
e33_root_provider: RootProvider = lambda: None,
e34_root_provider: RootProvider = lambda: None,
e35_root_provider: RootProvider = lambda: None,
) -> APIRouter:
router = APIRouter(prefix="/api/v1/laboratory", tags=["laboratory"])
@@ -592,4 +663,39 @@ def build_advanced_laboratory_router(
"invalid_total": invalid_total,
}
@router.get("/e35/results")
def list_e35_results(
limit: int = Query(default=1, ge=1, le=10),
) -> dict[str, object]:
root = _configured_root(e35_root_provider)
if root is None:
return _empty_catalog(False)
candidates = _candidates(root, _E35_RESULT_ID)
items: list[dict[str, object]] = []
invalid_total = 0
for candidate in candidates:
try:
result = _read_e35_cached(
str(candidate.resolve()),
_result_signature(candidate),
)
if not result.accepted:
raise ValueError("E35 result is not accepted")
if len(items) < limit:
items.append(_project_e35(result))
except (
E35DegradationReplayError,
KeyError,
OSError,
TypeError,
ValueError,
):
invalid_total += 1
return {
**_empty_catalog(True),
"items": items,
"candidate_total": len(candidates),
"invalid_total": invalid_total,
}
return router
+7
View File
@@ -527,6 +527,13 @@ app.include_router(
/ "e34"
/ "results"
),
e35_root_provider=lambda: (
REPOSITORY_ROOT
/ ".runtime"
/ "compute-experiments"
/ "e35"
/ "results"
),
)
)
app.include_router(