Files
hunjing/backend/tests/modules/safety/test_governor.py
T
2026-08-21 16:00:13 +08:00

67 lines
2.2 KiB
Python

"""司命决策器测试:风险等级 × 权限策略 × 是否确认 的决策矩阵,以及策略字典加载。"""
from __future__ import annotations
from app.modules.safety.governor import (
PermissionPolicy,
SafetyDecision,
SafetyGovernor,
ToolPolicy,
)
def test_low_risk_defaults_to_allow() -> None:
governor = SafetyGovernor()
result = governor.evaluate(tool="calc", risk_level="L1")
assert result.decision is SafetyDecision.allow
def test_medium_risk_unconfirmed_asks() -> None:
governor = SafetyGovernor()
result = governor.evaluate(tool="x", risk_level="L2")
assert result.decision is SafetyDecision.ask
def test_confirmed_becomes_allow() -> None:
governor = SafetyGovernor()
result = governor.evaluate(tool="x", risk_level="L3", confirmed=True)
assert result.decision is SafetyDecision.allow
def test_l4_always_denied() -> None:
governor = SafetyGovernor()
result = governor.evaluate(tool="x", risk_level="L4")
assert result.decision is SafetyDecision.deny
def test_forbidden_policy_denied() -> None:
governor = SafetyGovernor(
{"pay": ToolPolicy(risk_level="L3", permission_policy=PermissionPolicy.forbidden)}
)
result = governor.evaluate(tool="pay", risk_level="L3")
assert result.decision is SafetyDecision.deny
assert result.policy is PermissionPolicy.forbidden
def test_explicit_tool_policy_overrides_default() -> None:
governor = SafetyGovernor(
{"read": ToolPolicy(risk_level="L2", permission_policy=PermissionPolicy.allow)}
)
result = governor.evaluate(tool="read")
assert result.decision is SafetyDecision.allow
def test_from_policy_dict_loads_policies() -> None:
governor = SafetyGovernor.from_policy_dict(
{"tools": {"custom": {"risk_level": "L2", "permission_policy": "allow"}}}
)
result = governor.evaluate(tool="custom")
assert result.decision is SafetyDecision.allow
def test_from_policy_dict_empty_returns_default() -> None:
governor = SafetyGovernor.from_policy_dict({})
# 空 dict → 空 Governor,未列工具按 risk 推导:L2 → ask
result = governor.evaluate(tool="x", risk_level="L2")
assert result.decision is SafetyDecision.ask