159 lines
5.1 KiB
Python
159 lines
5.1 KiB
Python
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,
|
|
},
|
|
)
|