feat(governance): add AI agent version lifecycle proposals
Some checks failed
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
Some checks failed
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.ai_agent_version_lifecycle_update_proposal import (
|
||||
load_latest_ai_agent_version_lifecycle_update_proposal,
|
||||
)
|
||||
|
||||
|
||||
def test_load_latest_ai_agent_version_lifecycle_update_proposal_reads_committed_snapshot():
|
||||
data = load_latest_ai_agent_version_lifecycle_update_proposal()
|
||||
|
||||
assert data["schema_version"] == "ai_agent_version_lifecycle_update_proposal_v1"
|
||||
assert data["program_status"]["overall_completion_percent"] == 78
|
||||
assert data["program_status"]["current_task_id"] == "P2-413"
|
||||
assert data["program_status"]["next_task_id"] == "P2-414"
|
||||
assert data["program_status"]["read_only_mode"] is True
|
||||
assert data["program_status"]["runtime_authority"] == (
|
||||
"version_lifecycle_update_proposal_only_no_write_or_upgrade"
|
||||
)
|
||||
assert data["runtime_boundaries"]["read_only_update_proposal_allowed"] is True
|
||||
assert data["runtime_boundaries"]["package_upgrade_allowed"] is False
|
||||
assert data["runtime_boundaries"]["host_upgrade_allowed"] is False
|
||||
assert data["runtime_boundaries"]["k3s_upgrade_allowed"] is False
|
||||
assert data["runtime_boundaries"]["telegram_direct_send_allowed"] is False
|
||||
assert data["runtime_boundaries"]["production_write_allowed"] is False
|
||||
assert data["runtime_boundaries"]["openclaw_replacement_allowed"] is False
|
||||
assert data["telegram_digest_contract"]["direct_send_allowed"] is False
|
||||
assert data["telegram_digest_contract"]["gateway_queue_write_allowed"] is False
|
||||
assert data["telegram_digest_contract"]["bot_api_call_allowed"] is False
|
||||
assert data["rollups"]["domain_count"] == len(data["lifecycle_domains"]) == 12
|
||||
assert data["rollups"]["proposal_count"] == len(data["update_proposals"]) == 12
|
||||
assert data["rollups"]["cadence_count"] == len(data["cadence_matrix"]) == 6
|
||||
assert data["rollups"]["approval_gate_count"] == len(data["approval_gate_matrix"]) == 9
|
||||
assert data["rollups"]["false_runtime_boundary_count"] == 29
|
||||
assert data["rollups"]["auto_execution_allowed_count"] == 0
|
||||
assert data["rollups"]["telegram_direct_send_count"] == 0
|
||||
assert data["rollups"]["production_write_count"] == 0
|
||||
assert data["rollups"]["update_allowed_count"] == 0
|
||||
assert any(
|
||||
proposal["proposal_id"] == "openclaw_challenger_replay_bench"
|
||||
for proposal in data["update_proposals"]
|
||||
)
|
||||
assert all(proposal["requires_owner_approval"] is True for proposal in data["update_proposals"])
|
||||
assert all(proposal["direct_update_allowed"] is False for proposal in data["update_proposals"])
|
||||
|
||||
|
||||
def test_ai_agent_version_lifecycle_update_proposal_rejects_runtime_upgrade(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["runtime_boundaries"]["package_upgrade_allowed"] = True
|
||||
_write_snapshot(tmp_path, snapshot)
|
||||
|
||||
with pytest.raises(ValueError, match="runtime boundaries"):
|
||||
load_latest_ai_agent_version_lifecycle_update_proposal(tmp_path)
|
||||
|
||||
|
||||
def test_ai_agent_version_lifecycle_update_proposal_rejects_rollup_mismatch(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["rollups"]["proposal_count"] = 99
|
||||
_write_snapshot(tmp_path, snapshot)
|
||||
|
||||
with pytest.raises(ValueError, match="rollup counts"):
|
||||
load_latest_ai_agent_version_lifecycle_update_proposal(tmp_path)
|
||||
|
||||
|
||||
def test_ai_agent_version_lifecycle_update_proposal_rejects_direct_update(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["update_proposals"][0]["direct_update_allowed"] = True
|
||||
snapshot["rollups"]["read_only_proposal_count"] = 11
|
||||
_write_snapshot(tmp_path, snapshot)
|
||||
|
||||
with pytest.raises(ValueError, match="direct update"):
|
||||
load_latest_ai_agent_version_lifecycle_update_proposal(tmp_path)
|
||||
|
||||
|
||||
def test_ai_agent_version_lifecycle_update_proposal_rejects_missing_evidence(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["update_proposals"][0]["evidence_refs"] = []
|
||||
_write_snapshot(tmp_path, snapshot)
|
||||
|
||||
with pytest.raises(ValueError, match="evidence_refs"):
|
||||
load_latest_ai_agent_version_lifecycle_update_proposal(tmp_path)
|
||||
|
||||
|
||||
def test_ai_agent_version_lifecycle_update_proposal_rejects_work_window_markers(tmp_path):
|
||||
snapshot = _snapshot()
|
||||
snapshot["program_status"]["status_note"] = "不可放入 My request for Codex"
|
||||
_write_snapshot(tmp_path, snapshot)
|
||||
|
||||
with pytest.raises(ValueError, match="forbidden work-window conversation content"):
|
||||
load_latest_ai_agent_version_lifecycle_update_proposal(tmp_path)
|
||||
|
||||
|
||||
def _write_snapshot(tmp_path, snapshot: dict) -> None:
|
||||
(tmp_path / "ai_agent_version_lifecycle_update_proposal_2026-06-26.json").write_text(
|
||||
json.dumps(snapshot),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def _snapshot() -> dict:
|
||||
return json.loads(json.dumps(load_latest_ai_agent_version_lifecycle_update_proposal()))
|
||||
@@ -0,0 +1,37 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from src.api.v1.agents import router
|
||||
|
||||
|
||||
def test_ai_agent_version_lifecycle_update_proposal_endpoint_returns_committed_snapshot():
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
client = TestClient(app)
|
||||
|
||||
response = client.get("/api/v1/agents/agent-version-lifecycle-update-proposal")
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["schema_version"] == "ai_agent_version_lifecycle_update_proposal_v1"
|
||||
assert data["program_status"]["overall_completion_percent"] == 78
|
||||
assert data["program_status"]["current_task_id"] == "P2-413"
|
||||
assert data["program_status"]["next_task_id"] == "P2-414"
|
||||
assert data["program_status"]["read_only_mode"] is True
|
||||
assert data["runtime_boundaries"]["package_upgrade_allowed"] is False
|
||||
assert data["runtime_boundaries"]["k3s_upgrade_allowed"] is False
|
||||
assert data["runtime_boundaries"]["telegram_direct_send_allowed"] is False
|
||||
assert data["runtime_boundaries"]["production_write_allowed"] is False
|
||||
assert data["runtime_boundaries"]["openclaw_replacement_allowed"] is False
|
||||
assert data["rollups"]["domain_count"] == 12
|
||||
assert data["rollups"]["proposal_count"] == 12
|
||||
assert data["rollups"]["approval_required_count"] == 12
|
||||
assert data["rollups"]["auto_execution_allowed_count"] == 0
|
||||
assert data["rollups"]["telegram_direct_send_count"] == 0
|
||||
assert data["rollups"]["production_write_count"] == 0
|
||||
assert any(
|
||||
proposal["proposal_id"] == "telegram_bot_gateway_policy_refresh"
|
||||
for proposal in data["update_proposals"]
|
||||
)
|
||||
Reference in New Issue
Block a user