Add production safety controls

This commit is contained in:
2026-06-18 13:24:17 +02:00
parent 01e5464ec1
commit 3c6fe24b03
11 changed files with 316 additions and 13 deletions

View File

@@ -134,6 +134,7 @@ def test_event_core_executes_allowed_active_decision(tmp_path: Path) -> None:
actuator_entity_id="light.storage",
stage=SafetyStage.ACTIVE,
min_confidence=0.8,
active_ready=True,
)
}
}
@@ -153,3 +154,58 @@ def test_event_core_executes_allowed_active_decision(tmp_path: Path) -> None:
decision = [item.decision for item in audit if item.decision is not None][0]
assert calls == ["light.storage"]
assert decision.executed is True
def test_active_requires_dry_run_readiness(tmp_path: Path) -> None:
stores = FutureStores(tmp_path)
stores.save_runtime(
RuntimeState(
entities={
"light.storage": EntityState(
entity_id="light.storage",
domain="light",
state="off",
)
}
)
)
stores.save_learning(
LearningState(
profiles={
"light.storage": LearningProfile(
actuator_entity_id="light.storage",
patterns=[
BehaviorPatternV2(
actuator_entity_id="light.storage",
target_state="on",
trigger_entity_id="binary_sensor.storage_door",
trigger_state="on",
support=3,
confidence=0.95,
)
],
)
}
)
)
stores.save_control(
stores.control().model_copy(
update={
"profiles": {
"light.storage": ControlProfile(
actuator_entity_id="light.storage",
stage=SafetyStage.ACTIVE,
min_confidence=0.8,
)
}
}
)
)
audit = EventCore(stores).process_state_event(
StateEvent(entity_id="binary_sensor.storage_door", new_state="on")
)
decision = [item.decision for item in audit if item.decision is not None][0]
assert decision.allowed is False
assert "Active ist noch nicht freigegeben" in decision.blockers[0]