Files
awoooi/apps/api/src/services/portfolio_infrastructure_asset_reconciliation.py
ogt 4af6487ba6
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 2s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m31s
CD Pipeline / build-and-deploy (push) Successful in 15m18s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 22s
CD Pipeline / post-deploy-checks (push) Successful in 5m35s
fix(alerting): align Alertmanager metric schema
2026-07-16 18:01:47 +08:00

315 lines
13 KiB
Python

"""Portfolio-wide infrastructure inventory reconciliation.
The committed snapshot deliberately separates an imported inventory claim from
current source truth and production runtime truth. Group defaults keep the
snapshot reviewable; this loader expands every member into a complete asset
record and validates the fixed typed-executor contract.
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from src.services.snapshot_paths import default_operations_dir
_DEFAULT_OPERATIONS_DIR = default_operations_dir(Path(__file__))
_SNAPSHOT_FILE = "portfolio-infrastructure-asset-reconciliation.snapshot.json"
_SCHEMA_VERSION = "portfolio_infrastructure_asset_reconciliation_v1"
_PROGRAM_ID = "AIA-SRE-P0-20260715"
_ALLOWED_DOMAINS = {
"kubernetes_workload",
"host_systemd",
"docker_container",
"windows_vmware",
"database",
"backup_restore",
"control_plane_recovery",
"ai_provider",
"control_plane_service",
"unknown",
}
_EXPECTED_EXECUTORS = {
"kubernetes_workload": "kubernetes_controlled_executor",
"host_systemd": "host_ansible_executor",
"docker_container": "host_ansible_executor_with_exact_container_playbook",
"windows_vmware": "Agent99",
"database": "db_bounded_executor",
"backup_restore": "backup_restore_break_glass",
"control_plane_recovery": "Agent99",
"ai_provider": "deterministic_provider_router",
"control_plane_service": "single_control_plane_executor",
"unknown": None,
}
_REQUIRED_ASSET_FIELDS = {
"canonical_id",
"inventory_labels",
"source_rows",
"category",
"product_id",
"project_id",
"site_id",
"owner_lane",
"runtime_identity",
"source_truth_state",
"live_truth_state",
"reconciliation_state",
"findings",
"source_refs",
"domain_router",
"executor",
"verifier",
"monitoring",
"alerting",
"telegram_destination",
"backup_restore",
"learning_targets",
"priority",
"dependencies",
"next_action",
}
_LEARNING_TARGETS = ["KM", "RAG", "MCP", "PlayBook"]
_PUBLIC_RUNTIME_IDENTITY_ALIASES = {
"ai-provider:ollama_gcp_a": "provider:GCP-A/Ollama",
"ai-provider:ollama_gcp_b": "provider:GCP-B/Ollama",
}
def load_portfolio_infrastructure_asset_reconciliation(
operations_dir: Path | None = None,
) -> dict[str, Any]:
"""Load, expand, and validate the portfolio inventory reconciliation."""
directory = operations_dir or _DEFAULT_OPERATIONS_DIR
path = directory / _SNAPSHOT_FILE
with path.open(encoding="utf-8") as handle:
payload = json.load(handle)
if not isinstance(payload, dict):
raise ValueError(f"{path}: expected JSON object")
if payload.get("schema_version") != _SCHEMA_VERSION:
raise ValueError(f"{path}: unexpected schema_version")
if payload.get("program_id") != _PROGRAM_ID:
raise ValueError(f"{path}: unexpected program_id")
source = _dict(payload.get("source_inventory"), "source_inventory", path)
if source.get("live_truth_accepted") is not False:
raise ValueError(f"{path}: imported health claims cannot be live truth")
if source.get("runtime_probe_performed") is not False:
raise ValueError(f"{path}: snapshot must not claim an unrecorded live probe")
category_counts = _dict(
source.get("source_category_counts"), "source_category_counts", path
)
if sum(category_counts.values()) != source.get("inventory_item_row_count"):
raise ValueError(f"{path}: source category counts do not cover imported rows")
governance = _dict(payload.get("governance"), "governance", path)
if governance.get("github_frozen") is not True:
raise ValueError(f"{path}: GitHub freeze must remain active")
if governance.get("cross_domain_fallback_allowed") is not False:
raise ValueError(f"{path}: cross-domain fallback must remain forbidden")
if governance.get("unknown_asset_terminal") != "asset_identity_unresolved":
raise ValueError(f"{path}: unknown assets must fail closed")
assets = _expand_assets(payload, path)
canonical_ids = [str(asset["canonical_id"]) for asset in assets]
if len(canonical_ids) != len(set(canonical_ids)):
raise ValueError(f"{path}: duplicate canonical asset id")
mapped_rows: list[str] = []
omission_count = 0
for asset in assets:
_validate_asset(asset, path)
rows = asset["source_rows"]
mapped_rows.extend(rows)
if asset["reconciliation_state"] == "missing_from_imported_inventory":
omission_count += 1
if rows:
raise ValueError(f"{path}: omitted asset cannot claim source rows")
if len(mapped_rows) != len(set(mapped_rows)):
raise ValueError(f"{path}: imported source row mapped more than once")
if len(mapped_rows) != source.get("inventory_item_row_count"):
raise ValueError(f"{path}: imported inventory row coverage mismatch")
work_items = _list(payload.get("reconciliation_work_items"), "work_items", path)
known_work_ids = {str(item.get("id") or "") for item in work_items}
if "" in known_work_ids or len(known_work_ids) != len(work_items):
raise ValueError(f"{path}: work item ids must be unique and non-empty")
expected_order = list(range(1, len(work_items) + 1))
if [item.get("order") for item in work_items] != expected_order:
raise ValueError(f"{path}: work item order must be contiguous")
priorities = [item.get("priority") for item in work_items]
if any(priority not in {"P0", "P1"} for priority in priorities):
raise ValueError(f"{path}: work item priority must be P0 or P1")
first_p1 = priorities.index("P1") if "P1" in priorities else len(priorities)
if "P0" in priorities[first_p1:]:
raise ValueError(f"{path}: P0 work must precede P1 work")
for item in work_items:
unknown = set(item.get("dependencies") or []) - known_work_ids
if unknown:
raise ValueError(f"{path}: {item['id']} has unknown dependencies")
rollups = _dict(payload.get("rollups"), "rollups", path)
if rollups.get("imported_item_rows") != len(mapped_rows):
raise ValueError(f"{path}: rollup imported row mismatch")
if rollups.get("canonical_assets") != len(assets):
raise ValueError(f"{path}: rollup canonical asset mismatch")
if rollups.get("inventory_omissions") != omission_count:
raise ValueError(f"{path}: rollup omission mismatch")
conflicts = _list(payload.get("conflict_register"), "conflict_register", path)
if rollups.get("conflicts") != len(conflicts):
raise ValueError(f"{path}: rollup conflict mismatch")
conflict_assets = {
str(canonical_id)
for conflict in conflicts
for canonical_id in (conflict.get("assets") or [])
if canonical_id != "all-imported-assets"
}
unknown_conflict_assets = conflict_assets - set(canonical_ids)
if unknown_conflict_assets:
raise ValueError(f"{path}: conflict register references unknown assets")
if rollups.get("conflict_assets") != len(conflict_assets):
raise ValueError(f"{path}: rollup conflict asset mismatch")
source_reconciled_assets = sum(
asset.get("source_truth_state") == "source_reconciled_runtime_pending"
for asset in assets
)
if rollups.get("source_reconciled_assets") != source_reconciled_assets:
raise ValueError(f"{path}: rollup source-reconciled asset mismatch")
if rollups.get("reconciliation_work_items") != len(work_items):
raise ValueError(f"{path}: rollup work item mismatch")
runtime_closed_assets: list[dict[str, Any]] = []
for asset in assets:
runtime_closure = asset.get("runtime_closure")
if runtime_closure is None:
continue
if not isinstance(runtime_closure, dict):
raise ValueError(f"{path}: {asset['canonical_id']} invalid runtime closure")
if runtime_closure.get("status") not in {
"verified_absent",
"verified_healthy",
}:
continue
required_receipt_fields = {
"trace_id",
"run_id",
"work_item_id",
"post_verifier",
}
missing_receipts = sorted(
key
for key in required_receipt_fields
if not str(runtime_closure.get(key) or "").strip()
)
if missing_receipts:
raise ValueError(
f"{path}: {asset['canonical_id']} runtime closure missing "
f"{missing_receipts}"
)
runtime_closed_assets.append(asset)
if rollups.get("runtime_closed_assets") != len(runtime_closed_assets):
raise ValueError(f"{path}: rollup runtime-closed asset mismatch")
expected_completion_percent = round(
len(runtime_closed_assets) * 100 / max(len(assets), 1)
)
if rollups.get("program_completion_percent") != expected_completion_percent:
raise ValueError(f"{path}: rollup program completion mismatch")
result = dict(payload)
result["assets"] = assets
return result
def build_portfolio_infrastructure_public_projection(
payload: dict[str, Any],
) -> dict[str, Any]:
"""Return the complete management projection without local paths/raw endpoints.
The expanded ``assets`` list is the canonical public shape. ``asset_groups``
is removed because it duplicates the same records and still contains the
imported topology strings before endpoint redaction.
"""
projection = dict(payload)
projection.pop("asset_groups", None)
source_inventory = dict(projection["source_inventory"])
source_inventory["source_path"] = (
"external_inventory:infrastructure_inventory.md"
)
projection["source_inventory"] = source_inventory
assets: list[dict[str, Any]] = []
for raw_asset in projection["assets"]:
asset = dict(raw_asset)
public_identity = _PUBLIC_RUNTIME_IDENTITY_ALIASES.get(
str(asset["canonical_id"])
)
if public_identity:
asset["runtime_identity"] = public_identity
assets.append(asset)
projection["assets"] = assets
projection["public_projection"] = {
"topology_redacted": True,
"source_path_redacted": True,
"expanded_assets_authoritative": True,
}
return projection
def _expand_assets(payload: dict[str, Any], path: Path) -> list[dict[str, Any]]:
groups = _list(payload.get("asset_groups"), "asset_groups", path)
expanded: list[dict[str, Any]] = []
for group_index, group in enumerate(groups):
if not isinstance(group, dict):
raise ValueError(f"{path}: asset_groups[{group_index}] must be an object")
common = _dict(group.get("common"), "asset_group.common", path)
category = str(group.get("category") or "")
group_id = str(group.get("group_id") or "")
if not category or not group_id:
raise ValueError(f"{path}: every asset group requires id/category")
for member in _list(group.get("members"), "asset_group.members", path):
if not isinstance(member, dict):
raise ValueError(f"{path}: asset member must be an object")
asset = dict(common)
asset.update(member)
asset["category"] = category
asset["group_id"] = group_id
expanded.append(asset)
return expanded
def _validate_asset(asset: dict[str, Any], path: Path) -> None:
missing = sorted(_REQUIRED_ASSET_FIELDS - asset.keys())
if missing:
raise ValueError(f"{path}: {asset.get('canonical_id')} missing {missing}")
domain = str(asset.get("domain_router") or "")
if domain not in _ALLOWED_DOMAINS:
raise ValueError(f"{path}: {asset['canonical_id']} has invalid domain")
if asset.get("executor") != _EXPECTED_EXECUTORS[domain]:
raise ValueError(f"{path}: {asset['canonical_id']} executor/domain mismatch")
if asset.get("learning_targets") != _LEARNING_TARGETS:
raise ValueError(f"{path}: {asset['canonical_id']} learning targets incomplete")
if asset.get("live_truth_state") == "verified_healthy":
raise ValueError(f"{path}: snapshot health cannot become live truth")
if asset.get("priority") not in {"P0", "P1", "P2"}:
raise ValueError(f"{path}: {asset['canonical_id']} priority invalid")
if not isinstance(asset.get("monitoring"), dict):
raise ValueError(f"{path}: {asset['canonical_id']} monitoring required")
if not isinstance(asset.get("alerting"), dict):
raise ValueError(f"{path}: {asset['canonical_id']} alerting required")
if not isinstance(asset.get("backup_restore"), dict):
raise ValueError(f"{path}: {asset['canonical_id']} backup contract required")
if domain == "unknown" and asset.get("executor") is not None:
raise ValueError(f"{path}: unknown asset must not have executor")
def _dict(value: Any, label: str, path: Path) -> dict[str, Any]:
if not isinstance(value, dict):
raise ValueError(f"{path}: {label} must be an object")
return value
def _list(value: Any, label: str, path: Path) -> list[Any]:
if not isinstance(value, list):
raise ValueError(f"{path}: {label} must be an array")
return value