feat(lab): add lazy E40 evidence review

This commit is contained in:
DCCONSTRUCTIONS
2026-07-30 21:53:04 +03:00
parent e9bbfb9a41
commit fdcaf57ae7
24 changed files with 3570 additions and 165 deletions
+88
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import json
from pathlib import Path
from types import SimpleNamespace
@@ -41,6 +42,93 @@ def test_advanced_catalogs_are_empty_when_not_configured() -> None:
}
def test_advanced_index_is_empty_when_not_configured() -> None:
router = build_advanced_laboratory_router()
route = _endpoint(router, "/api/v1/laboratory/advanced-index")
assert route() == { # type: ignore[operator]
"schema_version": "missioncore.laboratory-advanced-index/v1",
"items": [],
"access": "read-only",
}
def test_advanced_index_reads_only_bounded_identity_documents(
tmp_path: Path,
) -> None:
e31 = tmp_path / "e31"
invalid = e31 / f"e31-source-qualification-{'1' * 64}"
valid = e31 / f"e31-source-qualification-{'2' * 64}"
invalid.mkdir(parents=True)
valid.mkdir()
(invalid / "manifest.json").write_text("{}", encoding="utf-8")
(valid / "manifest.json").write_text(
json.dumps(
{
"schema_version": "missioncore.e31-source-qualification/v1",
"result_id": valid.name,
"created_at_utc": "2026-07-27T10:00:00Z",
"identity_sha256": "2" * 64,
"identity": {
"authority": {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
}
},
}
),
encoding="utf-8",
)
router = build_advanced_laboratory_router(
e31_root_provider=lambda: e31,
)
route = _endpoint(router, "/api/v1/laboratory/advanced-index")
assert route() == { # type: ignore[operator]
"schema_version": "missioncore.laboratory-advanced-index/v1",
"items": [
{
"work_id": "e31-source-binding",
"result_id": valid.name,
"created_at_utc": "2026-07-27T10:00:00Z",
"access": "read-only",
}
],
"access": "read-only",
}
def test_advanced_index_rejects_authority_escalation(
tmp_path: Path,
) -> None:
root = tmp_path / "e40"
candidate = root / f"e40-perception-product-gate-{'a' * 64}"
candidate.mkdir(parents=True)
(candidate / "manifest.json").write_text(
json.dumps(
{
"schema_version": "missioncore.e40-perception-product-gate/v1",
"result_id": candidate.name,
"created_at_utc": "2026-07-28T11:00:00Z",
"identity_sha256": "a" * 64,
"identity": {
"authority": {
"commands_enabled": True,
"navigation_or_safety_accepted": False,
}
},
}
),
encoding="utf-8",
)
router = build_advanced_laboratory_router(
e40_root_provider=lambda: root,
)
route = _endpoint(router, "/api/v1/laboratory/advanced-index")
assert route()["items"] == [] # type: ignore[index,operator]
def test_advanced_catalogs_fail_closed_on_incomplete_results(
tmp_path: Path,
) -> None:
+177
View File
@@ -0,0 +1,177 @@
from __future__ import annotations
import json
from pathlib import Path
from types import SimpleNamespace
from typing import Any
from fastapi import APIRouter
from fastapi.routing import APIRoute
from pytest import MonkeyPatch
import k1link.web.e40_case_review_api as case_api
from k1link.web.e40_case_review_api import build_e40_case_review_router
def _endpoint(router: APIRouter, path: str) -> object:
for route in router.routes:
if (
isinstance(route, APIRoute)
and route.path == path
and route.methods is not None
and "GET" in route.methods
):
return route.endpoint
raise AssertionError(f"GET {path} route is missing")
def _prediction(
*,
sequence: int,
severity: str,
split: str = "validation",
presence: str = "object-present",
predicted_presence: str = "occupied-environment",
) -> dict[str, Any]:
return {
"schema_version": "missioncore.e40-perception-prediction/v1",
"sequence": sequence,
"item_id": f"e30-review-item-{sequence:064x}",
"review_key": f"geometry:{sequence}:0",
"source_frame_index": 100 + sequence,
"source_stratum": "geometry-only",
"severity": severity,
"split": split,
"prediction": {
"presence": predicted_presence,
"geometry_association": "independent-occupied",
"freshness": "current",
},
"presence_confidence": 1.0,
"reference": {
"presence": presence,
"geometry_association": "object-associated",
"freshness": "current",
},
"scored": split == "validation",
"authority": {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
def test_e40_case_review_is_bounded_sorted_and_source_bound(
tmp_path: Path,
monkeypatch: MonkeyPatch,
) -> None:
result_id = f"e40-perception-product-gate-{'a' * 64}"
materialization_id = f"e30-materialization-{'b' * 64}"
candidate = tmp_path / result_id
candidate.mkdir()
rows = [
_prediction(sequence=7, severity="medium"),
_prediction(
sequence=1,
severity="standard",
presence="object-present",
predicted_presence="object-present",
),
_prediction(sequence=4, severity="high"),
_prediction(sequence=2, severity="high"),
_prediction(sequence=9, severity="standard", split="development"),
]
rows[1]["prediction"]["geometry_association"] = "object-associated"
predictions = candidate / "predictions.jsonl"
predictions.write_text(
"".join(json.dumps(row) + "\n" for row in rows),
encoding="utf-8",
)
(candidate / "manifest.json").write_text("{}", encoding="utf-8")
result = SimpleNamespace(
result_id=result_id,
result_root=candidate,
manifest={
"identity": {
"source": {"materialization_id": materialization_id},
},
},
report={"metrics": {"validation_items": 4}},
)
def fake_read(
root_text: str,
signature: tuple[int, ...],
) -> SimpleNamespace:
assert root_text == str(candidate.resolve())
assert signature
return result
monkeypatch.setattr(case_api, "_read_result_cached", fake_read)
router = build_e40_case_review_router(
e40_root_provider=lambda: tmp_path,
)
route = _endpoint(
router,
"/api/v1/laboratory/e40/results/{result_id}/cases",
)
catalog = route(result_id=result_id, limit=2) # type: ignore[operator]
assert catalog == {
"schema_version": "missioncore.laboratory-e40-case-catalog/v1",
"result_id": result_id,
"materialization_id": materialization_id,
"items": [
{
"item_id": f"e30-review-item-{2:064x}",
"sequence": 2,
"source_frame_index": 102,
"source_stratum": "geometry-only",
"severity": "high",
"presence_confidence": 1.0,
"prediction_basis": "fixed-stratum-policy",
"reference": {
"presence": "object-present",
"geometry_association": "object-associated",
"freshness": "current",
},
"prediction": {
"presence": "occupied-environment",
"geometry_association": "independent-occupied",
"freshness": "current",
},
"mismatched_dimensions": [
"presence",
"geometry_association",
],
"access": "read-only",
},
{
"item_id": f"e30-review-item-{4:064x}",
"sequence": 4,
"source_frame_index": 104,
"source_stratum": "geometry-only",
"severity": "high",
"presence_confidence": 1.0,
"prediction_basis": "fixed-stratum-policy",
"reference": {
"presence": "object-present",
"geometry_association": "object-associated",
"freshness": "current",
},
"prediction": {
"presence": "occupied-environment",
"geometry_association": "independent-occupied",
"freshness": "current",
},
"mismatched_dimensions": [
"presence",
"geometry_association",
],
"access": "read-only",
},
],
"total": 3,
"truncated": True,
"access": "read-only",
}
+122
View File
@@ -0,0 +1,122 @@
from __future__ import annotations
from pathlib import Path
import pytest
from k1link.compute.e40_operator_review import (
E40OperatorReviewConflictError,
E40OperatorReviewStore,
E40OperatorReviewSubject,
E40OperatorReviewSubstrate,
)
def _substrate() -> E40OperatorReviewSubstrate:
return E40OperatorReviewSubstrate(
result_id=f"e40-perception-product-gate-{'a' * 64}",
materialization_id=f"e30-materialization-{'b' * 64}",
case_catalog_sha256="c" * 64,
subjects=(
E40OperatorReviewSubject(
item_id=f"e30-review-item-{'d' * 64}",
sequence=2,
),
E40OperatorReviewSubject(
item_id=f"e30-review-item-{'e' * 64}",
sequence=9,
),
),
)
def test_e40_operator_verdict_is_atomic_resumable_and_revisioned(
tmp_path: Path,
) -> None:
store = E40OperatorReviewStore(root=tmp_path)
substrate = _substrate()
first_item = substrate.subjects[0].item_id
empty = store.get(substrate=substrate, reviewer_id="DC")
assert empty["revision"] == 0
assert empty["reviewed_item_count"] == 0
assert empty["remaining_item_count"] == 2
saved = store.record_verdict(
substrate=substrate,
reviewer_id="DC",
item_id=first_item,
expected_revision=0,
idempotency_key="ui-first",
verdict="confirmed-error",
)
assert saved["revision"] == 1
assert saved["reviewed_item_count"] == 1
assert saved["decisions"][0]["verdict"] == "confirmed-error" # type: ignore[index]
resumed = E40OperatorReviewStore(root=tmp_path).get(
substrate=substrate,
reviewer_id="DC",
)
assert resumed == saved
replay = store.record_verdict(
substrate=substrate,
reviewer_id="DC",
item_id=first_item,
expected_revision=0,
idempotency_key="ui-first",
verdict="confirmed-error",
)
assert replay == saved
revised = store.record_verdict(
substrate=substrate,
reviewer_id="DC",
item_id=first_item,
expected_revision=1,
idempotency_key="ui-revise",
verdict="rejected-error",
)
assert revised["revision"] == 2
assert revised["reviewed_item_count"] == 1
assert revised["decisions"][0]["verdict"] == "rejected-error" # type: ignore[index]
with pytest.raises(E40OperatorReviewConflictError):
store.record_verdict(
substrate=substrate,
reviewer_id="DC",
item_id=substrate.subjects[1].item_id,
expected_revision=1,
idempotency_key="ui-stale",
verdict="confirmed-error",
)
def test_e40_operator_review_is_bound_to_exact_case_catalog(
tmp_path: Path,
) -> None:
store = E40OperatorReviewStore(root=tmp_path)
substrate = _substrate()
store.record_verdict(
substrate=substrate,
reviewer_id="DC",
item_id=substrate.subjects[0].item_id,
expected_revision=0,
idempotency_key="ui-bound",
verdict="confirmed-error",
)
changed = E40OperatorReviewSubstrate(
result_id=substrate.result_id,
materialization_id=substrate.materialization_id,
case_catalog_sha256="f" * 64,
subjects=substrate.subjects,
)
changed_review = store.get(substrate=changed, reviewer_id="DC")
assert changed_review["revision"] == 0
assert changed_review["review_id"] != store.get(
substrate=substrate,
reviewer_id="DC",
)["review_id"]