Добавление канонического графа M4.7
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from k1link.perception.contracts import LocalObstacleMap, SourceAccounting
|
||||
from k1link.perception.graph_contracts import (
|
||||
REFERENCE_GRAPH_ID_V2,
|
||||
DeliveredFrame,
|
||||
GraphRunMode,
|
||||
GraphState,
|
||||
TerminalOutcome,
|
||||
TerminalOutcomeType,
|
||||
build_graph_run_result_v2,
|
||||
)
|
||||
from k1link.perception.reference_graph_parity import (
|
||||
compare_reference_graph_to_accepted_ledgers,
|
||||
)
|
||||
|
||||
|
||||
def _result():
|
||||
obstacle_map = LocalObstacleMap(
|
||||
source_id="RAVNOVES00",
|
||||
session_id="20260720T065719Z_viewer_live",
|
||||
frame_id="frame-000000",
|
||||
graph_id=REFERENCE_GRAPH_ID_V2,
|
||||
generated_monotonic_ns=1,
|
||||
output_age_ns=0,
|
||||
occupied=(),
|
||||
unknown=(),
|
||||
camera_uncertainty=(),
|
||||
accounting=SourceAccounting(1, 1, 0, 0),
|
||||
)
|
||||
return build_graph_run_result_v2(
|
||||
graph_id=REFERENCE_GRAPH_ID_V2,
|
||||
source_profile_id="m4-ravnoves00-recorded-realtime/v1",
|
||||
run_mode=GraphRunMode.LOSSLESS_REPLAY,
|
||||
state=GraphState.STOPPED,
|
||||
admitted_count=1,
|
||||
outcomes=(
|
||||
TerminalOutcome(
|
||||
source_id="RAVNOVES00",
|
||||
session_id="20260720T065719Z_viewer_live",
|
||||
frame_id="frame-000000",
|
||||
sequence=0,
|
||||
outcome=TerminalOutcomeType.DELIVERED,
|
||||
stage_id="threat",
|
||||
reason="object-payload-delivered",
|
||||
),
|
||||
),
|
||||
deliveries=(DeliveredFrame(0, obstacle_map, ()),),
|
||||
queue_high_watermarks=(("detector", 1),),
|
||||
)
|
||||
|
||||
|
||||
def _write_ledgers(root: Path, *, threat_assessments: list[dict[str, object]]) -> tuple[Path, Path]:
|
||||
temporal = root / "temporal.jsonl"
|
||||
threat = root / "threat.jsonl"
|
||||
temporal.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"sequence": 0,
|
||||
"frame_id": "frame-000000",
|
||||
"current": [],
|
||||
"rolling_retained": [],
|
||||
"held": [],
|
||||
"expired": [],
|
||||
}
|
||||
)
|
||||
+ "\n",
|
||||
"utf-8",
|
||||
)
|
||||
threat.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"sequence": 0,
|
||||
"frame_id": "frame-000000",
|
||||
"camera_proposals": [],
|
||||
"assessments": threat_assessments,
|
||||
}
|
||||
)
|
||||
+ "\n",
|
||||
"utf-8",
|
||||
)
|
||||
return temporal, threat
|
||||
|
||||
|
||||
def test_reference_graph_parity_accepts_exact_frame_semantics(tmp_path: Path) -> None:
|
||||
temporal, threat = _write_ledgers(tmp_path, threat_assessments=[])
|
||||
|
||||
report = compare_reference_graph_to_accepted_ledgers(
|
||||
_result(),
|
||||
temporal_frames_path=temporal,
|
||||
threat_frames_path=threat,
|
||||
expected_frames=1,
|
||||
)
|
||||
|
||||
assert report.accepted is True
|
||||
assert dict(report.mismatch_counts) == {
|
||||
"camera_uncertainty": 0,
|
||||
"current": 0,
|
||||
"expired": 0,
|
||||
"held": 0,
|
||||
"rolling_retained": 0,
|
||||
"source_binding": 0,
|
||||
"threat_assessments": 0,
|
||||
}
|
||||
|
||||
|
||||
def test_reference_graph_parity_reports_threat_drift(tmp_path: Path) -> None:
|
||||
temporal, threat = _write_ledgers(tmp_path, threat_assessments=[{"component_id": "x"}])
|
||||
|
||||
report = compare_reference_graph_to_accepted_ledgers(
|
||||
_result(),
|
||||
temporal_frames_path=temporal,
|
||||
threat_frames_path=threat,
|
||||
expected_frames=1,
|
||||
)
|
||||
|
||||
assert report.accepted is False
|
||||
assert dict(report.mismatch_counts)["threat_assessments"] == 1
|
||||
Reference in New Issue
Block a user