{ "$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 } } } } }