feat(governance): 定義 Agent 主動營運委派契約
This commit is contained in:
184
apps/api/tests/test_ai_agent_proactive_operations_contract.py
Normal file
184
apps/api/tests/test_ai_agent_proactive_operations_contract.py
Normal file
@@ -0,0 +1,184 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.ai_agent_proactive_operations_contract import (
|
||||
load_latest_ai_agent_proactive_operations_contract,
|
||||
)
|
||||
|
||||
|
||||
def test_load_latest_ai_agent_proactive_operations_contract_reads_committed_snapshot():
|
||||
data = load_latest_ai_agent_proactive_operations_contract()
|
||||
|
||||
assert data["schema_version"] == "ai_agent_proactive_operations_contract_v1"
|
||||
assert data["program_status"]["overall_completion_percent"] == 30
|
||||
assert data["program_status"]["current_task_id"] == "P2-402A"
|
||||
assert data["program_status"]["next_task_id"] == "P2-402B"
|
||||
assert data["program_status"]["read_only_mode"] is True
|
||||
assert data["program_status"]["runtime_authority"] == "contract_only_no_version_or_runtime_update"
|
||||
assert data["approval_boundaries"]["runtime_version_update_allowed"] is False
|
||||
assert data["approval_boundaries"]["package_upgrade_allowed"] is False
|
||||
assert data["approval_boundaries"]["host_upgrade_allowed"] is False
|
||||
assert data["approval_boundaries"]["workflow_schedule_enabled"] is False
|
||||
assert data["approval_boundaries"]["telegram_direct_send_allowed"] is False
|
||||
assert data["rollups"]["version_domain_count"] == len(data["version_lifecycle_domains"]) == 12
|
||||
assert data["rollups"]["delegable_capability_count"] == len(data["delegable_capabilities"]) == 24
|
||||
assert data["rollups"]["auto_execute_allowed_count"] == 0
|
||||
assert any(domain["domain_id"] == "ai_agents_models" for domain in data["version_lifecycle_domains"])
|
||||
assert any(
|
||||
capability["capability_id"] == "telegram_delivery_audit"
|
||||
for capability in data["delegable_capabilities"]
|
||||
)
|
||||
|
||||
|
||||
def test_load_latest_ai_agent_proactive_operations_contract_rejects_version_update(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["approval_boundaries"]["package_upgrade_allowed"] = True
|
||||
(tmp_path / "ai_agent_proactive_operations_contract_2026-06-11.json").write_text(
|
||||
json.dumps(snapshot),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError, match="approval boundaries"):
|
||||
load_latest_ai_agent_proactive_operations_contract(tmp_path)
|
||||
|
||||
|
||||
def test_load_latest_ai_agent_proactive_operations_contract_rejects_rollup_mismatch(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["rollups"]["delegable_capability_count"] = 99
|
||||
(tmp_path / "ai_agent_proactive_operations_contract_2026-06-11.json").write_text(
|
||||
json.dumps(snapshot),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError, match="rollup counts"):
|
||||
load_latest_ai_agent_proactive_operations_contract(tmp_path)
|
||||
|
||||
|
||||
def test_load_latest_ai_agent_proactive_operations_contract_rejects_auto_execute(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["delegable_capabilities"][0]["automation_level"] = "L5_auto_execute"
|
||||
snapshot["rollups"]["auto_execute_allowed_count"] = 1
|
||||
(tmp_path / "ai_agent_proactive_operations_contract_2026-06-11.json").write_text(
|
||||
json.dumps(snapshot),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError, match="auto execute"):
|
||||
load_latest_ai_agent_proactive_operations_contract(tmp_path)
|
||||
|
||||
|
||||
def _snapshot() -> dict:
|
||||
return {
|
||||
"schema_version": "ai_agent_proactive_operations_contract_v1",
|
||||
"generated_at": "2026-06-11T21:30:00+08:00",
|
||||
"program_status": {
|
||||
"overall_completion_percent": 30,
|
||||
"current_priority": "P2",
|
||||
"current_task_id": "P2-402A",
|
||||
"next_task_id": "P2-402B",
|
||||
"read_only_mode": True,
|
||||
"runtime_authority": "contract_only_no_version_or_runtime_update",
|
||||
},
|
||||
"delegation_model": {
|
||||
"autonomy_levels": [],
|
||||
"agent_responsibilities": [],
|
||||
"telegram_policy": {},
|
||||
},
|
||||
"version_lifecycle_domains": [
|
||||
{
|
||||
"domain_id": "python_packages",
|
||||
"display_name": "Python",
|
||||
"primary_owner": "hermes",
|
||||
"cadence": "daily",
|
||||
"current_allowed_autonomy": "L2_approval_package_only",
|
||||
"update_authority": "dependency approval",
|
||||
"approval_gate": "dependency_approval_required",
|
||||
}
|
||||
],
|
||||
"delegable_capabilities": [
|
||||
{
|
||||
"capability_id": "version_discovery_freshness",
|
||||
"display_name": "版本發現",
|
||||
"primary_owner": "hermes",
|
||||
"risk_tier": "low",
|
||||
"automation_level": "L1_report_only",
|
||||
"outputs": ["report"],
|
||||
"approval_gate": "read_only_allowed",
|
||||
"telegram_policy": "failure_only",
|
||||
}
|
||||
],
|
||||
"cadence_matrix": [
|
||||
{
|
||||
"cadence_id": "daily_repo_only",
|
||||
"frequency": "daily",
|
||||
"scope": "repo",
|
||||
"allowed_now": True,
|
||||
"next_gate": "none",
|
||||
},
|
||||
{
|
||||
"cadence_id": "weekly_external_primary_sources",
|
||||
"frequency": "weekly",
|
||||
"scope": "external",
|
||||
"allowed_now": False,
|
||||
"next_gate": "approval",
|
||||
},
|
||||
],
|
||||
"mcp_tool_requirements": [
|
||||
{
|
||||
"tool_id": "gitea_release_pr_mcp",
|
||||
"display_name": "Gitea",
|
||||
"purpose": "測試。",
|
||||
"owner_agent": "hermes",
|
||||
"status": "planned",
|
||||
"approval_gate": "write_requires_human_gate",
|
||||
}
|
||||
],
|
||||
"rag_memory_contract": [
|
||||
{
|
||||
"memory_id": "version_history",
|
||||
"display_name": "Version",
|
||||
"storage": "PostgreSQL",
|
||||
"owner_agent": "hermes",
|
||||
"purpose": "測試。",
|
||||
"redaction_policy": "no secrets",
|
||||
}
|
||||
],
|
||||
"rollout_tasks": [
|
||||
{
|
||||
"task_id": "P2-402A",
|
||||
"priority": "P2",
|
||||
"status": "done",
|
||||
"completion_percent": 100,
|
||||
"owner_agent": "Hermes",
|
||||
"summary": "測試。",
|
||||
"next_gate": "deploy",
|
||||
}
|
||||
],
|
||||
"approval_boundaries": {
|
||||
"runtime_version_update_allowed": False,
|
||||
"package_upgrade_allowed": False,
|
||||
"host_upgrade_allowed": False,
|
||||
"container_pull_allowed": False,
|
||||
"workflow_schedule_enabled": False,
|
||||
"auto_merge_allowed": False,
|
||||
"telegram_direct_send_allowed": False,
|
||||
"secret_plaintext_allowed": False,
|
||||
"paid_external_service_allowed": False,
|
||||
"production_route_change_allowed": False,
|
||||
},
|
||||
"rollups": {
|
||||
"version_domain_count": 1,
|
||||
"delegable_capability_count": 1,
|
||||
"cadence_count": 2,
|
||||
"mcp_tool_count": 1,
|
||||
"rag_memory_count": 1,
|
||||
"rollout_task_count": 1,
|
||||
"auto_execute_allowed_count": 0,
|
||||
"approval_required_capability_count": 1,
|
||||
"blocked_update_domain_ids": ["python_packages"],
|
||||
"telegram_action_required_capability_ids": [],
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from src.api.v1.agents import router
|
||||
|
||||
|
||||
def test_ai_agent_proactive_operations_contract_endpoint_returns_committed_snapshot():
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
client = TestClient(app)
|
||||
|
||||
response = client.get("/api/v1/agents/agent-proactive-operations-contract")
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["schema_version"] == "ai_agent_proactive_operations_contract_v1"
|
||||
assert data["program_status"]["overall_completion_percent"] == 30
|
||||
assert data["program_status"]["current_task_id"] == "P2-402A"
|
||||
assert data["program_status"]["next_task_id"] == "P2-402B"
|
||||
assert data["program_status"]["read_only_mode"] is True
|
||||
assert data["approval_boundaries"]["runtime_version_update_allowed"] is False
|
||||
assert data["approval_boundaries"]["package_upgrade_allowed"] is False
|
||||
assert data["approval_boundaries"]["workflow_schedule_enabled"] is False
|
||||
assert data["approval_boundaries"]["telegram_direct_send_allowed"] is False
|
||||
assert data["rollups"]["version_domain_count"] == 12
|
||||
assert data["rollups"]["delegable_capability_count"] == 24
|
||||
assert data["rollups"]["auto_execute_allowed_count"] == 0
|
||||
assert any(domain["domain_id"] == "host_os_packages" for domain in data["version_lifecycle_domains"])
|
||||
assert any(
|
||||
capability["capability_id"] == "market_watch_and_candidate_intake"
|
||||
for capability in data["delegable_capabilities"]
|
||||
)
|
||||
Reference in New Issue
Block a user