guardrail-space-verifiable-.../guardrail_space/engine.py

39 lines
1.5 KiB
Python

from typing import Dict, Any, Tuple
from .contract import SafetyContract
def evaluate_action(contract: SafetyContract, state: Dict[str, Any], action: Dict[str, Any]) -> Tuple[str, Dict[str, Any]]:
"""Evaluate a proposed action against a SafetyContract.
Returns a tuple (verdict, payload) where verdict is one of:
- 'accept' (payload is possibly rewritten action)
- 'veto' (payload contains reason)
This minimal engine performs precondition and budget checks and may
rewrite actions to a safe alternative when possible.
"""
ok, reason = contract.check_preconditions(state, action)
if not ok:
return "veto", {"reason": reason}
ok, reason = contract.check_budgets(state, action)
if not ok:
# attempt a simple rewrite: scale down costs/speeds if present
if "speed" in action:
safe_action = dict(action)
safe_action["speed"] = action["speed"] * 0.5
# Re-check budgets assuming cost scales with speed linearly
costs = dict(action.get("costs", {}))
for k in costs:
costs[k] = costs[k] * 0.5
safe_action["costs"] = costs
ok2, reason2 = contract.check_budgets(state, safe_action)
if ok2:
contract.charge_budgets(safe_action)
return "accept", safe_action
return "veto", {"reason": reason}
# Accept and charge budgets
contract.charge_budgets(action)
return "accept", action