"""Tests for CAP-025 (live-pilot-apply pipeline readiness) — P3 W5, REQ-316. CAP-025 is a LOCAL-tier structural-readiness check: the pilot-apply pipeline (contract resolve -> adapter compile -> terraform plan -> policy scan -> confidence signal -> terraform apply -> outbox) must be wired and all its dependencies present. The live apply against AWS is P4's live-verify; P3 only asserts the pipeline is structurally ready. """ import json import sys from pathlib import Path import pytest ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT)) import core.regression_verify as rv # noqa: E402 def test_cap_025_pipeline_ready(): """CAP-025: on the current branch (W2/W3/W4/W5 deps in place), the pilot-apply pipeline is structurally ready -> Verified.""" status, detail = rv._check_cap_025_live_pilot_apply() assert status == "Verified", f"CAP-025 {status}: {detail}" def test_cap_025_in_registry(): """CAP-025 is in the seeded CAPABILITY_REGISTRY.""" cap_ids = [entry[0] for entry in rv.CAPABILITY_REGISTRY] assert "CAP-025" in cap_ids # the entry's check fn must be the one we wrote cap_025 = [e for e in rv.CAPABILITY_REGISTRY if e[0] == "CAP-025"][0] assert cap_025[2] == "local" # tier assert cap_025[3] is rv._check_cap_025_live_pilot_apply def test_cap_025_detects_missing_primitive(tmp_path, monkeypatch): """CAP-025 detects an absent DynamoDB L1 primitive (REQ-322): if the modules/registry.json lacks a `dynamodb` entry, the check returns Broken (not Verified). Uses monkeypatch to redirect the registry path to a tmp copy without the dynamodb key.""" # Snapshot the real registry so we can restore after the check runs. real_registry = ROOT / "modules" / "registry.json" real_data = json.loads(real_registry.read_text()) # Build a fake registry without `dynamodb`. fake_data = {k: v for k, v in real_data.items() if k != "dynamodb"} assert "dynamodb" not in fake_data, "test setup: dynamodb must be removed" fake_registry = tmp_path / "registry.json" fake_registry.write_text(json.dumps(fake_data)) # Point ROOT at a tmp dir that mirrors only the files the check reads # after the registry step. The check reads (in order): # scripts/run_platform.sh, core.contract_resolver, adapters.terraform.adapter, # core.confidence_signal, core.outbox_writer, core/environments/dev.json, # modules/registry.json, adapters/kyverno-json/policies/..., core/metrics/outcome_backfill.py # Simpler approach: monkeypatch the registry_path by inlining the check # logic against a fake ROOT. We re-run the check with a patched # `Path.read_text` scoped to the registry file via monkeypatch. original_read_text = Path.read_text def fake_read_text(self, *args, **kwargs): if self == real_registry: return json.dumps(fake_data) return original_read_text(self, *args, **kwargs) monkeypatch.setattr(Path, "read_text", fake_read_text) status, detail = rv._check_cap_025_live_pilot_apply() assert status == "Broken", f"expected Broken for missing dynamodb, got {status}: {detail}" assert "dynamodb" in detail assert "REQ-322" in detail