feat(lab): complete E30 evidence review gate
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from k1link.compute.e30_engineering_generation import (
|
||||
E30_ENGINEERING_DECISION_SCHEMA,
|
||||
E30EngineeringGenerationError,
|
||||
_validate_decision,
|
||||
)
|
||||
from k1link.web.e30_engineering_api import _validate_decisions
|
||||
|
||||
|
||||
def _item() -> dict[str, object]:
|
||||
return {
|
||||
"sequence": 0,
|
||||
"item_id": f"e30-review-item-{'a' * 64}",
|
||||
"review_key": "geometry:100:0",
|
||||
"stratum": "geometry-only",
|
||||
}
|
||||
|
||||
|
||||
def _decision(**overrides: object) -> dict[str, object]:
|
||||
value: dict[str, object] = {
|
||||
"schema_version": E30_ENGINEERING_DECISION_SCHEMA,
|
||||
"sequence": 0,
|
||||
"item_id": f"e30-review-item-{'a' * 64}",
|
||||
"review_key": "geometry:100:0",
|
||||
"source_stratum": "geometry-only",
|
||||
"verdict": "confirmed",
|
||||
"effective_stratum": "geometry-only",
|
||||
"detector_assessment": "missed-object",
|
||||
"projection_assessment": "aligned",
|
||||
"point_ownership": "object",
|
||||
"cause_code": "detector_error",
|
||||
"confidence": 0.88,
|
||||
"human_exception_required": False,
|
||||
"exception_reason": None,
|
||||
"review_prompt": None,
|
||||
"evidence_note": "Visible object has geometry but no semantic observation.",
|
||||
"review_sheet": {
|
||||
"path": "geometry-only-01.jpg",
|
||||
"sha256": "b" * 64,
|
||||
"ordinal": 1,
|
||||
},
|
||||
}
|
||||
value.update(overrides)
|
||||
return value
|
||||
|
||||
|
||||
def test_engineering_decision_supports_detector_miss_without_rewriting_a2() -> None:
|
||||
validated = _validate_decision(
|
||||
value=_decision(),
|
||||
item=_item(),
|
||||
reason_taxonomy=("detector_error", "unknown"),
|
||||
expected_sheet={
|
||||
"path": "geometry-only-01.jpg",
|
||||
"sha256": "b" * 64,
|
||||
"ordinal": 1,
|
||||
},
|
||||
)
|
||||
|
||||
assert validated["verdict"] == "confirmed"
|
||||
assert validated["effective_stratum"] == "geometry-only"
|
||||
assert validated["detector_assessment"] == "missed-object"
|
||||
|
||||
|
||||
def test_engineering_uncertainty_must_route_a_bounded_exception() -> None:
|
||||
with pytest.raises(
|
||||
E30EngineeringGenerationError,
|
||||
match="insufficient decision must route an exception",
|
||||
):
|
||||
_validate_decision(
|
||||
value=_decision(
|
||||
verdict="insufficient-evidence",
|
||||
effective_stratum=None,
|
||||
detector_assessment="insufficient-evidence",
|
||||
confidence=0.48,
|
||||
),
|
||||
item=_item(),
|
||||
reason_taxonomy=("detector_error", "unknown"),
|
||||
expected_sheet={
|
||||
"path": "geometry-only-01.jpg",
|
||||
"sha256": "b" * 64,
|
||||
"ordinal": 1,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_engineering_api_recomputes_distributions_from_all_486_decisions() -> None:
|
||||
decisions = []
|
||||
for sequence in range(486):
|
||||
decision = _decision(
|
||||
sequence=sequence,
|
||||
item_id=f"e30-review-item-{sequence:064x}",
|
||||
review_key=f"geometry:{sequence}:0",
|
||||
)
|
||||
decisions.append(decision)
|
||||
decisions[-1] = {
|
||||
**decisions[-1],
|
||||
"verdict": "insufficient-evidence",
|
||||
"effective_stratum": None,
|
||||
"detector_assessment": "insufficient-evidence",
|
||||
"projection_assessment": "not-assessable",
|
||||
"point_ownership": "insufficient-evidence",
|
||||
"cause_code": "unknown",
|
||||
"confidence": 0.48,
|
||||
"human_exception_required": True,
|
||||
"exception_reason": "ambiguity",
|
||||
"review_prompt": {
|
||||
"question": "Is this an occupied physical object?",
|
||||
"focus": "Inspect the selected white LiDAR cluster.",
|
||||
"effects": {
|
||||
"object-present": "Retain occupied geometry.",
|
||||
"background-or-noise": "Reject the cluster.",
|
||||
"insufficient-evidence": "Keep the item unknown.",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
summary, causes = _validate_decisions(decisions)
|
||||
|
||||
assert summary["reviewed_item_count"] == 486
|
||||
assert summary["human_exception_count"] == 1
|
||||
assert summary["verdict_distribution"] == {
|
||||
"confirmed": 485,
|
||||
"insufficient-evidence": 1,
|
||||
}
|
||||
assert causes["reasons"] == [
|
||||
{"reason_code": "detector_error", "count": 485},
|
||||
{"reason_code": "unknown", "count": 1},
|
||||
]
|
||||
|
||||
|
||||
def test_engineering_exception_requires_a_specific_review_prompt() -> None:
|
||||
with pytest.raises(
|
||||
E30EngineeringGenerationError,
|
||||
match="exception review prompt is invalid",
|
||||
):
|
||||
_validate_decision(
|
||||
value=_decision(
|
||||
verdict="insufficient-evidence",
|
||||
effective_stratum=None,
|
||||
detector_assessment="insufficient-evidence",
|
||||
projection_assessment="not-assessable",
|
||||
point_ownership="insufficient-evidence",
|
||||
cause_code="unknown",
|
||||
confidence=0.48,
|
||||
human_exception_required=True,
|
||||
exception_reason="ambiguity",
|
||||
),
|
||||
item=_item(),
|
||||
reason_taxonomy=("detector_error", "unknown"),
|
||||
expected_sheet={
|
||||
"path": "geometry-only-01.jpg",
|
||||
"sha256": "b" * 64,
|
||||
"ordinal": 1,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user