from __future__ import annotations import json import pytest from src.services.runtime_surface_inventory import load_latest_runtime_surface_inventory def test_load_latest_runtime_surface_inventory_reads_newest_file(tmp_path): older = _snapshot(generated_at="2026-06-04T00:00:00+08:00", completion=40) newer = _snapshot(generated_at="2026-06-05T00:00:00+08:00", completion=100) (tmp_path / "runtime_surface_inventory_2026-06-04.json").write_text( json.dumps(older), encoding="utf-8", ) (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text( json.dumps(newer), encoding="utf-8", ) loaded = load_latest_runtime_surface_inventory(tmp_path) assert loaded["generated_at"] == "2026-06-05T00:00:00+08:00" assert loaded["program_status"]["overall_completion_percent"] == 100 assert loaded["rollups"]["total_surfaces"] == 3 assert loaded["operation_boundaries"]["kubectl_allowed"] is False def test_runtime_surface_inventory_requires_read_only_mode(tmp_path): snapshot = _snapshot() snapshot["program_status"]["read_only_mode"] = False (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text( json.dumps(snapshot), encoding="utf-8", ) with pytest.raises(ValueError, match="read_only_mode"): load_latest_runtime_surface_inventory(tmp_path) def test_runtime_surface_inventory_requires_blocked_operations(tmp_path): snapshot = _snapshot() snapshot["operation_boundaries"]["kubectl_allowed"] = True (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text( json.dumps(snapshot), encoding="utf-8", ) with pytest.raises(ValueError, match="operation boundaries"): load_latest_runtime_surface_inventory(tmp_path) def test_runtime_surface_inventory_requires_rollup_consistency(tmp_path): snapshot = _snapshot() snapshot["rollups"]["by_kind"]["deployment"] = 99 (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text( json.dumps(snapshot), encoding="utf-8", ) with pytest.raises(ValueError, match="by_kind"): load_latest_runtime_surface_inventory(tmp_path) def test_runtime_surface_inventory_requires_secret_redaction(tmp_path): snapshot = _snapshot() snapshot["runtime_surfaces"][2]["secret_exposure"] = "none" (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text( json.dumps(snapshot), encoding="utf-8", ) with pytest.raises(ValueError, match="secret surfaces"): load_latest_runtime_surface_inventory(tmp_path) def test_runtime_surface_inventory_requires_operator_denials(tmp_path): snapshot = _snapshot() snapshot["operator_contract"]["must_not_interpret_as"] = ["runtime 執行授權"] (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text( json.dumps(snapshot), encoding="utf-8", ) with pytest.raises(ValueError, match="must_not_interpret_as"): load_latest_runtime_surface_inventory(tmp_path) def test_runtime_surface_inventory_fails_when_missing(tmp_path): with pytest.raises(FileNotFoundError): load_latest_runtime_surface_inventory(tmp_path) def _snapshot( *, generated_at: str = "2026-06-05T00:00:00+08:00", completion: int = 100, ) -> dict: return { "schema_version": "runtime_surface_inventory_v1", "generated_at": generated_at, "program_status": { "overall_completion_percent": completion, "current_priority": "P1", "current_task_id": "P1-001", "next_task_id": "P1-002", "read_only_mode": True, }, "source_refs": ["k8s/awoooi-prod/"], "rollups": { "total_surfaces": 3, "by_kind": {"deployment": 1, "ingress": 1, "secret": 1}, "by_status": {"manifest_mapped": 1, "action_required": 2}, "by_evidence_level": { "committed_manifest": 1, "missing_manifest": 1, "live_check_required": 1, }, "action_required_surface_ids": ["external_nginx_gateway_route", "awoooi_secrets"], "secret_surface_ids": ["awoooi_secrets"], "live_check_missing_surface_ids": ["external_nginx_gateway_route", "awoooi_secrets"], "total_source_components": 1, "source_components_with_runtime_binding": 1, }, "runtime_surfaces": [ _surface( "awoooi_api_deployment", "deployment", "manifest_mapped", "committed_manifest", "none", "not_run", ), _surface( "external_nginx_gateway_route", "ingress", "action_required", "missing_manifest", "none", "required", ), _surface( "awoooi_secrets", "secret", "action_required", "live_check_required", "template_only", "required", ), ], "source_runtime_components": [ { "component_id": "api_fastapi_app", "display_name": "FastAPI app", "source_ref": "apps/api/src/main.py", "component_kind": "api_process", "runtime_binding": "Deployment/awoooi-api", "status": "bound", "next_action": "只讀確認。", } ], "evidence_gaps": [ { "gap_id": "external_gateway_manifest_gap", "severity": "high", "status": "action_required", "summary": "缺外部 gateway manifest。", "evidence_refs": ["k8s/awoooi-prod/"], "next_action": "只讀補證據。", } ], "operator_contract": { "display_mode": "read_only_runtime_surface", "must_not_interpret_as": [ "runtime 執行授權", "rollout / restart / scale / delete 批准", "Secret 已驗證或可讀取", "Ingress / DNS 可修改", ], "secret_display_policy": "只顯示 redacted metadata。", }, "operation_boundaries": { "read_only_api_allowed": True, "live_k8s_query_allowed": False, "kubectl_allowed": False, "rollout_allowed": False, "restart_allowed": False, "scale_allowed": False, "delete_allowed": False, "secret_read_allowed": False, "secret_plaintext_allowed": False, "active_scan_allowed": False, "production_route_change_allowed": False, }, "approval_boundaries": { "sdk_installation_allowed": False, "paid_api_call_allowed": False, "shadow_or_canary_allowed": False, "production_routing_allowed": False, "destructive_operation_allowed": False, }, } def _surface( surface_id: str, kind: str, status: str, evidence_level: str, secret_exposure: str, live_check_status: str, ) -> dict: return { "surface_id": surface_id, "display_name": surface_id, "kind": kind, "manifest_ref": "k8s/awoooi-prod/example.yaml", "status": status, "risk_level": "high", "evidence_level": evidence_level, "runtime_binding": "example runtime binding", "health_contract": "example health contract", "secret_exposure": secret_exposure, "live_check_status": live_check_status, "evidence_refs": ["k8s/awoooi-prod/example.yaml"], "next_action": "只讀確認。", }