feat(perception): seal M4.8S reference graph replay

This commit is contained in:
DCCONSTRUCTIONS
2026-08-25 16:44:26 +03:00
parent 33cef2fdea
commit 05590867b7
12 changed files with 2578 additions and 1 deletions
+78
View File
@@ -0,0 +1,78 @@
from __future__ import annotations
import hashlib
import json
from pathlib import Path
from k1link.perception.detector import RF_DETR_SHADOW_PROVIDER_ID
from k1link.perception.m48s_advisory import (
AdvisoryFamily,
advisory_policy_matrix,
)
from k1link.perception.object_understanding import AdvisoryResponse
from k1link.perception.providers import ProviderRole, ReferencePerceptionGraphConfigV2
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
GRAPH_CONFIG = (
REPOSITORY_ROOT
/ "config/perception/m48s-rf-detr-reference-graph-shadow-v0.json"
)
def test_m48s_reference_graph_replaces_only_the_detector_pin() -> None:
shadow_document = json.loads(GRAPH_CONFIG.read_text("utf-8"))
canonical_document = json.loads(
(REPOSITORY_ROOT / "config/perception/m4-reference-graph-v2.json").read_text(
"utf-8"
)
)
shadow = ReferencePerceptionGraphConfigV2.from_dict(shadow_document)
canonical = ReferencePerceptionGraphConfigV2.from_dict(canonical_document)
shadow_pins = {item.role: item for item in shadow.providers}
canonical_pins = {item.role: item for item in canonical.providers}
assert shadow.graph_id == canonical.graph_id == "reference-perception-graph/v2"
assert shadow.source_profile_id == canonical.source_profile_id
assert shadow.queues == canonical.queues
assert shadow.authority == canonical.authority
assert shadow_pins[ProviderRole.DETECTOR].provider_id == RF_DETR_SHADOW_PROVIDER_ID
assert shadow_pins[ProviderRole.DETECTOR] != canonical_pins[ProviderRole.DETECTOR]
assert all(
shadow_pins[role] == canonical_pins[role]
for role in ProviderRole
if role is not ProviderRole.DETECTOR
)
def test_m48s_reference_graph_pins_every_profile_digest() -> None:
config = ReferencePerceptionGraphConfigV2.from_dict(
json.loads(GRAPH_CONFIG.read_text("utf-8"))
)
paths = {
ProviderRole.SOURCE: "m4-recorded-realtime-baseline-v1.json",
ProviderRole.DETECTOR: "rf-detr-large-risk-shadow-v0.json",
ProviderRole.GEOMETRY: "m4-geometry-association-v1.json",
ProviderRole.TEMPORAL: "m4-temporal-motion-v1.json",
ProviderRole.MOTION: "m4-temporal-motion-v1.json",
ProviderRole.ROLLING: "m4-rolling-local-map-v1.json",
ProviderRole.THREAT: "m4-replay-threat-v3.json",
}
pins = {item.role: item for item in config.providers}
for role, name in paths.items():
payload = (REPOSITORY_ROOT / "config/perception" / name).read_bytes()
assert pins[role].sha256 == hashlib.sha256(payload).hexdigest()
def test_m48s_advisory_policy_is_bounded_distinct_and_commandless() -> None:
matrix = advisory_policy_matrix()
assert set(matrix) == set(AdvisoryFamily)
assert matrix[AdvisoryFamily.GENERIC_OBSTACLE] == (
AdvisoryResponse.ROUTE_AROUND,
)
assert AdvisoryResponse.YIELD in matrix[AdvisoryFamily.PERSON]
assert AdvisoryResponse.STOP in matrix[AdvisoryFamily.ANIMAL]
assert AdvisoryResponse.REDUCE_SPEED in matrix[AdvisoryFamily.LIGHT_ROAD_USER]
assert AdvisoryResponse.MONITOR in matrix[AdvisoryFamily.VEHICLE]
assert len(set(matrix.values())) == len(matrix)
@@ -0,0 +1,49 @@
from __future__ import annotations
import hashlib
import json
from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
RESULT_ID = (
"m48s-reference-graph-shadow-gate-"
"e8da7a521768daba0ead1a6e4803871ce3a85f91a7d8ee36c5719ac10433e791"
)
RESULT_ROOT = (
REPOSITORY_ROOT
/ ".runtime/compute-experiments/m48s-semantic-shadow/"
"reference-graph-shadow-results"
/ RESULT_ID
)
def test_m48s_complete_reference_graph_shadow_is_accepted_without_production_authority() -> None:
manifest = json.loads((RESULT_ROOT / "manifest.json").read_text("utf-8"))
identity = manifest["identity"]
evidence = identity["evidence"]
execution = evidence["execution"]
completion = evidence["world_state_completion_age_ms"]
assert manifest["result_id"] == RESULT_ID
assert identity["completed"] is True
assert identity["accepted"] is True
assert identity["production_accepted"] is False
assert identity["decision"]["source_paced_runtime_gate_accepted"] is True
assert identity["decision"]["detector_replacement_authorized"] is False
assert execution["admitted_frames"] == 4489
assert execution["delivered_world_states"] == 4481
assert execution["terminal_outcomes"] == {"delivered": 4481, "superseded": 8}
assert execution["effective_world_state_fps"] >= 9.5
assert completion["p95"] <= 175.0
assert all(evidence["checks"].values())
assert evidence["semantic_advisory"]["additional_inference_passes"] == 0
assert evidence["identity_continuity"]["duplicate_component_ids_within_frame"] == 0
assert identity["authority"] == {
"actuation_allowed": False,
"candidate_accepted": False,
"commands_enabled": False,
"ground_truth": False,
"navigation_or_safety_accepted": False,
}
for name, expected_sha256 in manifest["artifacts"].items():
assert hashlib.sha256((RESULT_ROOT / name).read_bytes()).hexdigest() == expected_sha256
+76 -1
View File
@@ -4,7 +4,7 @@ import json
import subprocess
import sys
import threading
from collections.abc import Iterator
from collections.abc import Callable, Iterator
from dataclasses import replace
from pathlib import Path
from queue import Queue
@@ -39,6 +39,7 @@ from k1link.perception.contracts import (
TimestampBundle,
)
from k1link.perception.graph import (
DeliveredFrame,
GraphExecutionError,
GraphRunMode,
GraphRunResult,
@@ -460,6 +461,8 @@ def _graph_v2(
capacity: int = 8,
run_mode: GraphRunMode = GraphRunMode.LOSSLESS_REPLAY,
terminal_timeout_ns: int = 500_000_000,
delivery_observer: Callable[[DeliveredFrame, int], None] | None = None,
delivery_evidence_observer: Callable[..., None] | None = None,
) -> ReferencePerceptionGraphV2:
return ReferencePerceptionGraphV2(
config=_config_v2(capacity, terminal_timeout_ns),
@@ -471,6 +474,8 @@ def _graph_v2(
rolling=_Rolling(),
threat=_Threat(),
run_mode=run_mode,
delivery_observer=delivery_observer,
delivery_evidence_observer=delivery_evidence_observer,
clock_ns=lambda: 10_000,
)
@@ -527,6 +532,50 @@ def test_reference_graph_v2_publishes_current_and_retained_occupancy() -> None:
}
def test_reference_graph_v2_observes_final_delivery_completion_age() -> None:
observed: list[tuple[int, int, int]] = []
def observe(delivery: DeliveredFrame, completion_age_ns: int) -> None:
observed.append(
(
delivery.sequence,
delivery.obstacle_map.output_age_ns,
completion_age_ns,
)
)
result = _graph_v2(
_Source((_packet(0, source_age_ns=123),)),
delivery_observer=observe,
).run()
assert result.state is GraphState.STOPPED
assert observed == [(0, 123, 123)]
def test_reference_graph_v2_observes_exact_delivery_evidence_inputs() -> None:
observed: list[tuple[int, int, tuple[str, ...], frozenset[str], int]] = []
def observe(delivery, packet, proposals, associated_ids, completion_age_ns) -> None:
observed.append(
(
delivery.sequence,
packet.envelope.sequence,
tuple(proposal.proposal_id for proposal in proposals),
associated_ids,
completion_age_ns,
)
)
result = _graph_v2(
_Source((_packet(0, source_age_ns=123),)),
delivery_evidence_observer=observe,
).run()
assert result.state is GraphState.STOPPED
assert observed == [(0, 0, ("proposal-0",), frozenset({"proposal-0"}), 123)]
def test_reference_graph_v2_lossless_mode_applies_bounded_backpressure() -> None:
release = Event()
@@ -784,6 +833,32 @@ def test_decoded_recorded_source_attaches_images_without_detector_logic(tmp_path
assert int(packets[1].image_payload[0, 0, 0]) == 7
def test_decoded_recorded_source_primes_decoder_before_source_clock() -> None:
events: list[str] = []
class Source(RecordedRavnoves00Source):
def __init__(self) -> None:
pass
def packets(self, stop_event: Event) -> Iterator[SourcePacket]:
events.append("source-clock-started")
if not stop_event.is_set():
yield _packet(0)
class Decoder:
def frames(self, stop_event: Event) -> Iterator[np.ndarray]:
events.append("decoder-primed")
if not stop_event.is_set():
yield np.zeros((600, 800, 3), dtype=np.uint8)
packets = list(
DecodedRecordedSource(source=Source(), decoder=Decoder()).packets(Event())
)
assert len(packets) == 1
assert events == ["decoder-primed", "source-clock-started"]
def test_camera_only_path_never_invents_metric_occupancy_or_free_space() -> None:
result = _graph(_Source((_packet(0, lidar=False),))).run()
delivery = result.deliveries[0]