feat(iwooos): 新增 AI provider owner response 驗收 gate
This commit is contained in:
@@ -179,6 +179,9 @@ def validate(root: Path) -> None:
|
||||
monitoring_owner_response_acceptance = load_json(
|
||||
security_dir / "monitoring-owner-response-acceptance.snapshot.json"
|
||||
)
|
||||
ai_provider_owner_response_acceptance = load_json(
|
||||
security_dir / "ai-provider-owner-response-acceptance.snapshot.json"
|
||||
)
|
||||
domain_tls_inventory = load_json(security_dir / "domain-tls-certbot-inventory.snapshot.json")
|
||||
domain_tls_owner_confirmation_request = load_json(
|
||||
security_dir / "domain-tls-certbot-owner-confirmation-request.snapshot.json"
|
||||
@@ -3222,6 +3225,32 @@ def validate(root: Path) -> None:
|
||||
ssh_network_category["evidence_refs"],
|
||||
evidence_ref,
|
||||
)
|
||||
ai_provider_category = next(
|
||||
item
|
||||
for item in high_value_config_coverage["coverage_categories"]
|
||||
if item["category_id"] == "ai_provider_model_routing"
|
||||
)
|
||||
assert_equal(
|
||||
"high_value_config_coverage.coverage_categories.ai_provider.coverage_percent",
|
||||
ai_provider_category["coverage_percent"],
|
||||
64,
|
||||
)
|
||||
assert_equal(
|
||||
"high_value_config_coverage.coverage_categories.ai_provider.coverage_status",
|
||||
ai_provider_category["coverage_status"],
|
||||
"owner_response_acceptance_ready_needs_provider_owner_evidence",
|
||||
)
|
||||
for evidence_ref in [
|
||||
"docs/HARD_RULES.md",
|
||||
"docs/ai",
|
||||
"docs/security/AI-PROVIDER-OWNER-RESPONSE-ACCEPTANCE.md",
|
||||
"docs/security/ai-provider-owner-response-acceptance.snapshot.json",
|
||||
]:
|
||||
assert_contains(
|
||||
"high_value_config_coverage.coverage_categories.ai_provider.evidence_refs",
|
||||
ai_provider_category["evidence_refs"],
|
||||
evidence_ref,
|
||||
)
|
||||
backup_restore_category = next(
|
||||
item
|
||||
for item in high_value_config_coverage["coverage_categories"]
|
||||
@@ -5567,6 +5596,192 @@ def validate(root: Path) -> None:
|
||||
f"monitoring_owner_response_acceptance.{item['acceptance_candidate_id']}.{false_key}",
|
||||
item[false_key],
|
||||
)
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.schema",
|
||||
ai_provider_owner_response_acceptance["schema_version"],
|
||||
"ai_provider_owner_response_acceptance_v1",
|
||||
)
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.status",
|
||||
ai_provider_owner_response_acceptance["status"],
|
||||
"owner_response_acceptance_ledger_ready_no_runtime_action",
|
||||
)
|
||||
expected_ai_provider_owner_response_acceptance_summary = {
|
||||
"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,
|
||||
"owner_response_rejected_count": 0,
|
||||
"owner_response_quarantined_count": 0,
|
||||
"supplement_requested_count": 0,
|
||||
"fallback_order_accepted_count": 0,
|
||||
"dry_run_result_accepted_count": 0,
|
||||
"benchmark_result_accepted_count": 0,
|
||||
"cost_review_accepted_count": 0,
|
||||
"privacy_review_accepted_count": 0,
|
||||
"data_classification_accepted_count": 0,
|
||||
"prompt_redaction_accepted_count": 0,
|
||||
"secret_handling_accepted_count": 0,
|
||||
"quota_budget_accepted_count": 0,
|
||||
"latency_slo_accepted_count": 0,
|
||||
"quality_gate_accepted_count": 0,
|
||||
"rollback_owner_accepted_count": 0,
|
||||
"maintenance_window_accepted_count": 0,
|
||||
"postcheck_evidence_accepted_count": 0,
|
||||
"provider_switch_authorized_count": 0,
|
||||
"external_provider_call_authorized_count": 0,
|
||||
"paid_provider_call_authorized_count": 0,
|
||||
"prompt_send_authorized_count": 0,
|
||||
"live_endpoint_probe_authorized_count": 0,
|
||||
"secret_value_collection_allowed_count": 0,
|
||||
"runtime_gate_count": 0,
|
||||
"action_button_count": 0,
|
||||
"coverage_percent_after_acceptance": 64,
|
||||
}
|
||||
for key, expected in expected_ai_provider_owner_response_acceptance_summary.items():
|
||||
assert_equal(
|
||||
f"ai_provider_owner_response_acceptance.summary.{key}",
|
||||
ai_provider_owner_response_acceptance["summary"][key],
|
||||
expected,
|
||||
)
|
||||
for key, value in ai_provider_owner_response_acceptance["boundaries"].items():
|
||||
if key == "not_authorization":
|
||||
assert_true(f"ai_provider_owner_response_acceptance.boundaries.{key}", value)
|
||||
else:
|
||||
assert_false(f"ai_provider_owner_response_acceptance.boundaries.{key}", value)
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.acceptance_candidates.count",
|
||||
len(ai_provider_owner_response_acceptance["acceptance_candidates"]),
|
||||
8,
|
||||
)
|
||||
expected_ai_provider_candidate_ids = [
|
||||
"ai_provider_owner_response_acceptance:ai_router_provider_policy",
|
||||
"ai_provider_owner_response_acceptance:ollama_proxy_gateway",
|
||||
"ai_provider_owner_response_acceptance:fallback_order_and_circuit_breaker",
|
||||
"ai_provider_owner_response_acceptance:cost_budget_and_quota",
|
||||
"ai_provider_owner_response_acceptance:privacy_data_egress_boundary",
|
||||
"ai_provider_owner_response_acceptance:benchmark_dry_run_pack",
|
||||
"ai_provider_owner_response_acceptance:model_card_and_version_inventory",
|
||||
"ai_provider_owner_response_acceptance:agent_replacement_candidate_runtime_boundary",
|
||||
]
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.acceptance_candidates",
|
||||
[item["acceptance_candidate_id"] for item in ai_provider_owner_response_acceptance["acceptance_candidates"]],
|
||||
expected_ai_provider_candidate_ids,
|
||||
)
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.reviewer_checks.count",
|
||||
len(ai_provider_owner_response_acceptance["reviewer_checks"]),
|
||||
24,
|
||||
)
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.outcome_lanes.count",
|
||||
len(ai_provider_owner_response_acceptance["outcome_lanes"]),
|
||||
10,
|
||||
)
|
||||
assert_equal(
|
||||
"ai_provider_owner_response_acceptance.blocked_actions.count",
|
||||
len(ai_provider_owner_response_acceptance["blocked_actions"]),
|
||||
38,
|
||||
)
|
||||
for item in ai_provider_owner_response_acceptance["acceptance_candidates"]:
|
||||
assert_equal(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.acceptance_fields",
|
||||
len(item["acceptance_fields"]),
|
||||
37,
|
||||
)
|
||||
assert_equal(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.required_owner_fields",
|
||||
len(item["required_owner_fields"]),
|
||||
24,
|
||||
)
|
||||
assert_equal(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.reviewer_checks",
|
||||
len(item["reviewer_checks"]),
|
||||
24,
|
||||
)
|
||||
assert_equal(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.outcome_lanes",
|
||||
len(item["outcome_lanes"]),
|
||||
10,
|
||||
)
|
||||
assert_equal(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.blocked_actions",
|
||||
len(item["blocked_actions"]),
|
||||
38,
|
||||
)
|
||||
assert_true(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.not_approval",
|
||||
item["not_approval"],
|
||||
)
|
||||
for false_key in [
|
||||
"request_sent",
|
||||
"recipient_confirmed",
|
||||
"owner_response_received",
|
||||
"owner_response_accepted",
|
||||
"owner_response_rejected",
|
||||
"owner_response_quarantined",
|
||||
"supplement_requested",
|
||||
"fallback_order_accepted",
|
||||
"dry_run_result_accepted",
|
||||
"benchmark_result_accepted",
|
||||
"cost_review_accepted",
|
||||
"privacy_review_accepted",
|
||||
"data_classification_accepted",
|
||||
"prompt_redaction_accepted",
|
||||
"secret_handling_accepted",
|
||||
"quota_budget_accepted",
|
||||
"latency_slo_accepted",
|
||||
"quality_gate_accepted",
|
||||
"rollback_owner_accepted",
|
||||
"maintenance_window_accepted",
|
||||
"postcheck_evidence_accepted",
|
||||
"provider_switch_authorized",
|
||||
"model_route_change_authorized",
|
||||
"fallback_order_change_authorized",
|
||||
"ollama_proxy_change_authorized",
|
||||
"nginx_reload_authorized",
|
||||
"env_change_authorized",
|
||||
"external_provider_call_authorized",
|
||||
"paid_provider_call_authorized",
|
||||
"prompt_send_authorized",
|
||||
"live_endpoint_probe_authorized",
|
||||
"benchmark_live_call_authorized",
|
||||
"dry_run_external_call_authorized",
|
||||
"quota_increase_authorized",
|
||||
"cost_limit_change_authorized",
|
||||
"privacy_boundary_change_authorized",
|
||||
"data_egress_change_authorized",
|
||||
"secret_value_collection_allowed",
|
||||
"secret_hash_collection_allowed",
|
||||
"partial_token_collection_allowed",
|
||||
"api_key_rotation_authorized",
|
||||
"secret_store_read_authorized",
|
||||
"model_download_authorized",
|
||||
"sdk_install_authorized",
|
||||
"agent_runtime_enable_authorized",
|
||||
"shadow_or_canary_enable_authorized",
|
||||
"production_deploy_authorized",
|
||||
"workflow_dispatch_authorized",
|
||||
"host_write_authorized",
|
||||
"ssh_read_authorized",
|
||||
"ssh_write_authorized",
|
||||
"active_scan_authorized",
|
||||
"runtime_gate",
|
||||
"action_buttons_allowed",
|
||||
]:
|
||||
assert_false(
|
||||
f"ai_provider_owner_response_acceptance.{item['acceptance_candidate_id']}.{false_key}",
|
||||
item[false_key],
|
||||
)
|
||||
assert_equal(
|
||||
"public_gateway_preflight_inventory.schema",
|
||||
public_gateway_preflight_inventory["schema_version"],
|
||||
@@ -6596,6 +6811,7 @@ def validate(root: Path) -> None:
|
||||
"public_frontend_sensitive_surface_guard_allowlisted_match_count": 2,
|
||||
"public_frontend_sensitive_surface_guard_violation_count": 0,
|
||||
"public_frontend_sensitive_surface_guard_runtime_gate_count": 0,
|
||||
"ai_provider_model_routing_coverage_percent": 64,
|
||||
}
|
||||
for key, expected in expected_high_value_config_coverage_summary.items():
|
||||
assert_equal(
|
||||
@@ -6603,6 +6819,43 @@ def validate(root: Path) -> None:
|
||||
iwooos_projection["summary"][key],
|
||||
expected,
|
||||
)
|
||||
expected_ai_provider_owner_response_projection_summary = {
|
||||
"ai_provider_owner_response_acceptance_candidate_count": 8,
|
||||
"ai_provider_owner_response_acceptance_write_capable_candidate_count": 5,
|
||||
"ai_provider_owner_response_acceptance_paid_provider_related_candidate_count": 5,
|
||||
"ai_provider_owner_response_acceptance_data_egress_candidate_count": 6,
|
||||
"ai_provider_owner_response_acceptance_live_evidence_required_candidate_count": 6,
|
||||
"ai_provider_owner_response_acceptance_acceptance_field_count": 37,
|
||||
"ai_provider_owner_response_acceptance_required_owner_field_count": 24,
|
||||
"ai_provider_owner_response_acceptance_reviewer_check_count": 24,
|
||||
"ai_provider_owner_response_acceptance_outcome_lane_count": 10,
|
||||
"ai_provider_owner_response_acceptance_blocked_action_count": 38,
|
||||
"ai_provider_owner_response_acceptance_owner_response_received_count": 0,
|
||||
"ai_provider_owner_response_acceptance_owner_response_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_dry_run_result_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_benchmark_result_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_cost_review_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_privacy_review_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_fallback_order_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_prompt_redaction_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_secret_handling_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_quality_gate_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_rollback_owner_accepted_count": 0,
|
||||
"ai_provider_owner_response_acceptance_provider_switch_authorized_count": 0,
|
||||
"ai_provider_owner_response_acceptance_external_provider_call_authorized_count": 0,
|
||||
"ai_provider_owner_response_acceptance_paid_provider_call_authorized_count": 0,
|
||||
"ai_provider_owner_response_acceptance_prompt_send_authorized_count": 0,
|
||||
"ai_provider_owner_response_acceptance_live_endpoint_probe_authorized_count": 0,
|
||||
"ai_provider_owner_response_acceptance_secret_value_collection_allowed_count": 0,
|
||||
"ai_provider_owner_response_acceptance_runtime_gate_count": 0,
|
||||
"ai_provider_owner_response_acceptance_coverage_percent_after_acceptance": 64,
|
||||
}
|
||||
for key, expected in expected_ai_provider_owner_response_projection_summary.items():
|
||||
assert_equal(
|
||||
f"iwooos_projection.summary.{key}",
|
||||
iwooos_projection["summary"][key],
|
||||
expected,
|
||||
)
|
||||
expected_host_service_projection_summary = {
|
||||
"host_service_config_inventory_first_layer": True,
|
||||
"host_service_config_inventory_surface_count": 9,
|
||||
@@ -16507,15 +16760,15 @@ def validate(root: Path) -> None:
|
||||
iwooos_projection_page,
|
||||
"{ key: 'dockerSystemd', rank: 'P1-1', value: '62%'",
|
||||
)
|
||||
assert_text_contains(
|
||||
"iwooos_page.high_value_config_control_coverage_ai_provider_percent",
|
||||
iwooos_projection_page,
|
||||
"{ key: 'aiProvider', rank: 'P1-2', value: '60%'",
|
||||
)
|
||||
assert_text_contains(
|
||||
"iwooos_page.high_value_config_control_coverage_ssh_network_percent",
|
||||
iwooos_projection_page,
|
||||
"{ key: 'sshNetwork', rank: 'P1-3', value: '62%'",
|
||||
"{ key: 'sshNetwork', rank: 'P1-2', value: '62%'",
|
||||
)
|
||||
assert_text_contains(
|
||||
"iwooos_page.high_value_config_control_coverage_ai_provider_percent",
|
||||
iwooos_projection_page,
|
||||
"{ key: 'aiProvider', rank: 'P1-3', value: '64%'",
|
||||
)
|
||||
assert_text_contains(
|
||||
"iwooos_page.high_value_config_control_coverage_k8s_gitops_percent",
|
||||
@@ -16550,6 +16803,24 @@ def validate(root: Path) -> None:
|
||||
"secret_metadata_coverage_percent=68",
|
||||
"gitea_workflow_runner_source_control_coverage_percent=72",
|
||||
"public_admin_api_runtime_config_coverage_percent=66",
|
||||
"ai_provider_model_routing_coverage_percent=64",
|
||||
"ai_provider_owner_response_acceptance_candidate_count=8",
|
||||
"ai_provider_owner_response_acceptance_write_capable_candidate_count=5",
|
||||
"ai_provider_owner_response_acceptance_required_owner_field_count=24",
|
||||
"ai_provider_owner_response_acceptance_reviewer_check_count=24",
|
||||
"ai_provider_owner_response_acceptance_outcome_lane_count=10",
|
||||
"ai_provider_owner_response_acceptance_blocked_action_count=38",
|
||||
"ai_provider_owner_response_acceptance_owner_response_received_count=0",
|
||||
"ai_provider_owner_response_acceptance_owner_response_accepted_count=0",
|
||||
"ai_provider_owner_response_acceptance_dry_run_result_accepted_count=0",
|
||||
"ai_provider_owner_response_acceptance_benchmark_result_accepted_count=0",
|
||||
"ai_provider_owner_response_acceptance_cost_review_accepted_count=0",
|
||||
"ai_provider_owner_response_acceptance_privacy_review_accepted_count=0",
|
||||
"ai_provider_owner_response_acceptance_provider_switch_authorized_count=0",
|
||||
"ai_provider_owner_response_acceptance_external_provider_call_authorized_count=0",
|
||||
"ai_provider_owner_response_acceptance_paid_provider_call_authorized_count=0",
|
||||
"ai_provider_owner_response_acceptance_prompt_send_authorized_count=0",
|
||||
"ai_provider_owner_response_acceptance_runtime_gate_count=0",
|
||||
"public_frontend_sensitive_surface_guard_file_count=225",
|
||||
"public_frontend_sensitive_surface_guard_forbidden_pattern_count=12",
|
||||
"public_frontend_sensitive_surface_guard_violation_count=0",
|
||||
@@ -17125,7 +17396,7 @@ def validate(root: Path) -> None:
|
||||
list(web_messages_en["iwooos"]["highValueConfigControlCoverage"]["summary"].keys()),
|
||||
key,
|
||||
)
|
||||
for key in ["dockerSystemd", "sshNetwork", "backupRestore", "monitoring"]:
|
||||
for key in ["dockerSystemd", "sshNetwork", "aiProvider", "k8sGitops"]:
|
||||
assert_contains(
|
||||
"web_messages.zh-TW.iwooos.highValueConfigControlCoverage.items",
|
||||
list(web_messages_zh["iwooos"]["highValueConfigControlCoverage"]["items"].keys()),
|
||||
@@ -17136,6 +17407,16 @@ def validate(root: Path) -> None:
|
||||
list(web_messages_en["iwooos"]["highValueConfigControlCoverage"]["items"].keys()),
|
||||
key,
|
||||
)
|
||||
assert_text_contains(
|
||||
"web_messages.zh-TW.iwooos.highValueConfigControlCoverage.items.aiProvider.body",
|
||||
web_messages_zh["iwooos"]["highValueConfigControlCoverage"]["items"]["aiProvider"]["body"],
|
||||
"8 個候選、24 個審查檢查項、10 條結果分流、38 類禁止動作",
|
||||
)
|
||||
assert_text_contains(
|
||||
"web_messages.en.iwooos.highValueConfigControlCoverage.items.aiProvider.body",
|
||||
web_messages_en["iwooos"]["highValueConfigControlCoverage"]["items"]["aiProvider"]["body"],
|
||||
"8 個候選、24 個審查檢查項、10 條結果分流、38 類禁止動作",
|
||||
)
|
||||
assert_text_contains(
|
||||
"web_messages.zh-TW.iwooos.highValueConfigControlCoverage.items.sshNetwork.body",
|
||||
web_messages_zh["iwooos"]["highValueConfigControlCoverage"]["items"]["sshNetwork"]["body"],
|
||||
|
||||
Reference in New Issue
Block a user