#!/usr/bin/env python3
"""驗證 IwoooS 高價值配置控管 snapshot 維持只讀邊界。

本 guard 只讀取 repo 內已提交的 Markdown / JSON snapshot，不連線主機、不
SSH、不讀 secret、不執行 Nginx / K8s / workflow / runner / backup / scan
動作。它的用途是把 Nginx、TLS、K8s、Secrets、runner、防火牆、backup、
monitoring、public runtime 與 agent-bounty-protocol 等高價值配置，固定成
可重複驗證的資安控管基線。
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any


EXPECTED_CATEGORIES = {
    "nginx_public_gateway": 92,
    "dns_tls_certbot": 78,
    "k8s_production_gitops": 66,
    "secret_metadata": 70,
    "gitea_workflow_runner_source_control": 74,
    "public_admin_api_runtime_config": 66,
    "backup_restore_credential": 66,
    "agent_bounty_protocol_runtime": 68,
    "monitoring_alerting_observability": 78,
    "docker_compose_systemd_host_config": 68,
    "ssh_firewall_network_access": 70,
    "ai_provider_model_routing": 64,
    "product_surface_runtime_routes": 72,
    "security_evidence_tooling": 88,
}

REQUIRED_C0_CATEGORIES = {
    "nginx_public_gateway",
    "dns_tls_certbot",
    "k8s_production_gitops",
    "secret_metadata",
    "gitea_workflow_runner_source_control",
    "public_admin_api_runtime_config",
    "backup_restore_credential",
    "agent_bounty_protocol_runtime",
}

REQUIRED_CONTROL_DOCS = [
    "docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md",
    "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
    "docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md",
    "docs/security/PUBLIC-GATEWAY-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/PUBLIC-GATEWAY-RENDERED-DIFF-ACCEPTANCE.md",
    "docs/security/PUBLIC-GATEWAY-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/DOMAIN-TLS-CERTBOT-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/HOST-SERVICE-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/HOST-SERVICE-CHANGE-EVIDENCE-ACCEPTANCE.md",
    "docs/security/HOST-SERVICE-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/SSH-NETWORK-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/PORT-FIREWALL-CHANGE-EVIDENCE-ACCEPTANCE.md",
    "docs/security/SSH-NETWORK-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/BACKUP-RESTORE-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/BACKUP-RESTORE-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/K8S-ARGOCD-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/K8S-ARGOCD-CHANGE-EVIDENCE-ACCEPTANCE.md",
    "docs/security/K8S-ARGOCD-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/CD-RUNNER-SECRET-INJECTION-CHANGE-EVIDENCE-ACCEPTANCE.md",
    "docs/security/CD-RUNNER-SECRET-INJECTION-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/PUBLIC-RUNTIME-CONFIG-CHANGE-EVIDENCE-ACCEPTANCE.md",
    "docs/security/MONITORING-OWNER-REQUEST-DRAFT.md",
    "docs/security/MONITORING-POST-INCIDENT-READBACK-PLAN.md",
    "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md",
    "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md",
    "docs/security/SOC-SIEM-KALI-WAZUH-INTEGRATION-CONTROL.md",
    "docs/security/SECURITY-ASSET-CONTROL-LEDGER.md",
    "docs/security/AI-PROVIDER-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/AGENT-BOUNTY-OWNER-REQUEST-DRAFT.md",
    "docs/security/TELEGRAM-NOTIFICATION-EGRESS-NO-NEW-BYPASS-GUARD.md",
    "docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md",
    "docs/security/TELEGRAM-ALERT-READABILITY-GUARD.md",
    "docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md",
]

SUMMARY_ZERO_MARKERS = (
    "_authorized_count",
    "_executed_count",
    "_received_count",
    "_accepted_count",
    "_allowed_count",
    "_confirmed_count",
    "_quarantined_count",
    "_rejected_count",
    "_ready_count",
)

SUMMARY_ZERO_KEYS = {
    "action_button_count",
    "request_sent_count",
    "runtime_gate_count",
    "runtime_approval_package_ready_count",
    "supplement_requested_count",
    "impact_supplement_requested_count",
}

TRUE_BOUNDARY_KEYS = {"not_authorization"}

FALSE_BOUNDARY_KEYS = [
    "runtime_execution_authorized",
    "host_write_authorized",
    "nginx_reload_authorized",
    "public_gateway_reload_authorized",
    "certbot_renew_authorized",
    "argocd_sync_authorized",
    "kubectl_action_authorized",
    "workflow_modification_authorized",
    "runner_change_authorized",
    "secret_value_collection_allowed",
    "backup_run_authorized",
    "restore_run_authorized",
    "active_scan_authorized",
    "action_buttons_allowed",
]

ARTIFACT_SPECS = [
    {
        "label": "public gateway owner response acceptance",
        "path": "docs/security/public-gateway-owner-response-acceptance.snapshot.json",
        "schema": "public_gateway_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 3,
            "blocked_actions": 28,
            "reviewer_checks": 22,
            "outcome_lanes": 8,
            "required_owner_response_fields": 22,
        },
        "summary_counts": {
            "acceptance_candidate_count": 3,
            "c0_acceptance_candidate_count": 2,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "public gateway rendered diff acceptance",
        "path": "docs/security/public-gateway-rendered-diff-acceptance.snapshot.json",
        "schema": "public_gateway_rendered_diff_acceptance_v1",
        "status": "rendered_diff_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "blocked_actions": 22,
            "reviewer_checks": 15,
            "outcome_lanes": 8,
            "required_evidence_fields": 14,
        },
        "summary_counts": {
            "diff_acceptance_candidate_count": 3,
            "c0_diff_acceptance_candidate_count": 2,
            "rendered_diff_received_count": 0,
            "rendered_diff_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "public gateway post incident readback plan",
        "path": "docs/security/public-gateway-post-incident-readback-plan.snapshot.json",
        "schema": "public_gateway_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 3,
            "blocked_actions": 41,
            "reviewer_checks": 28,
            "outcome_lanes": 10,
            "required_readback_fields": 30,
        },
        "summary_counts": {
            "source_diff_acceptance_candidate_count": 3,
            "source_c0_diff_acceptance_candidate_count": 2,
            "source_c1_diff_acceptance_candidate_count": 1,
            "source_required_evidence_field_count": 14,
            "source_reviewer_check_count": 15,
            "source_blocked_action_count": 22,
            "source_rendered_diff_accepted_count": 0,
            "source_nginx_test_evidence_accepted_count": 0,
            "source_route_smoke_result_accepted_count": 0,
            "source_runtime_gate_count": 0,
            "readback_candidate_count": 3,
            "c0_readback_candidate_count": 2,
            "c1_readback_candidate_count": 1,
            "write_capable_readback_candidate_count": 3,
            "route_health_review_required_candidate_count": 3,
            "upstream_websocket_tls_review_required_candidate_count": 3,
            "ai_monitoring_cross_project_review_required_candidate_count": 3,
            "no_false_green_required_candidate_count": 3,
            "readback_field_count": 36,
            "required_readback_field_count": 30,
            "reviewer_check_count": 28,
            "outcome_lane_count": 10,
            "blocked_action_count": 41,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "actor_attribution_accepted_count": 0,
            "change_time_window_accepted_count": 0,
            "intent_or_break_glass_accepted_count": 0,
            "before_after_route_state_accepted_count": 0,
            "source_live_diff_state_accepted_count": 0,
            "nginx_test_readback_accepted_count": 0,
            "nginx_reload_or_no_reload_accepted_count": 0,
            "route_smoke_readback_accepted_count": 0,
            "tls_acme_readback_accepted_count": 0,
            "websocket_readback_accepted_count": 0,
            "upstream_health_accepted_count": 0,
            "public_admin_api_route_impact_accepted_count": 0,
            "ai_provider_impact_accepted_count": 0,
            "monitoring_alert_accepted_count": 0,
            "operator_notification_accepted_count": 0,
            "cross_project_sync_accepted_count": 0,
            "rollback_validation_accepted_count": 0,
            "post_change_monitoring_accepted_count": 0,
            "recovery_or_still_degraded_accepted_count": 0,
            "postcheck_readback_accepted_count": 0,
            "recurrence_guard_accepted_count": 0,
            "no_false_green_accepted_count": 0,
            "host_live_conf_read_authorized_count": 0,
            "nginx_test_authorized_count": 0,
            "nginx_test_executed_count": 0,
            "nginx_reload_authorized_count": 0,
            "nginx_reload_executed_count": 0,
            "public_gateway_reload_authorized_count": 0,
            "route_smoke_authorized_count": 0,
            "route_smoke_executed_count": 0,
            "dns_tls_probe_authorized_count": 0,
            "certbot_renew_authorized_count": 0,
            "public_route_change_authorized_count": 0,
            "admin_route_change_authorized_count": 0,
            "websocket_route_change_authorized_count": 0,
            "acme_challenge_change_authorized_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "coverage_percent_after_readback_plan": 92,
        },
    },
    {
        "label": "domain tls certbot owner response acceptance",
        "path": "docs/security/domain-tls-certbot-owner-response-acceptance.snapshot.json",
        "schema": "domain_tls_certbot_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 4,
            "blocked_actions": 20,
            "reviewer_checks": 13,
            "outcome_lanes": 7,
            "required_owner_response_fields": 13,
        },
        "summary_counts": {
            "acceptance_candidate_count": 4,
            "c0_acceptance_candidate_count": 4,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "host service owner response acceptance",
        "path": "docs/security/host-service-owner-response-acceptance.snapshot.json",
        "schema": "host_service_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 9,
            "blocked_actions": 27,
            "reviewer_checks": 21,
            "outcome_lanes": 8,
        },
        "summary_counts": {
            "acceptance_candidate_count": 9,
            "write_capable_acceptance_candidate_count": 3,
            "required_owner_field_count": 18,
            "reviewer_check_count": 21,
            "outcome_lane_count": 8,
            "blocked_action_count": 27,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "host service change evidence acceptance",
        "path": "docs/security/host-service-change-evidence-acceptance.snapshot.json",
        "schema": "host_service_change_evidence_acceptance_v1",
        "status": "change_evidence_acceptance_ready_no_runtime_action",
        "list_counts": {
            "change_evidence_candidates": 9,
            "blocked_actions": 39,
            "reviewer_checks": 26,
            "outcome_lanes": 10,
            "required_evidence_fields": 25,
        },
        "summary_counts": {
            "change_evidence_candidate_count": 9,
            "write_capable_change_evidence_candidate_count": 3,
            "live_evidence_required_candidate_count": 8,
            "change_evidence_field_count": 45,
            "required_evidence_field_count": 25,
            "reviewer_check_count": 26,
            "outcome_lane_count": 10,
            "blocked_action_count": 39,
            "change_evidence_received_count": 0,
            "change_evidence_accepted_count": 0,
            "docker_daemon_state_accepted_count": 0,
            "compose_stack_state_accepted_count": 0,
            "systemd_unit_state_accepted_count": 0,
            "failed_unit_review_accepted_count": 0,
            "port_binding_state_accepted_count": 0,
            "public_route_recovery_accepted_count": 0,
            "operator_notification_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "host service post incident readback plan",
        "path": "docs/security/host-service-post-incident-readback-plan.snapshot.json",
        "schema": "host_service_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 9,
            "blocked_actions": 41,
            "reviewer_checks": 28,
            "outcome_lanes": 10,
            "required_readback_fields": 28,
        },
        "summary_counts": {
            "readback_candidate_count": 9,
            "write_capable_readback_candidate_count": 3,
            "live_evidence_required_readback_candidate_count": 8,
            "recovery_health_impact_review_required_candidate_count": 9,
            "cross_project_sync_required_candidate_count": 9,
            "no_false_green_required_candidate_count": 9,
            "readback_field_count": 36,
            "required_readback_field_count": 28,
            "reviewer_check_count": 28,
            "outcome_lane_count": 10,
            "blocked_action_count": 41,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "actor_attribution_accepted_count": 0,
            "before_after_state_accepted_count": 0,
            "docker_daemon_state_accepted_count": 0,
            "compose_stack_state_accepted_count": 0,
            "systemd_unit_state_accepted_count": 0,
            "failed_unit_review_accepted_count": 0,
            "port_binding_state_accepted_count": 0,
            "public_route_recovery_accepted_count": 0,
            "admin_route_recovery_accepted_count": 0,
            "agent_provider_health_accepted_count": 0,
            "monitoring_alert_accepted_count": 0,
            "operator_notification_accepted_count": 0,
            "cross_project_sync_accepted_count": 0,
            "restoration_evidence_accepted_count": 0,
            "postcheck_readback_accepted_count": 0,
            "recurrence_guard_accepted_count": 0,
            "no_false_green_accepted_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "coverage_percent_after_readback_plan": 64,
        },
    },
    {
        "label": "ssh network owner response acceptance",
        "path": "docs/security/ssh-network-owner-response-acceptance.snapshot.json",
        "schema": "ssh_network_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 16,
            "blocked_actions": 22,
            "reviewer_checks": 15,
            "outcome_lanes": 7,
            "required_owner_fields": 13,
        },
        "summary_counts": {
            "acceptance_candidate_count": 16,
            "write_capable_acceptance_candidate_count": 6,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "port firewall change evidence acceptance",
        "path": "docs/security/port-firewall-change-evidence-acceptance.snapshot.json",
        "schema": "port_firewall_change_evidence_acceptance_v1",
        "status": "change_evidence_acceptance_ready_no_runtime_action",
        "list_counts": {
            "change_evidence_candidates": 14,
            "blocked_actions": 28,
            "reviewer_checks": 21,
            "outcome_lanes": 9,
            "required_evidence_fields": 21,
        },
        "summary_counts": {
            "change_evidence_candidate_count": 14,
            "write_capable_change_evidence_candidate_count": 6,
            "change_evidence_received_count": 0,
            "change_evidence_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "ssh network post incident readback plan",
        "path": "docs/security/ssh-network-post-incident-readback-plan.snapshot.json",
        "schema": "ssh_network_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 14,
            "blocked_actions": 34,
            "reviewer_checks": 24,
            "outcome_lanes": 10,
            "required_readback_fields": 24,
        },
        "summary_counts": {
            "readback_candidate_count": 14,
            "write_capable_readback_candidate_count": 6,
            "policy_or_exposure_readback_candidate_count": 5,
            "health_impact_review_required_candidate_count": 14,
            "cross_project_sync_required_candidate_count": 14,
            "recurrence_guard_required_candidate_count": 14,
            "readback_field_count": 30,
            "required_readback_field_count": 24,
            "reviewer_check_count": 24,
            "outcome_lane_count": 10,
            "blocked_action_count": 34,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "actor_attribution_accepted_count": 0,
            "before_after_state_accepted_count": 0,
            "service_dependency_accepted_count": 0,
            "public_route_impact_accepted_count": 0,
            "ai_provider_impact_accepted_count": 0,
            "monitoring_alert_impact_accepted_count": 0,
            "operator_notification_accepted_count": 0,
            "cross_project_sync_accepted_count": 0,
            "restoration_evidence_accepted_count": 0,
            "postcheck_readback_accepted_count": 0,
            "recurrence_guard_accepted_count": 0,
            "no_false_green_accepted_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "coverage_percent_after_readback_plan": 64,
        },
    },
    {
        "label": "backup restore owner response acceptance",
        "path": "docs/security/backup-restore-owner-response-acceptance.snapshot.json",
        "schema": "backup_restore_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 38,
            "blocked_actions": 31,
            "reviewer_checks": 22,
            "outcome_lanes": 9,
            "required_owner_fields": 23,
        },
        "summary_counts": {
            "acceptance_candidate_count": 38,
            "write_capable_acceptance_candidate_count": 27,
            "required_owner_field_count": 23,
            "reviewer_check_count": 22,
            "outcome_lane_count": 9,
            "blocked_action_count": 31,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "backup restore post incident readback plan",
        "path": "docs/security/backup-restore-post-incident-readback-plan.snapshot.json",
        "schema": "backup_restore_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 38,
            "blocked_actions": 51,
            "reviewer_checks": 32,
            "outcome_lanes": 11,
            "required_readback_fields": 34,
        },
        "summary_counts": {
            "source_acceptance_candidate_count": 38,
            "readback_candidate_count": 38,
            "write_capable_readback_candidate_count": 27,
            "live_evidence_required_readback_candidate_count": 38,
            "restore_drill_readback_required_candidate_count": 38,
            "offsite_or_escrow_readback_required_candidate_count": 20,
            "retention_or_remote_delete_readback_required_candidate_count": 17,
            "cross_project_sync_required_candidate_count": 38,
            "no_false_green_required_candidate_count": 38,
            "required_readback_field_count": 34,
            "reviewer_check_count": 32,
            "outcome_lane_count": 11,
            "blocked_action_count": 51,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "backup_status_readback_accepted_count": 0,
            "restore_drill_readback_accepted_count": 0,
            "offsite_sync_readback_accepted_count": 0,
            "credential_escrow_non_secret_readback_accepted_count": 0,
            "retention_runway_readback_accepted_count": 0,
            "backup_health_no_false_green_readback_accepted_count": 0,
            "backup_run_authorized_count": 0,
            "restore_run_authorized_count": 0,
            "offsite_sync_authorized_count": 0,
            "credential_escrow_marker_write_authorized_count": 0,
            "retention_change_authorized_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "coverage_percent_after_readback_plan": 66,
        },
    },
    {
        "label": "k8s argocd owner response acceptance",
        "path": "docs/security/k8s-argocd-owner-response-acceptance.snapshot.json",
        "schema": "k8s_argocd_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 4,
            "blocked_actions": 18,
            "reviewer_checks": 12,
            "outcome_lanes": 7,
            "required_owner_fields": 11,
        },
        "summary_counts": {
            "acceptance_candidate_count": 4,
            "c0_acceptance_candidate_count": 3,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "k8s argocd change evidence acceptance",
        "path": "docs/security/k8s-argocd-change-evidence-acceptance.snapshot.json",
        "schema": "k8s_argocd_change_evidence_acceptance_v1",
        "status": "change_evidence_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "change_evidence_candidates": 4,
            "blocked_actions": 28,
            "reviewer_checks": 18,
            "outcome_lanes": 8,
            "required_evidence_fields": 18,
        },
        "summary_counts": {
            "change_evidence_candidate_count": 4,
            "c0_change_evidence_candidate_count": 3,
            "change_evidence_received_count": 0,
            "change_evidence_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "k8s argocd post incident readback plan",
        "path": "docs/security/k8s-argocd-post-incident-readback-plan.snapshot.json",
        "schema": "k8s_argocd_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 4,
            "blocked_actions": 41,
            "reviewer_checks": 28,
            "outcome_lanes": 10,
            "required_readback_fields": 31,
        },
        "summary_counts": {
            "source_change_evidence_candidate_count": 4,
            "c0_readback_candidate_count": 3,
            "c1_readback_candidate_count": 1,
            "readback_candidate_count": 4,
            "write_capable_readback_candidate_count": 4,
            "source_manifest_file_count": 49,
            "source_yaml_manifest_file_count": 45,
            "source_c0_file_count": 36,
            "deployment_object_count": 5,
            "cronjob_object_count": 5,
            "secret_object_count": 6,
            "network_policy_object_count": 6,
            "rbac_object_count": 5,
            "argocd_application_count": 1,
            "prometheus_rule_count": 4,
            "degraded_or_pending_review_required_candidate_count": 4,
            "drift_or_schedule_review_required_candidate_count": 4,
            "route_ai_monitoring_impact_required_candidate_count": 4,
            "cross_project_sync_required_candidate_count": 4,
            "no_false_green_required_candidate_count": 4,
            "readback_field_count": 36,
            "required_readback_field_count": 31,
            "reviewer_check_count": 28,
            "outcome_lane_count": 10,
            "blocked_action_count": 41,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "actor_attribution_accepted_count": 0,
            "argocd_app_health_accepted_count": 0,
            "argocd_sync_status_accepted_count": 0,
            "degraded_state_accepted_count": 0,
            "pending_workload_accepted_count": 0,
            "image_pull_or_scheduling_accepted_count": 0,
            "rollout_before_after_accepted_count": 0,
            "event_summary_accepted_count": 0,
            "metrics_alert_accepted_count": 0,
            "drift_scanner_accepted_count": 0,
            "cronjob_schedule_accepted_count": 0,
            "network_policy_service_impact_accepted_count": 0,
            "rbac_serviceaccount_impact_accepted_count": 0,
            "secret_metadata_parity_accepted_count": 0,
            "public_admin_route_impact_accepted_count": 0,
            "ai_provider_monitoring_impact_accepted_count": 0,
            "backup_restore_impact_accepted_count": 0,
            "operator_notification_accepted_count": 0,
            "cross_project_sync_accepted_count": 0,
            "recovery_or_still_degraded_accepted_count": 0,
            "postcheck_readback_accepted_count": 0,
            "recurrence_guard_accepted_count": 0,
            "no_false_green_accepted_count": 0,
            "argocd_api_read_authorized_count": 0,
            "argocd_sync_authorized_count": 0,
            "live_cluster_read_authorized_count": 0,
            "kubectl_action_authorized_count": 0,
            "helm_action_authorized_count": 0,
            "network_policy_change_authorized_count": 0,
            "nodeport_change_authorized_count": 0,
            "rbac_change_authorized_count": 0,
            "secret_value_collection_allowed_count": 0,
            "route_smoke_authorized_count": 0,
            "production_write_authorized_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "coverage_percent_after_readback_plan": 66,
        },
    },
    {
        "label": "cd runner secret injection change evidence acceptance",
        "path": "docs/security/cd-runner-secret-injection-change-evidence-acceptance.snapshot.json",
        "schema": "cd_runner_secret_injection_change_evidence_acceptance_v1",
        "status": "change_evidence_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "change_evidence_candidates": 5,
            "blocked_actions": 32,
            "reviewer_checks": 19,
            "outcome_lanes": 8,
            "required_evidence_fields": 19,
        },
        "summary_counts": {
            "change_evidence_candidate_count": 5,
            "c0_change_evidence_candidate_count": 4,
            "change_evidence_received_count": 0,
            "change_evidence_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "cd runner secret injection post incident readback plan",
        "path": "docs/security/cd-runner-secret-injection-post-incident-readback-plan.snapshot.json",
        "schema": "cd_runner_secret_injection_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 5,
            "blocked_actions": 52,
            "reviewer_checks": 30,
            "outcome_lanes": 11,
            "required_readback_fields": 33,
        },
        "summary_counts": {
            "source_change_evidence_candidate_count": 5,
            "source_c0_change_evidence_candidate_count": 4,
            "source_c1_change_evidence_candidate_count": 1,
            "source_required_evidence_field_count": 19,
            "source_reviewer_check_count": 19,
            "source_blocked_action_count": 32,
            "source_change_evidence_accepted_count": 0,
            "source_runtime_gate_count": 0,
            "readback_candidate_count": 5,
            "c0_readback_candidate_count": 4,
            "c1_readback_candidate_count": 1,
            "write_capable_readback_candidate_count": 5,
            "secret_sensitive_readback_candidate_count": 5,
            "runner_or_workflow_readback_candidate_count": 5,
            "deploy_or_run_readback_required_candidate_count": 5,
            "cross_project_sync_required_candidate_count": 5,
            "no_false_green_required_candidate_count": 5,
            "readback_field_count": 44,
            "required_readback_field_count": 33,
            "reviewer_check_count": 30,
            "outcome_lane_count": 11,
            "blocked_action_count": 52,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "workflow_diff_state_accepted_count": 0,
            "runner_attestation_accepted_count": 0,
            "secret_name_parity_accepted_count": 0,
            "secret_injection_route_accepted_count": 0,
            "deploy_marker_readback_accepted_count": 0,
            "gitea_action_run_readback_accepted_count": 0,
            "log_redaction_readback_accepted_count": 0,
            "runtime_gate_count": 0,
            "secret_metadata_coverage_percent_after_readback_plan": 70,
            "gitea_workflow_runner_coverage_percent_after_readback_plan": 74,
        },
    },
    {
        "label": "public runtime config change evidence acceptance",
        "path": "docs/security/public-runtime-config-change-evidence-acceptance.snapshot.json",
        "schema": "public_runtime_config_change_evidence_acceptance_v1",
        "status": "change_evidence_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "change_evidence_candidates": 6,
            "blocked_actions": 32,
            "reviewer_checks": 21,
            "outcome_lanes": 8,
            "required_evidence_fields": 21,
        },
        "summary_counts": {
            "change_evidence_candidate_count": 6,
            "c0_change_evidence_candidate_count": 5,
            "change_evidence_received_count": 0,
            "change_evidence_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "monitoring owner request draft",
        "path": "docs/security/monitoring-owner-request-draft.snapshot.json",
        "schema": "monitoring_owner_request_draft_v1",
        "status": "owner_request_draft_ready_not_dispatched",
        "list_counts": {
            "request_drafts": 60,
            "blocked_actions": 24,
            "required_owner_fields": 14,
        },
        "summary_counts": {
            "request_draft_count": 60,
            "write_capable_request_draft_count": 11,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "monitoring owner response acceptance",
        "path": "docs/security/monitoring-owner-response-acceptance.snapshot.json",
        "schema": "monitoring_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 60,
            "blocked_actions": 34,
            "reviewer_checks": 23,
            "outcome_lanes": 12,
            "required_owner_fields": 14,
        },
        "summary_counts": {
            "acceptance_candidate_count": 60,
            "write_capable_acceptance_candidate_count": 11,
            "acceptance_field_count": 38,
            "reviewer_check_count": 23,
            "outcome_lane_count": 12,
            "blocked_action_count": 34,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "false_green_risk_review_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "monitoring post incident readback plan",
        "path": "docs/security/monitoring-post-incident-readback-plan.snapshot.json",
        "schema": "monitoring_post_incident_readback_plan_v1",
        "status": "post_incident_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 60,
            "blocked_actions": 53,
            "reviewer_checks": 28,
            "outcome_lanes": 11,
            "required_readback_fields": 30,
        },
        "summary_counts": {
            "source_acceptance_candidate_count": 60,
            "source_write_capable_acceptance_candidate_count": 11,
            "source_live_evidence_required_candidate_count": 60,
            "source_acceptance_field_count": 38,
            "source_required_owner_field_count": 14,
            "source_reviewer_check_count": 23,
            "source_outcome_lane_count": 12,
            "source_blocked_action_count": 34,
            "source_owner_response_accepted_count": 0,
            "source_alert_chain_health_accepted_count": 0,
            "source_receiver_receipt_proof_accepted_count": 0,
            "source_runtime_gate_count": 0,
            "readback_candidate_count": 60,
            "write_capable_readback_candidate_count": 11,
            "live_evidence_required_readback_candidate_count": 60,
            "alert_rule_readback_candidate_count": 13,
            "deploy_or_reload_readback_candidate_count": 6,
            "receiver_receipt_review_required_candidate_count": 60,
            "stale_silence_review_required_candidate_count": 60,
            "freshness_alert_chain_review_required_candidate_count": 60,
            "no_false_green_required_candidate_count": 60,
            "readback_field_count": 39,
            "required_readback_field_count": 30,
            "reviewer_check_count": 28,
            "outcome_lane_count": 11,
            "blocked_action_count": 53,
            "post_incident_readback_received_count": 0,
            "post_incident_readback_accepted_count": 0,
            "receiver_receipt_readback_accepted_count": 0,
            "stale_pending_resolved_review_accepted_count": 0,
            "silence_mute_dedup_inhibit_review_accepted_count": 0,
            "alert_chain_health_readback_accepted_count": 0,
            "runtime_gate_count": 0,
            "coverage_percent_after_readback_plan": 70,
        },
    },
    {
        "label": "wazuh iwooos intrusion readback plan",
        "path": "docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json",
        "schema": "wazuh_iwooos_intrusion_readback_plan_v1",
        "status": "wazuh_intrusion_readback_plan_ready_no_runtime_action",
        "list_counts": {
            "readback_candidates": 6,
            "blocked_actions": 49,
            "reviewer_checks": 24,
            "outcome_lanes": 12,
        },
        "summary_counts": {
            "wazuh_platform_reported_count": 1,
            "readback_candidate_count": 6,
            "c0_readback_candidate_count": 6,
            "affected_host_alias_count": 2,
            "wazuh_event_required_candidate_count": 5,
            "host_forensics_required_candidate_count": 5,
            "cross_project_sync_required_candidate_count": 6,
            "required_readback_field_count": 30,
            "reviewer_check_count": 24,
            "outcome_lane_count": 12,
            "blocked_action_count": 49,
            "wazuh_manager_health_ref_received_count": 0,
            "wazuh_agent_status_ref_received_count": 0,
            "wazuh_event_ref_received_count": 0,
            "host_forensics_ref_received_count": 0,
            "containment_decision_received_count": 0,
            "recovery_proof_received_count": 0,
            "postcheck_readback_received_count": 0,
            "recurrence_guard_received_count": 0,
            "cross_project_sync_received_count": 0,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "wazuh_event_accepted_count": 0,
            "host_forensics_accepted_count": 0,
            "containment_decision_accepted_count": 0,
            "recovery_proof_accepted_count": 0,
            "postcheck_readback_accepted_count": 0,
            "recurrence_guard_accepted_count": 0,
            "readonly_api_code_path_present_count": 1,
            "readonly_api_enabled_count": 0,
            "active_response_authorized_count": 0,
            "host_write_authorized_count": 0,
            "secret_value_collection_allowed_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "coverage_percent_after_readback_plan": 72,
        },
    },
    {
        "label": "external host intrusion prevention control",
        "path": "docs/security/external-host-intrusion-prevention-control.snapshot.json",
        "schema": "external_host_intrusion_prevention_control_v1",
        "status": "external_host_intrusion_prevention_control_ready_no_runtime_action",
        "list_counts": {
            "prevention_domains": 12,
            "control_candidates": 14,
            "blocked_actions": 82,
            "reviewer_checks": 34,
            "outcome_lanes": 12,
            "required_owner_fields": 36,
        },
        "summary_counts": {
            "prevention_domain_count": 12,
            "host_alias_count": 4,
            "sensor_alias_count": 1,
            "control_candidate_count": 14,
            "c0_control_candidate_count": 10,
            "c1_control_candidate_count": 4,
            "p0_control_candidate_count": 14,
            "urgent_prevention_candidate_count": 14,
            "maintenance_window_required_candidate_count": 14,
            "break_glass_required_candidate_count": 10,
            "owner_approval_required_candidate_count": 14,
            "cross_project_sync_required_candidate_count": 14,
            "rollback_required_candidate_count": 14,
            "validation_required_candidate_count": 14,
            "wazuh_event_required_candidate_count": 7,
            "host_forensics_required_candidate_count": 6,
            "config_diff_required_candidate_count": 8,
            "backup_restore_required_candidate_count": 1,
            "no_false_green_required_candidate_count": 14,
            "required_owner_field_count": 36,
            "reviewer_check_count": 34,
            "outcome_lane_count": 12,
            "blocked_action_count": 82,
            "coverage_percent_after_prevention_control": 74,
            "docker_compose_systemd_host_config_coverage_percent_after_prevention_control": 68,
            "ssh_firewall_network_access_coverage_percent_after_prevention_control": 70,
            "monitoring_alerting_observability_coverage_percent_after_prevention_control": 74,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "evidence_ref_received_count": 0,
            "evidence_ref_accepted_count": 0,
            "prevention_control_accepted_count": 0,
            "containment_decision_accepted_count": 0,
            "maintenance_window_accepted_count": 0,
            "rollback_plan_accepted_count": 0,
            "postcheck_accepted_count": 0,
            "wazuh_active_response_enabled_count": 0,
            "host_write_authorized_count": 0,
            "ssh_write_authorized_count": 0,
            "firewall_change_authorized_count": 0,
            "nginx_reload_authorized_count": 0,
            "docker_restart_authorized_count": 0,
            "systemctl_restart_authorized_count": 0,
            "argocd_sync_authorized_count": 0,
            "workflow_modification_authorized_count": 0,
            "runner_change_authorized_count": 0,
            "repo_secret_change_authorized_count": 0,
            "secret_value_collection_allowed_count": 0,
            "active_scan_authorized_count": 0,
            "package_upgrade_authorized_count": 0,
            "production_write_authorized_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
        },
    },
    {
        "label": "soc siem kali wazuh integration control",
        "path": "docs/security/soc-siem-kali-wazuh-integration-control.snapshot.json",
        "schema": "soc_siem_kali_wazuh_integration_control_v1",
        "status": "soc_siem_kali_wazuh_integration_control_ready_no_runtime_action",
        "list_counts": {
            "standard_frameworks": 14,
            "operating_roles": 9,
            "incident_lifecycle_stages": 8,
            "maturity_stages": 7,
            "validation_gates": 18,
            "control_domains": 16,
            "signal_sources": 12,
            "control_candidates": 20,
            "blocked_actions": 103,
            "reviewer_checks": 36,
            "outcome_lanes": 14,
            "required_owner_fields": 42,
        },
        "summary_counts": {
            "standard_framework_count": 14,
            "operating_role_count": 9,
            "incident_lifecycle_stage_count": 8,
            "maturity_stage_count": 7,
            "validation_gate_count": 18,
            "control_domain_count": 16,
            "c0_control_domain_count": 12,
            "c1_control_domain_count": 4,
            "signal_source_count": 12,
            "control_candidate_count": 20,
            "c0_control_candidate_count": 12,
            "c1_control_candidate_count": 8,
            "p0_control_candidate_count": 12,
            "p1_control_candidate_count": 8,
            "required_owner_field_count": 42,
            "reviewer_check_count": 36,
            "outcome_lane_count": 14,
            "blocked_action_count": 103,
            "coverage_percent_after_soc_integration_control": 78,
            "monitoring_alerting_observability_coverage_percent_after_soc_control": 78,
            "security_evidence_tooling_coverage_percent_after_soc_control": 88,
            "wazuh_event_ref_received_count": 0,
            "kali_scope_ref_accepted_count": 0,
            "kali_finding_envelope_accepted_count": 0,
            "siem_correlation_rule_accepted_count": 0,
            "alert_route_accepted_count": 0,
            "incident_case_accepted_count": 0,
            "forensic_evidence_accepted_count": 0,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "active_response_enabled_count": 0,
            "kali_active_scan_authorized_count": 0,
            "kali_execute_authorized_count": 0,
            "prometheus_reload_authorized_count": 0,
            "alertmanager_reload_authorized_count": 0,
            "telegram_send_authorized_count": 0,
            "soar_case_create_authorized_count": 0,
            "auto_block_authorized_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
        },
    },
    {
        "label": "telegram alert readability guard",
        "path": "docs/security/telegram-alert-readability-guard.snapshot.json",
        "schema": "telegram_alert_readability_guard_v1",
        "status": "telegram_alert_readability_guard_ready_no_runtime_action",
        "list_counts": {
            "source_markers": 11,
            "final_exit_contracts": 3,
            "test_contracts": 11,
            "ai_signal_lanes": 7,
            "host_resource_lanes": 6,
            "blocked_raw_output_markers": 12,
            "required_output_markers": 7,
        },
        "summary_counts": {
            "source_formatter_marker_count": 11,
            "final_exit_contract_count": 3,
            "test_contract_count": 11,
            "ai_signal_lane_count": 7,
            "host_resource_lane_count": 6,
            "blocked_raw_output_marker_count": 12,
            "required_output_marker_count": 7,
            "telegram_send_authorized_count": 0,
            "bot_api_call_authorized_count": 0,
            "raw_payload_storage_allowed_count": 0,
            "secret_value_collection_allowed_count": 0,
            "production_write_authorized_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
        },
    },
    {
        "label": "security asset control ledger",
        "path": "docs/security/security-asset-control-ledger.snapshot.json",
        "schema": "security_asset_control_ledger_v1",
        "status": "security_asset_control_ledger_ready_no_runtime_action",
        "list_counts": {
            "asset_groups": 16,
            "required_owner_fields": 24,
            "reviewer_checks": 24,
            "outcome_lanes": 10,
            "blocked_actions": 44,
        },
        "summary_counts": {
            "asset_group_count": 16,
            "p0_asset_group_count": 14,
            "p1_asset_group_count": 2,
            "c0_asset_group_count": 14,
            "c1_asset_group_count": 2,
            "evidence_ref_count": 64,
            "existing_evidence_ref_count": 64,
            "missing_evidence_ref_count": 0,
            "required_owner_field_count": 24,
            "reviewer_check_count": 24,
            "outcome_lane_count": 10,
            "blocked_action_count": 44,
            "owner_packet_required_count": 16,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "live_evidence_accepted_count": 0,
            "runtime_gate_count": 0,
            "action_button_count": 0,
            "host_write_authorized_count": 0,
            "active_scan_authorized_count": 0,
            "wazuh_active_response_authorized_count": 0,
            "kali_execute_authorized_count": 0,
            "soar_action_authorized_count": 0,
            "auto_block_authorized_count": 0,
            "secret_value_collected_count": 0,
            "raw_payload_stored_count": 0,
            "security_asset_control_ledger_completion_percent": 100,
            "iwooos_headline_progress_percent": 64,
        },
    },
    {
        "label": "ai provider owner response acceptance",
        "path": "docs/security/ai-provider-owner-response-acceptance.snapshot.json",
        "schema": "ai_provider_owner_response_acceptance_v1",
        "status": "owner_response_acceptance_ledger_ready_no_runtime_action",
        "list_counts": {
            "acceptance_candidates": 8,
            "blocked_actions": 38,
            "reviewer_checks": 24,
            "outcome_lanes": 10,
            "required_owner_fields": 24,
        },
        "summary_counts": {
            "acceptance_candidate_count": 8,
            "write_capable_acceptance_candidate_count": 5,
            "paid_provider_related_candidate_count": 5,
            "data_egress_candidate_count": 6,
            "live_evidence_required_candidate_count": 6,
            "acceptance_field_count": 37,
            "required_owner_field_count": 24,
            "reviewer_check_count": 24,
            "outcome_lane_count": 10,
            "blocked_action_count": 38,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "dry_run_result_accepted_count": 0,
            "benchmark_result_accepted_count": 0,
            "cost_review_accepted_count": 0,
            "privacy_review_accepted_count": 0,
            "fallback_order_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
    {
        "label": "agent bounty owner request draft",
        "path": "docs/security/agent-bounty-owner-request-draft.snapshot.json",
        "schema": "agent_bounty_owner_request_draft_v1",
        "status": "owner_request_draft_ready_not_dispatched",
        "list_counts": {
            "request_drafts": 11,
            "blocked_actions": 28,
            "required_owner_fields": 22,
        },
        "summary_counts": {
            "request_draft_count": 11,
            "write_capable_request_draft_count": 8,
            "owner_response_received_count": 0,
            "owner_response_accepted_count": 0,
            "runtime_gate_count": 0,
        },
    },
]


def load_json(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8"))


def fail(message: str) -> None:
    raise SystemExit(f"BLOCKED {message}")


def assert_equal(label: str, actual: Any, expected: Any) -> None:
    if actual != expected:
        fail(f"{label}: expected {expected!r}, got {actual!r}")


def assert_at_least(label: str, actual: int, expected_minimum: int) -> None:
    if actual < expected_minimum:
        fail(f"{label}: expected >= {expected_minimum!r}, got {actual!r}")


def assert_path_exists(root: Path, relative_path: str) -> None:
    path = root / relative_path
    if not path.exists():
        fail(f"path missing: {relative_path}")


def assert_file_contains(root: Path, relative_path: str, marker: str) -> None:
    path = root / relative_path
    assert_path_exists(root, relative_path)
    text = path.read_text(encoding="utf-8")
    if marker not in text:
        fail(f"{relative_path}: missing marker {marker!r}")


def assert_summary_zero_boundaries(label: str, summary: dict[str, Any]) -> None:
    for key, value in summary.items():
        if not isinstance(value, int):
            continue
        should_be_zero = key in SUMMARY_ZERO_KEYS or any(key.endswith(marker) for marker in SUMMARY_ZERO_MARKERS)
        if should_be_zero and value != 0:
            fail(f"{label}.summary.{key}: expected 0, got {value!r}")


def assert_execution_boundaries_false(label: str, data: dict[str, Any]) -> None:
    boundaries = data.get("execution_boundaries", {})
    if not isinstance(boundaries, dict):
        return
    for key, value in boundaries.items():
        if key in TRUE_BOUNDARY_KEYS:
            if value is not True:
                fail(f"{label}.execution_boundaries.{key}: expected true, got {value!r}")
            continue
        if value is not False:
            fail(f"{label}.execution_boundaries.{key}: expected false, got {value!r}")


def validate_coverage_snapshot(root: Path) -> None:
    coverage_path = root / "docs/security/high-value-config-control-coverage.snapshot.json"
    coverage = load_json(coverage_path)
    summary = coverage["summary"]

    assert_equal("coverage.schema_version", coverage["schema_version"], "high_value_config_control_coverage_v1")
    assert_equal("coverage.status", coverage["status"], "coverage_matrix_ready")
    assert_equal("coverage.source_category_definition", coverage["source_category_definition"], "scripts/security/high-value-config-change-gate.py")
    assert_equal("coverage.summary.category_count", summary["category_count"], len(EXPECTED_CATEGORIES))
    assert_equal("coverage.summary.registered_control_count", summary["registered_control_count"], len(EXPECTED_CATEGORIES))
    assert_equal("coverage.summary.c0_category_count", summary["c0_category_count"], len(REQUIRED_C0_CATEGORIES))
    assert_equal("coverage.summary.c1_category_count", summary["c1_category_count"], 4)
    assert_equal("coverage.summary.c2_category_count", summary["c2_category_count"], 1)
    assert_equal("coverage.summary.c3_category_count", summary["c3_category_count"], 1)
    assert_equal("coverage.summary.owner_response_required_count", summary["owner_response_required_count"], len(EXPECTED_CATEGORIES))
    assert_equal("coverage.summary.owner_response_received_count", summary["owner_response_received_count"], 0)
    assert_equal("coverage.summary.owner_response_accepted_count", summary["owner_response_accepted_count"], 0)
    assert_equal("coverage.summary.runtime_gate_count", summary["runtime_gate_count"], 0)
    assert_equal("coverage.summary.action_button_count", summary["action_button_count"], 0)
    assert_at_least("coverage.summary.average_coverage_percent", summary["average_coverage_percent"], 68)
    assert_at_least("coverage.summary.needs_live_evidence_count", summary["needs_live_evidence_count"], 9)

    categories = {item["category_id"]: item for item in coverage["coverage_categories"]}
    assert_equal("coverage.category ids", set(categories), set(EXPECTED_CATEGORIES))
    for category_id, expected_minimum in EXPECTED_CATEGORIES.items():
        category = categories[category_id]
        assert_at_least(f"coverage.{category_id}.coverage_percent", category["coverage_percent"], expected_minimum)
        assert_equal(f"coverage.{category_id}.owner_response_required", category["owner_response_required"], True)
        if category_id in REQUIRED_C0_CATEGORIES:
            assert_equal(f"coverage.{category_id}.control_tier", category["control_tier"], "C0")
        for ref in category.get("evidence_refs", []):
            if ref.startswith(("docs/", "scripts/", "k8s/", "infra/", "ops/")):
                assert_path_exists(root, ref)

    assert_execution_boundaries_false("coverage", coverage)
    boundaries = coverage["execution_boundaries"]
    for key in FALSE_BOUNDARY_KEYS:
        assert_equal(f"coverage.execution_boundaries.{key}", boundaries.get(key), False)


def validate_artifact_spec(root: Path, spec: dict[str, Any]) -> None:
    path = root / spec["path"]
    assert_path_exists(root, spec["path"])
    data = load_json(path)
    summary = data.get("summary", {})
    label = spec["label"]

    assert_equal(f"{label}.schema_version", data.get("schema_version"), spec["schema"])
    assert_equal(f"{label}.status", data.get("status"), spec["status"])
    for key, expected_count in spec.get("list_counts", {}).items():
        value = data.get(key)
        if not isinstance(value, list):
            fail(f"{label}.{key}: expected list, got {type(value).__name__}")
        assert_equal(f"{label}.{key}.count", len(value), expected_count)
    for key, expected_value in spec.get("summary_counts", {}).items():
        assert_equal(f"{label}.summary.{key}", summary.get(key), expected_value)
    assert_summary_zero_boundaries(label, summary)
    assert_execution_boundaries_false(label, data)


def validate_supply_chain_manifest(root: Path) -> None:
    manifest = load_json(root / "docs/security/security-supply-chain-contract-manifest.snapshot.json")
    assert_equal("supply_chain.schema_version", manifest["schema_version"], "security_supply_chain_contract_manifest_v1")
    assert_equal("supply_chain.default_enforcement_level", manifest["default_enforcement_level"], "mirror_only")
    assert_equal("supply_chain.contract_count", manifest["contract_count"], 36)
    assert_equal("supply_chain.contract list count", len(manifest["contracts"]), manifest["contract_count"])

    for item in manifest["contracts"]:
        contract = item["contract"]
        if not item.get("forbidden_actions"):
            fail(f"supply_chain.{contract}.forbidden_actions: expected non-empty list")
        for ref_key in ["snapshot_paths", "human_docs"]:
            for ref in item.get(ref_key, []):
                assert_path_exists(root, ref)
        schema_path = item.get("schema_path")
        if schema_path:
            assert_path_exists(root, schema_path)
        if item.get("consumption_mode") not in {"mirror_only", "read_only_policy", "approval_only", "suggest_only"}:
            fail(f"supply_chain.{contract}.consumption_mode: unsafe value {item.get('consumption_mode')!r}")


def validate_high_value_config_api_path(root: Path) -> None:
    assert_file_contains(
        root,
        "apps/api/src/services/iwooos_high_value_config_control_coverage.py",
        "iwooos_high_value_config_control_coverage_v1",
    )
    assert_file_contains(
        root,
        "apps/api/src/api/v1/iwooos.py",
        "/api/v1/iwooos/high-value-config-control-coverage",
    )
    assert_file_contains(
        root,
        "apps/api/tests/test_iwooos_high_value_config_control_coverage.py",
        "test_iwooos_high_value_config_control_coverage_api_is_public_safe",
    )
    assert_file_contains(
        root,
        "apps/web/src/lib/api-client.ts",
        "getIwoooSHighValueConfigControlCoverage",
    )
    assert_file_contains(
        root,
        "apps/web/src/app/[locale]/iwooos/page.tsx",
        "apiClient.getIwoooSHighValueConfigControlCoverage",
    )
    assert_file_contains(
        root,
        "apps/api/src/services/iwooos_owner_evidence_intake_preflight.py",
        "iwooos_owner_evidence_intake_preflight_v1",
    )
    assert_file_contains(
        root,
        "apps/api/src/api/v1/iwooos.py",
        "/api/v1/iwooos/owner-evidence-intake-preflight",
    )
    assert_file_contains(
        root,
        "apps/api/tests/test_iwooos_owner_evidence_intake_preflight.py",
        "test_iwooos_owner_evidence_intake_preflight_api_is_public_safe",
    )
    assert_file_contains(
        root,
        "apps/web/src/lib/api-client.ts",
        "getIwoooSOwnerEvidenceIntakePreflight",
    )
    assert_file_contains(
        root,
        "apps/web/src/app/[locale]/iwooos/page.tsx",
        "apiClient.getIwoooSOwnerEvidenceIntakePreflight",
    )
    assert_file_contains(
        root,
        "apps/web/messages/zh-TW.json",
        '"ownerEvidenceIntakePreflight"',
    )


def validate(root: Path) -> None:
    for relative_path in REQUIRED_CONTROL_DOCS:
        assert_path_exists(root, relative_path)
    validate_coverage_snapshot(root)
    validate_supply_chain_manifest(root)
    validate_high_value_config_api_path(root)
    for spec in ARTIFACT_SPECS:
        validate_artifact_spec(root, spec)


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--root",
        default=Path(__file__).resolve().parents[2],
        type=Path,
        help="Repository root. Defaults to the current script's repository.",
    )
    args = parser.parse_args()
    validate(args.root.resolve())
    print("IWOOOS_CONFIG_CONTROL_GUARD_OK")


if __name__ == "__main__":
    main()
