{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://awoooi.wooo.work/schemas/public_gateway_preflight_inventory_v1.schema.json",
  "title": "IwoooS public gateway 變更前置 Gate 只讀清冊",
  "description": "定義 Nginx public gateway reload / route change 前必備的 owner、diff、nginx -t、route smoke、maintenance window 與 rollback 欄位。本契約不授權 SSH、live conf 讀取、nginx -t、Nginx reload、DNS / TLS probe、certbot renew 或 host write。",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "generated_at",
    "status",
    "source_scope",
    "git_commit",
    "source_reports",
    "summary",
    "execution_boundaries",
    "required_preflight_gates",
    "config_preflight_rows",
    "route_impacts",
    "unique_upstreams",
    "required_owner_fields",
    "next_collection_order",
    "operator_interpretation"
  ],
  "properties": {
    "schema_version": {
      "const": "public_gateway_preflight_inventory_v1"
    },
    "generated_at": {
      "type": "string"
    },
    "status": {
      "const": "repo_only_preflight_contract_ready"
    },
    "source_scope": {
      "const": "committed_nginx_and_domain_tls_snapshots_only"
    },
    "git_commit": {
      "type": "string"
    },
    "source_reports": {
      "type": "array",
      "minItems": 2,
      "maxItems": 2,
      "items": {
        "type": "string"
      }
    },
    "summary": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "source_config_count",
        "c0_source_config_count",
        "managed_domain_count",
        "route_impact_count",
        "unique_upstream_count",
        "tls_certificate_path_count",
        "certificate_owner_confirmation_required_count",
        "admin_route_domain_count",
        "websocket_route_domain_count",
        "acme_challenge_domain_count",
        "preflight_gate_count",
        "repo_only_preflight_ready_count",
        "owner_acceptance_required_gate_count",
        "preflight_gate_accepted_count",
        "owner_response_received_count",
        "owner_response_accepted_count",
        "owner_provided_live_conf_received_count",
        "rendered_diff_ready_count",
        "nginx_test_evidence_count",
        "route_smoke_evidence_count",
        "maintenance_window_accepted_count",
        "rollback_owner_accepted_count",
        "runtime_gate_count",
        "action_button_count",
        "coverage_percent_before_preflight",
        "coverage_percent_after_preflight"
      ],
      "properties": {
        "source_config_count": {
          "const": 3
        },
        "c0_source_config_count": {
          "const": 2
        },
        "managed_domain_count": {
          "const": 14
        },
        "route_impact_count": {
          "const": 14
        },
        "unique_upstream_count": {
          "type": "integer",
          "minimum": 1
        },
        "tls_certificate_path_count": {
          "const": 10
        },
        "certificate_owner_confirmation_required_count": {
          "const": 4
        },
        "admin_route_domain_count": {
          "const": 1
        },
        "websocket_route_domain_count": {
          "const": 6
        },
        "acme_challenge_domain_count": {
          "const": 7
        },
        "preflight_gate_count": {
          "const": 12
        },
        "repo_only_preflight_ready_count": {
          "const": 2
        },
        "owner_acceptance_required_gate_count": {
          "const": 10
        },
        "preflight_gate_accepted_count": {
          "const": 0
        },
        "owner_response_received_count": {
          "const": 0
        },
        "owner_response_accepted_count": {
          "const": 0
        },
        "owner_provided_live_conf_received_count": {
          "const": 0
        },
        "rendered_diff_ready_count": {
          "const": 0
        },
        "nginx_test_evidence_count": {
          "const": 0
        },
        "route_smoke_evidence_count": {
          "const": 0
        },
        "maintenance_window_accepted_count": {
          "const": 0
        },
        "rollback_owner_accepted_count": {
          "const": 0
        },
        "runtime_gate_count": {
          "const": 0
        },
        "action_button_count": {
          "const": 0
        },
        "coverage_percent_before_preflight": {
          "const": 78
        },
        "coverage_percent_after_preflight": {
          "const": 84
        }
      }
    },
    "execution_boundaries": {
      "type": "object",
      "additionalProperties": {
        "const": false
      },
      "required": [
        "runtime_execution_authorized",
        "host_live_conf_read_authorized",
        "ssh_read_authorized",
        "ssh_write_authorized",
        "host_write_authorized",
        "nginx_test_authorized",
        "nginx_test_executed",
        "nginx_reload_authorized",
        "nginx_reload_executed",
        "public_gateway_reload_authorized",
        "public_route_change_authorized",
        "admin_route_change_authorized",
        "websocket_route_change_authorized",
        "acme_challenge_change_authorized",
        "dns_query_executed",
        "live_tls_probe_executed",
        "certbot_renew_authorized",
        "certbot_renew_executed",
        "route_smoke_authorized",
        "route_smoke_executed",
        "rollback_executed",
        "secret_value_collection_allowed",
        "action_buttons_allowed"
      ]
    },
    "required_preflight_gates": {
      "type": "array",
      "minItems": 12,
      "maxItems": 12,
      "items": {
        "$ref": "#/$defs/preflight_gate"
      }
    },
    "config_preflight_rows": {
      "type": "array",
      "minItems": 3,
      "maxItems": 3,
      "items": {
        "$ref": "#/$defs/config_preflight_row"
      }
    },
    "route_impacts": {
      "type": "array",
      "minItems": 14,
      "maxItems": 14,
      "items": {
        "$ref": "#/$defs/route_impact"
      }
    },
    "unique_upstreams": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "required_owner_fields": {
      "type": "array",
      "minItems": 11,
      "items": {
        "type": "string"
      }
    },
    "next_collection_order": {
      "type": "array",
      "minItems": 10,
      "items": {
        "type": "string"
      }
    },
    "operator_interpretation": {
      "type": "array",
      "minItems": 4,
      "items": {
        "type": "string"
      }
    }
  },
  "$defs": {
    "preflight_gate": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "gate_id",
        "label",
        "required_evidence",
        "owner_acceptance_required",
        "repo_only_ready"
      ],
      "properties": {
        "gate_id": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "required_evidence": {
          "type": "string"
        },
        "owner_acceptance_required": {
          "type": "boolean"
        },
        "repo_only_ready": {
          "type": "boolean"
        }
      }
    },
    "config_preflight_row": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "config_id",
        "host",
        "role",
        "control_tier",
        "owner_gate",
        "repo_source_path",
        "live_path",
        "server_block_count",
        "server_name_count",
        "upstream_count",
        "tls_certificate_path_count",
        "admin_route_count",
        "acme_route_count",
        "websocket_route_count",
        "repo_source_hash_ready",
        "owner_response_received",
        "owner_response_accepted",
        "live_conf_evidence_received",
        "rendered_diff_ready",
        "nginx_test_evidence_received",
        "route_smoke_evidence_received",
        "maintenance_window_accepted",
        "rollback_owner_accepted",
        "runtime_gate_open"
      ],
      "properties": {
        "config_id": {
          "type": "string"
        },
        "host": {
          "type": "string"
        },
        "role": {
          "type": "string"
        },
        "control_tier": {
          "enum": [
            "C0",
            "C1",
            "C2",
            "C3"
          ]
        },
        "owner_gate": {
          "type": "string"
        },
        "repo_source_path": {
          "type": "string"
        },
        "live_path": {
          "type": "string"
        },
        "server_block_count": {
          "type": "integer",
          "minimum": 0
        },
        "server_name_count": {
          "type": "integer",
          "minimum": 0
        },
        "upstream_count": {
          "type": "integer",
          "minimum": 0
        },
        "tls_certificate_path_count": {
          "type": "integer",
          "minimum": 0
        },
        "admin_route_count": {
          "type": "integer",
          "minimum": 0
        },
        "acme_route_count": {
          "type": "integer",
          "minimum": 0
        },
        "websocket_route_count": {
          "type": "integer",
          "minimum": 0
        },
        "repo_source_hash_ready": {
          "const": true
        },
        "owner_response_received": {
          "const": false
        },
        "owner_response_accepted": {
          "const": false
        },
        "live_conf_evidence_received": {
          "const": false
        },
        "rendered_diff_ready": {
          "const": false
        },
        "nginx_test_evidence_received": {
          "const": false
        },
        "route_smoke_evidence_received": {
          "const": false
        },
        "maintenance_window_accepted": {
          "const": false
        },
        "rollback_owner_accepted": {
          "const": false
        },
        "runtime_gate_open": {
          "const": false
        }
      }
    },
    "route_impact": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "domain",
        "hosts",
        "config_ids",
        "control_tier",
        "upstream_count",
        "has_tls_certificate_path",
        "certificate_owner_confirmation_required",
        "acme_challenge_present",
        "admin_route_count",
        "websocket_route_count",
        "public_route_smoke_required",
        "admin_route_smoke_required",
        "websocket_or_api_smoke_required",
        "tls_owner_check_required",
        "owner_response_accepted",
        "route_smoke_accepted"
      ],
      "properties": {
        "domain": {
          "type": "string"
        },
        "hosts": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "config_ids": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "control_tier": {
          "enum": [
            "C0",
            "C1",
            "C2",
            "C3"
          ]
        },
        "upstream_count": {
          "type": "integer",
          "minimum": 0
        },
        "has_tls_certificate_path": {
          "type": "boolean"
        },
        "certificate_owner_confirmation_required": {
          "type": "boolean"
        },
        "acme_challenge_present": {
          "type": "boolean"
        },
        "admin_route_count": {
          "type": "integer",
          "minimum": 0
        },
        "websocket_route_count": {
          "type": "integer",
          "minimum": 0
        },
        "public_route_smoke_required": {
          "const": true
        },
        "admin_route_smoke_required": {
          "type": "boolean"
        },
        "websocket_or_api_smoke_required": {
          "type": "boolean"
        },
        "tls_owner_check_required": {
          "type": "boolean"
        },
        "owner_response_accepted": {
          "const": false
        },
        "route_smoke_accepted": {
          "const": false
        }
      }
    }
  }
}
