feat(perception): expire costmap permissions per cell

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 10:57:42 +03:00
parent bcacb02a22
commit 1f8101e4a5
7 changed files with 488 additions and 25 deletions
@@ -0,0 +1,76 @@
"""Bounded synthetic per-cell freshness tests, with no model/source dependency."""
import json
import pytest
from k1link.perception.costmap_freshness import CostmapCellEvidence
from k1link.perception.realtime_contract import RealtimeContractError
NOW = 9_007_199_254_740_993
def check(stamps, states, actions, *, elapsed_ms=0, uncertainty_ms=0):
return CostmapCellEvidence(tuple(stamps)).assess(
states=tuple(states),
actions=tuple(actions),
source_time_ns=NOW,
observed_source_time_ns=NOW + elapsed_ms * 1_000_000,
maximum_age_ms=250,
clock_uncertainty_ms=uncertainty_ms,
)
def test_expiry_is_addressed_and_cannot_clear_occupied_or_unknown_cells():
stamps = (NOW - 200_000_000, NOW, NOW - 999_000_000, None, None)
result = check(stamps, [1, 1, 2, 0, 1], [0, 1, 2, 2, 0], elapsed_ms=51)
assert result.states == (3, 1, 2, 0, 3)
assert result.actions == (2, 1, 2, 2, 2)
assert result.expired_cells == 1 and result.missing_support_cells == 1
assert result.suppressed_permissions == 2
assert result.oldest_permissive_source_time_ns == NOW
# Even an earlier assessment cannot restore a suppressed permission.
repeated = check(stamps, result.states, result.actions)
assert repeated.states == result.states and repeated.actions == result.actions
def test_ttl_boundary_includes_mapping_uncertainty_without_refreshing_support():
stamp = NOW - 200_000_000
assert check([stamp], [1], [0], elapsed_ms=45, uncertainty_ms=5).actions == (0,)
assert check([stamp], [1], [0], elapsed_ms=46, uncertainty_ms=5).actions == (2,)
assert check([stamp], [1], [0]).oldest_permissive_source_time_ns == stamp
def test_cell_wire_is_exact_int64_and_has_a_bounded_shape():
evidence = CostmapCellEvidence((NOW, None))
assert evidence.to_dict()["observed_source_time_ns"] == [str(NOW), None]
assert CostmapCellEvidence.from_dict(json.loads(json.dumps(evidence.to_dict()))) == evidence
with pytest.raises(RealtimeContractError):
CostmapCellEvidence((NOW,) * 8193)
@pytest.mark.parametrize("stamp", [NOW, "01", "-1", str(2**63), True, {}, "NaN"])
def test_invalid_wire_timestamp_is_rejected(stamp):
value = CostmapCellEvidence((NOW,)).to_dict()
value["observed_source_time_ns"] = [stamp]
with pytest.raises(RealtimeContractError):
CostmapCellEvidence.from_dict(value)
@pytest.mark.parametrize(
"stamps,states,actions,elapsed,uncertainty",
[
([NOW + 1], [1], [0], 0, 0),
([NOW], [1], [0], -1, 0),
([NOW], [1], [0], 0, float("nan")),
([NOW], [1], [0], 0, -1),
([NOW], [True], [0], 0, 0),
([NOW], [1], [True], 0, 0),
([NOW], [2], [0], 0, 0),
([None], [0], [1], 0, 0),
([NOW], [], [], 0, 0),
],
)
def test_invalid_evidence_never_grants_permission(stamps, states, actions, elapsed, uncertainty):
with pytest.raises(RealtimeContractError):
check(stamps, states, actions, elapsed_ms=elapsed, uncertainty_ms=uncertainty)
+110
View File
@@ -8,6 +8,7 @@ from pathlib import Path
import pytest
from k1link.perception.costmap_freshness import CostmapCellEvidence
from k1link.perception.realtime_contract import (
REQUIRED_LAYERS,
LayerEvidence,
@@ -296,3 +297,112 @@ def test_pilot_rejects_wrong_run_sequence_and_control_authority(pilot):
changed["commands_enabled"] = True
with pytest.raises(ValueError, match="authority"):
pilot.validate_receipt(changed, bundle, epoch_id="pilot")
@pytest.mark.parametrize("own_time", [NOW + 1, True])
def test_derivation_cannot_hide_invalid_own_time_behind_an_older_parent(own_time):
value = scene(held_ms=100)
with pytest.raises(RealtimeContractError):
derive_layer(
"costmap",
epoch_id="epoch",
source_sequence=2,
source_time_ns=NOW,
payload_sha256="a" * 64,
inputs=tuple(value.layers[i] for i in (0, 2, 3)),
oldest_required_input_time_ns=own_time,
)
def cell_input():
payload, bundle, ddr = pilot_input()
payload["costmap_states"] = [1, 1]
payload["costmap_material"] = [1, 1]
payload["policy_actions"] = [0, 0]
payload["policy_counts"] = {"ALLOW_candidate": 2, "HIGH_COST": 0, "NO_GO": 0}
payload["costmap_cell_evidence"] = CostmapCellEvidence((NOW - 200_000_000, NOW)).to_dict()
payload["tgs_counts"]["oldest_permissive_cell_source_ns"] = NOW - 200_000_000
return payload, bundle, ddr
def test_consumer_expires_only_old_cell_and_rehashes_view_without_mutating_wire(pilot):
payload, bundle, ddr = cell_input()
pilot.prepare_publication(
payload,
bundle,
ddr,
epoch_id="pilot",
now_ns=bundle["due_ns"] + 10_000_000,
mode="per-cell",
)
original = copy.deepcopy(payload)
freshness = pilot.validate_receipt(payload, bundle, epoch_id="pilot")
view, checked = pilot.assess_receipt(
payload,
freshness,
bundle=bundle,
now_ns=bundle["due_ns"] + 60_000_000,
)
assert checked.fresh_complete
assert view["costmap_states"] == [3, 1] and view["policy_actions"] == [2, 0]
assert view["cell_assessment"]["expired_ground_cells"] == 1
assert checked.layers[4].oldest_required_input_time_ns == NOW - 20_000_000
assert payload == original
derived = pilot.validate_receipt(view, bundle, epoch_id="pilot")
assert derived.source_time_ns == freshness.source_time_ns
aged, expired = pilot.assess_receipt(
view,
derived,
bundle=bundle,
now_ns=bundle["due_ns"] + 260_000_000,
)
assert not expired.fresh_complete and aged["policy_actions"] == [2, 2]
pilot.validate_receipt(aged, bundle, epoch_id="pilot")
with pytest.raises(ValueError, match="backwards"):
pilot.assess_receipt(view, derived, bundle=bundle, now_ns=bundle["due_ns"])
@pytest.mark.parametrize("missing,held_ms", [(True, 0), (False, 220)])
def test_cell_freshness_cannot_override_missing_lidar_or_stale_segmentation(
pilot, missing, held_ms
):
payload, bundle, ddr = cell_input()
bundle["available"] = not missing
if held_ms:
ddr.update(state="held", source_sequence=1, source_host_monotonic_ns=NOW - 220_000_000)
pilot.prepare_publication(
payload,
bundle,
ddr,
epoch_id="pilot",
now_ns=bundle["due_ns"],
mode="per-cell",
)
fresh = pilot.validate_receipt(payload, bundle, epoch_id="pilot")
view, checked = pilot.assess_receipt(
payload,
fresh,
bundle=bundle,
now_ns=bundle["due_ns"] + 60_000_000,
)
assert not checked.fresh_complete and view["policy_actions"] == [2, 2]
pilot.validate_receipt(view, bundle, epoch_id="pilot")
def test_cell_timestamp_and_mode_are_bound_to_costmap_hash(pilot):
payload, bundle, ddr = cell_input()
pilot.prepare_publication(
payload,
bundle,
ddr,
epoch_id="pilot",
now_ns=bundle["due_ns"],
mode="per-cell",
)
changed = copy.deepcopy(payload)
changed["costmap_cell_evidence"]["observed_source_time_ns"][0] = str(NOW)
with pytest.raises(ValueError, match="digest"):
pilot.validate_receipt(changed, bundle, epoch_id="pilot")
payload["costmap_freshness_mode"] = "whole-scene"
with pytest.raises(ValueError, match="digest"):
pilot.validate_receipt(payload, bundle, epoch_id="pilot")