from __future__ import annotations from pathlib import Path import pytest from k1link.laboratory.vegetation_mission_policy import ( VegetationMissionPolicyError, load_vegetation_mission_policy, resolve_terrain_policy, ) REPOSITORY_ROOT = Path(__file__).resolve().parents[1] POLICY_PATH = ( REPOSITORY_ROOT / "config" / "perception" / "lab-v1-vegetation-mission-policy-v1.json" ) def _policy() -> dict[str, object]: return load_vegetation_mission_policy(POLICY_PATH, repository_root=REPOSITORY_ROOT) def test_presets_are_defaults_and_explicit_mission_rule_wins() -> None: policy = _policy() urban_default = resolve_terrain_policy( policy, preset_id="urban", material_class="grass", evidence_state="VEGETATION_POTENTIALLY_TRAVERSABLE", ) assert urban_default.requested_action == "NO_GO" assert urban_default.effective_action == "NO_GO" assert urban_default.policy_source == "selected_preset_default" explicit_allow = resolve_terrain_policy( policy, preset_id="urban", material_class="grass", evidence_state="VEGETATION_POTENTIALLY_TRAVERSABLE", mission_rules={"grass": "ALLOW"}, ) assert explicit_allow.requested_action == "ALLOW" assert explicit_allow.effective_action == "ALLOW" assert explicit_allow.policy_source == "explicit_mission_rule" assert explicit_allow.actuation_authority is False def test_offroad_grass_is_high_cost_until_mission_changes_it() -> None: decision = resolve_terrain_policy( _policy(), preset_id="offroad", material_class="grass", evidence_state="VEGETATION_POTENTIALLY_TRAVERSABLE", ) assert decision.requested_action == "HIGH_COST" assert decision.effective_action == "HIGH_COST" assert decision.safety_reason is None @pytest.mark.parametrize( "state", [ "UNOBSERVED", "NEGATIVE_OR_UNSUPPORTED", "RIGID_OR_UNKNOWN_OBSTACLE", "VEGETATION_UNKNOWN", "VEGETATION_WITH_RIGID_GEOMETRY", ], ) def test_mission_allow_never_clears_hard_safety_interlock(state: str) -> None: decision = resolve_terrain_policy( _policy(), preset_id="offroad", material_class="grass", evidence_state=state, mission_rules={"grass": "ALLOW"}, ) assert decision.requested_action == "ALLOW" assert decision.effective_action == "NO_GO" assert decision.safety_reason == f"hard_safety_interlock:{state}" def test_missing_semantics_and_support_fail_closed() -> None: decision = resolve_terrain_policy( _policy(), preset_id="rural", material_class=None, evidence_state=None, ) assert decision.material_class == "vegetation_unknown" assert decision.evidence_state == "UNOBSERVED" assert decision.effective_action == "NO_GO" def test_woody_material_cannot_be_enabled_by_mission() -> None: with pytest.raises( VegetationMissionPolicyError, match="material cannot be overridden by a mission: tree_or_trunk", ): resolve_terrain_policy( _policy(), preset_id="offroad", material_class="tree_or_trunk", evidence_state="SUPPORTED_GROUND", mission_rules={"tree_or_trunk": "ALLOW"}, ) def test_unknown_material_is_treated_as_unknown_vegetation() -> None: decision = resolve_terrain_policy( _policy(), preset_id="offroad", material_class="provider_specific_leaf", evidence_state="SUPPORTED_GROUND", ) assert decision.material_class == "vegetation_unknown" assert decision.effective_action == "NO_GO" assert decision.safety_reason == "hard_safety_interlock:vegetation_unknown"