#!/usr/bin/env python3 from __future__ import annotations import argparse import json import re from pathlib import Path from typing import Any from common import DeployError, load_env_file RUN_ID_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$") SHA_RE = re.compile(r"^[0-9a-f]{40}$") TEST_SLOT_RE = re.compile(r"^test([1-9][0-9]*)$") STAGING_SLOT_RE = re.compile(r"^(blue|green)$") def require_regular_file(path: Path, subject: str, *, private: bool = False) -> None: if path.is_symlink() or not path.is_file(): raise DeployError(f"{subject} must be a regular non-symlink file: {path}") if private and path.stat().st_mode & 0o077: raise DeployError(f"{subject} must not be group/world accessible: {path}") def load_json_object(path: Path, subject: str) -> dict[str, Any]: require_regular_file(path, subject, private=True) try: value = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError) as exc: raise DeployError(f"{subject} is unreadable: {path}") from exc if not isinstance(value, dict): raise DeployError(f"{subject} must contain one JSON object: {path}") return value def resolve_active_d3_runtime_truth(base_env_file: Path) -> dict[str, str]: """Resolve the active microservice Runtime's private environment authority. The environment-level runtime.env remains the database/control-plane binding. Storage behavior belongs to the currently serving Runtime process, so callers must not infer it from that older environment-level file. """ base_env_file = base_env_file.expanduser() require_regular_file(base_env_file, "environment runtime authority") base_env_file = base_env_file.resolve() envv = load_env_file(base_env_file) env_name = str(envv.get("ENV_NAME") or "").strip() env_root_raw = str(envv.get("ENV_ROOT") or "").strip() if not env_name or not env_root_raw: raise DeployError("environment runtime authority is missing ENV_NAME or ENV_ROOT") env_root = Path(env_root_raw).expanduser().resolve() expected_base_env_file = env_root / "env" / "runtime.env" if base_env_file != expected_base_env_file: raise DeployError( "environment runtime authority is not the canonical ENV_ROOT runtime.env" ) is_test_slot = ( TEST_SLOT_RE.fullmatch(env_root.name) is not None and env_name == f"test-{env_root.name}" ) is_staging_slot = ( STAGING_SLOT_RE.fullmatch(env_root.name) is not None and env_root.parent.name == "staging" and env_name == f"staging-{env_root.name}" ) if not is_test_slot and not is_staging_slot: raise DeployError( "environment runtime authority ENV_NAME does not match its Test or Staging slot" ) state_root = env_root / ".runtime" / "serviceification-d3" state_file = state_root / "active.json" state = load_json_object(state_file, "active D3 state") run_id = str(state.get("runId") or "").strip() if not RUN_ID_RE.fullmatch(run_id): raise DeployError("active D3 state has no canonical runId") run_root = (state_root / "runs" / run_id).resolve() if ( state.get("envName") != env_name or state.get("envRoot") != str(env_root) or state.get("runRoot") != str(run_root) ): raise DeployError("active D3 state does not belong to the selected environment") if state.get("phase") != "serving": raise DeployError("active D3 state is not serving") evidence = state.get("deploymentEvidence") if ( not isinstance(evidence, dict) or evidence.get("stage") != "serving-verified" or evidence.get("runId") != run_id ): raise DeployError("active D3 state has no serving-verified evidence") exact_sources = state.get("exactSources") l2_commit = ( str(exact_sources.get("l2Commit") or "").strip() if isinstance(exact_sources, dict) else "" ) if not SHA_RE.fullmatch(l2_commit): raise DeployError("active D3 state has no immutable L2 metadata commit") artifacts = state.get("servingArtifacts") runtime_env_raw = ( str(artifacts.get("runtimeEnv") or "").strip() if isinstance(artifacts, dict) else "" ) runtime_env_file = Path(runtime_env_raw).expanduser() expected_runtime_env = run_root / "private" / "runtime.env" if runtime_env_file != expected_runtime_env: raise DeployError("active D3 Runtime authority is outside its sealed run root") require_regular_file(runtime_env_file, "active D3 Runtime authority", private=True) return { "schema": "nexuscrm.active-d3-runtime-truth/v1", "env_name": env_name, "run_id": run_id, "run_root": str(run_root), "runtime_env_file": str(runtime_env_file.resolve()), "l2_metadata_commit": l2_commit, "desired_bom_digest": str(state.get("desiredBomDigest") or ""), } def main() -> int: parser = argparse.ArgumentParser( description="Resolve the serving-verified D3 Runtime authority" ) parser.add_argument("--env-file", required=True) parser.add_argument("--summary-json") args = parser.parse_args() truth = resolve_active_d3_runtime_truth(Path(args.env_file)) serialized = json.dumps(truth, sort_keys=True, indent=2) + "\n" if args.summary_json: summary_path = Path(args.summary_json) summary_path.parent.mkdir(parents=True, exist_ok=True) summary_path.write_text(serialized, encoding="utf-8") print(serialized, end="") return 0 if __name__ == "__main__": raise SystemExit(main())