test_agent_governance_contract.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from pathlib import Path
  2. from app.core.system.permissions import (
  3. AGENTS_MANAGE,
  4. AGENTS_OPERATE,
  5. AGENTS_READ,
  6. permission_for_request,
  7. permissions_for_roles,
  8. )
  9. ROOT = Path(__file__).resolve().parents[1]
  10. def test_agent_governance_migration_is_additive_scoped_and_evidence_preserving():
  11. migration = (ROOT / "migrations/versions/20260802_450_agent_governance.py").read_text()
  12. assert 'revision = "20260802_450"' in migration
  13. assert 'down_revision = "20260802_440"' in migration
  14. for table in (
  15. "governed_agents", "governed_agent_versions", "agent_tool_grants",
  16. "agent_credentials", "agent_action_requests", "agent_governance_events",
  17. ):
  18. assert f"CREATE TABLE public.{table}" in migration
  19. assert "INTERVAL '15 minutes'" in migration
  20. assert "automatic_execution_allowed" in migration
  21. assert "REFERENCES public.governance_tasks(uid)" in migration
  22. assert "raise RuntimeError" in migration
  23. assert "DROP TABLE" not in migration.upper()
  24. def test_agent_permissions_are_separated_and_deny_by_default_router_knows_them():
  25. assert AGENTS_READ in permissions_for_roles(["viewer"])
  26. assert AGENTS_OPERATE not in permissions_for_roles(["viewer"])
  27. assert AGENTS_OPERATE in permissions_for_roles(["editor"])
  28. assert AGENTS_MANAGE not in permissions_for_roles(["editor"])
  29. assert AGENTS_MANAGE in permissions_for_roles(["admin"])
  30. assert permission_for_request("/api/knowledge/agents", "GET") == (AGENTS_READ,)
  31. assert permission_for_request("/api/knowledge/agents", "POST") == (AGENTS_MANAGE,)
  32. assert permission_for_request(
  33. "/api/knowledge/agents/x/actions/authorize", "POST"
  34. ) == (AGENTS_OPERATE,)
  35. assert permission_for_request(
  36. "/api/knowledge/agents/actions/x/reconcile", "POST"
  37. ) == (AGENTS_MANAGE,)
  38. def test_agent_api_and_operator_surface_expose_identity_grants_decisions_and_replay():
  39. api = (ROOT / "app/api/knowledge_base/agent_governance_routes.py").read_text()
  40. client = (ROOT / "frontend/src/api/agentGovernance.js").read_text()
  41. view = (ROOT / "frontend/src/views/systemManage/agentGovernance/index.vue").read_text()
  42. routes = (ROOT / "frontend/src/router/routes.js").read_text()
  43. for surface in ("/agents", "/grants", "/credentials", "/actions/authorize", "/reconcile", "/complete", "/replay", "/dashboard"):
  44. assert surface in api
  45. for operation in (
  46. "registerGovernedAgent", "createAgentToolGrant", "issueAgentCredential",
  47. "revokeAgentCredentials", "reconcileAgentAction", "replayAgentAction",
  48. ):
  49. assert operation in client
  50. for boundary in (
  51. "高风险和关键风险操作", "平台不会自动执行", "凭证最长 15 分钟",
  52. "凭证仅本次返回", "决策证据回放",
  53. ):
  54. assert boundary in view or boundary in api
  55. assert "/systemManage/agent-governance" in routes
  56. assert "agents:read" in routes
  57. def test_repository_never_persists_raw_prompt_token_or_output():
  58. migration = (ROOT / "migrations/versions/20260802_450_agent_governance.py").read_text()
  59. repository = (ROOT / "app/core/llm/agent_governance_repository.py").read_text()
  60. service = (ROOT / "app/core/llm/agent_governance.py").read_text()
  61. assert "raw_prompt" not in migration
  62. assert "token_digest" in migration and "token_digest" in repository
  63. assert "input_digest" in migration and "output_digest" in migration
  64. assert '"raw_prompt_retained": False' in service
  65. assert "high-risk automatic execution is disabled" in service
  66. assert "UnifiedWorkCenterService" in repository