feat(iwooos): 新增 K8s ArgoCD 事故回讀 gate
All checks were successful
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / tests (push) Successful in 1m48s
CD Pipeline / build-and-deploy (push) Successful in 6m0s
CD Pipeline / post-deploy-checks (push) Successful in 2m19s

This commit is contained in:
Your Name
2026-06-15 20:42:12 +08:00
parent 18cf52631c
commit 45c2b8ebe6
16 changed files with 2811 additions and 43 deletions

View File

@@ -207,6 +207,9 @@ def validate(root: Path) -> None:
k8s_argocd_change_evidence_acceptance = load_json(
security_dir / "k8s-argocd-change-evidence-acceptance.snapshot.json"
)
k8s_argocd_post_incident_readback_plan = load_json(
security_dir / "k8s-argocd-post-incident-readback-plan.snapshot.json"
)
cd_runner_secret_injection_change_evidence_acceptance = load_json(
security_dir / "cd-runner-secret-injection-change-evidence-acceptance.snapshot.json"
)
@@ -3062,12 +3065,12 @@ def validate(root: Path) -> None:
assert_equal(
"high_value_config_coverage.coverage_categories.k8s.coverage_percent",
k8s_gitops_category["coverage_percent"],
64,
66,
)
assert_equal(
"high_value_config_coverage.coverage_categories.k8s.coverage_status",
k8s_gitops_category["coverage_status"],
"change_evidence_acceptance_ready_needs_gitops_owner_evidence",
"post_incident_readback_plan_ready_needs_gitops_owner_evidence",
)
for evidence_ref in [
"docs/security/HIGH-VALUE-CONFIG-CHANGE-GATE.md",
@@ -3077,6 +3080,8 @@ def validate(root: Path) -> None:
"docs/security/k8s-argocd-owner-response-acceptance.snapshot.json",
"docs/security/K8S-ARGOCD-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/k8s-argocd-change-evidence-acceptance.snapshot.json",
"docs/security/K8S-ARGOCD-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/k8s-argocd-post-incident-readback-plan.snapshot.json",
"k8s/awoooi-prod",
"k8s/argocd",
]:
@@ -7127,6 +7132,8 @@ def validate(root: Path) -> None:
"docs/security/K8S-ARGOCD-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/k8s-argocd-change-evidence-acceptance.snapshot.json",
"docs/security/K8S-ARGOCD-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/k8s-argocd-post-incident-readback-plan.snapshot.json",
"docs/security/K8S-ARGOCD-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/host-service-config-inventory.snapshot.json",
"docs/security/HOST-SERVICE-CONFIG-INVENTORY.md",
"docs/security/host-service-post-incident-readback-plan.snapshot.json",
@@ -7188,6 +7195,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,
"k8s_production_gitops_coverage_percent": 66,
"ai_provider_model_routing_coverage_percent": 64,
}
for key, expected in expected_high_value_config_coverage_summary.items():
@@ -7422,6 +7430,61 @@ def validate(root: Path) -> None:
"k8s_argocd_change_evidence_acceptance_runtime_gate_count": 0,
"k8s_argocd_change_evidence_acceptance_action_button_count": 0,
"k8s_argocd_change_evidence_acceptance_coverage_percent_after_acceptance": 64,
"k8s_argocd_post_incident_readback_plan_first_layer": True,
"k8s_argocd_post_incident_readback_plan_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_c0_candidate_count": 3,
"k8s_argocd_post_incident_readback_plan_c1_candidate_count": 1,
"k8s_argocd_post_incident_readback_plan_write_capable_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_degraded_or_pending_review_required_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_drift_or_schedule_review_required_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_route_ai_monitoring_impact_required_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_cross_project_sync_required_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_no_false_green_required_candidate_count": 4,
"k8s_argocd_post_incident_readback_plan_readback_field_count": 36,
"k8s_argocd_post_incident_readback_plan_required_readback_field_count": 31,
"k8s_argocd_post_incident_readback_plan_reviewer_check_count": 28,
"k8s_argocd_post_incident_readback_plan_outcome_lane_count": 10,
"k8s_argocd_post_incident_readback_plan_blocked_action_count": 41,
"k8s_argocd_post_incident_readback_plan_post_incident_readback_received_count": 0,
"k8s_argocd_post_incident_readback_plan_post_incident_readback_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_actor_attribution_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_argocd_app_health_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_argocd_sync_status_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_degraded_state_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_pending_workload_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_image_pull_or_scheduling_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_rollout_before_after_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_event_summary_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_metrics_alert_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_drift_scanner_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_cronjob_schedule_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_network_policy_service_impact_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_rbac_serviceaccount_impact_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_secret_metadata_parity_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_public_admin_route_impact_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_ai_provider_monitoring_impact_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_backup_restore_impact_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_operator_notification_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_cross_project_sync_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_recovery_or_still_degraded_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_postcheck_readback_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_recurrence_guard_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_no_false_green_accepted_count": 0,
"k8s_argocd_post_incident_readback_plan_argocd_api_read_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_argocd_sync_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_live_cluster_read_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_kubectl_action_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_helm_action_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_network_policy_change_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_nodeport_change_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_rbac_change_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_secret_value_collection_allowed_count": 0,
"k8s_argocd_post_incident_readback_plan_route_smoke_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_production_write_authorized_count": 0,
"k8s_argocd_post_incident_readback_plan_runtime_gate_count": 0,
"k8s_argocd_post_incident_readback_plan_action_button_count": 0,
"k8s_argocd_post_incident_readback_plan_coverage_percent_after_readback_plan": 66,
"k8s_production_gitops_coverage_percent": 66,
"cd_runner_secret_injection_change_evidence_acceptance_first_layer": True,
"cd_runner_secret_injection_change_evidence_acceptance_candidate_count": 5,
"cd_runner_secret_injection_change_evidence_acceptance_c0_candidate_count": 4,
@@ -17214,7 +17277,7 @@ def validate(root: Path) -> None:
assert_text_contains(
"iwooos_page.high_value_config_control_coverage_k8s_gitops_percent",
iwooos_projection_page,
"{ key: 'k8sGitops', rank: 'P1-4', value: '64%'",
"{ key: 'k8sGitops', rank: 'P1-4', value: '66%'",
)
assert_text_before(
"iwooos_page.high_value_config_control_coverage_before_owner_packet",
@@ -17240,7 +17303,7 @@ def validate(root: Path) -> None:
"public_gateway_owner_response_acceptance_reviewer_check_count=22",
"public_gateway_owner_response_acceptance_outcome_lane_count=8",
"public_gateway_owner_response_acceptance_blocked_action_count=28",
"k8s_production_gitops_coverage_percent=64",
"k8s_production_gitops_coverage_percent=66",
"secret_metadata_coverage_percent=68",
"gitea_workflow_runner_source_control_coverage_percent=72",
"public_admin_api_runtime_config_coverage_percent=66",
@@ -17323,6 +17386,28 @@ def validate(root: Path) -> None:
"k8s_argocd_change_evidence_acceptance_accepted_count=0",
"k8s_argocd_change_evidence_acceptance_runtime_approval_package_ready_count=0",
"k8s_argocd_change_evidence_acceptance_runtime_gate_count=0",
"k8s_argocd_post_incident_readback_plan_candidate_count=4",
"k8s_argocd_post_incident_readback_plan_c0_candidate_count=3",
"k8s_argocd_post_incident_readback_plan_write_capable_candidate_count=4",
"k8s_argocd_post_incident_readback_plan_required_readback_field_count=31",
"k8s_argocd_post_incident_readback_plan_reviewer_check_count=28",
"k8s_argocd_post_incident_readback_plan_outcome_lane_count=10",
"k8s_argocd_post_incident_readback_plan_blocked_action_count=41",
"k8s_argocd_post_incident_readback_plan_post_incident_readback_received_count=0",
"k8s_argocd_post_incident_readback_plan_post_incident_readback_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_argocd_app_health_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_argocd_sync_status_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_degraded_state_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_pending_workload_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_image_pull_or_scheduling_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_metrics_alert_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_cross_project_sync_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_no_false_green_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_argocd_api_read_authorized_count=0",
"k8s_argocd_post_incident_readback_plan_argocd_sync_authorized_count=0",
"k8s_argocd_post_incident_readback_plan_kubectl_action_authorized_count=0",
"k8s_argocd_post_incident_readback_plan_runtime_gate_count=0",
"k8s_argocd_post_incident_readback_plan_action_button_count=0",
"public_gateway_rendered_diff_acceptance_candidate_count=3",
"public_gateway_rendered_diff_acceptance_reviewer_check_count=15",
"public_gateway_rendered_diff_acceptance_runtime_gate_count=0",
@@ -17579,7 +17664,7 @@ def validate(root: Path) -> None:
assert_text_contains(
"iwooos_page.critical_config_priority_k8s_percent",
iwooos_projection_page,
"{ key: 'k8sArgocd', rank: 'P0-3', state: '64% / sync 0'",
"{ key: 'k8sArgocd', rank: 'P0-3', state: '66% / readback 0'",
)
assert_text_contains(
"iwooos_page.critical_config_priority_workflow_secret_percent",
@@ -17656,6 +17741,16 @@ def validate(root: Path) -> None:
"k8s_argocd_change_evidence_acceptance_accepted_count=0",
"k8s_argocd_change_evidence_acceptance_runtime_approval_package_ready_count=0",
"k8s_argocd_change_evidence_acceptance_runtime_gate_count=0",
"k8s_argocd_post_incident_readback_plan_candidate_count=4",
"k8s_argocd_post_incident_readback_plan_c0_candidate_count=3",
"k8s_argocd_post_incident_readback_plan_write_capable_candidate_count=4",
"k8s_argocd_post_incident_readback_plan_required_readback_field_count=31",
"k8s_argocd_post_incident_readback_plan_reviewer_check_count=28",
"k8s_argocd_post_incident_readback_plan_outcome_lane_count=10",
"k8s_argocd_post_incident_readback_plan_blocked_action_count=41",
"k8s_argocd_post_incident_readback_plan_post_incident_readback_received_count=0",
"k8s_argocd_post_incident_readback_plan_post_incident_readback_accepted_count=0",
"k8s_argocd_post_incident_readback_plan_runtime_gate_count=0",
"argocd_api_read_authorized=false",
"argocd_sync_authorized=false",
"kubectl_action_authorized=false",
@@ -19087,6 +19182,223 @@ def validate(root: Path) -> None:
f"k8s_argocd_change_evidence_acceptance.{item['change_evidence_candidate_id']}.{false_key}",
item[false_key],
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.schema",
k8s_argocd_post_incident_readback_plan["schema_version"],
"k8s_argocd_post_incident_readback_plan_v1",
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.status",
k8s_argocd_post_incident_readback_plan["status"],
"post_incident_readback_plan_ready_no_runtime_action",
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.source_schema_version",
k8s_argocd_post_incident_readback_plan["source_schema_version"],
"k8s_argocd_change_evidence_acceptance_v1",
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.source_status",
k8s_argocd_post_incident_readback_plan["source_status"],
"change_evidence_acceptance_ledger_ready_no_runtime_action",
)
for source_path in [
"docs/security/K8S-ARGOCD-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/k8s-argocd-change-evidence-acceptance.snapshot.json",
]:
assert_contains(
"k8s_argocd_post_incident_readback_plan.source_paths",
k8s_argocd_post_incident_readback_plan["source_paths"],
source_path,
)
expected_k8s_post_incident_summary = {
"source_scan_group_count": 4,
"source_change_evidence_candidate_count": 4,
"source_c0_change_evidence_candidate_count": 3,
"source_c1_change_evidence_candidate_count": 1,
"source_write_capable_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,
"readback_candidate_count": 4,
"c0_readback_candidate_count": 3,
"c1_readback_candidate_count": 1,
"write_capable_readback_candidate_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,
}
for key, expected in expected_k8s_post_incident_summary.items():
assert_equal(
f"k8s_argocd_post_incident_readback_plan.summary.{key}",
k8s_argocd_post_incident_readback_plan["summary"][key],
expected,
)
for key, value in k8s_argocd_post_incident_readback_plan["boundaries"].items():
if key == "not_authorization":
assert_true(f"k8s_argocd_post_incident_readback_plan.boundaries.{key}", value)
else:
assert_false(f"k8s_argocd_post_incident_readback_plan.boundaries.{key}", value)
expected_k8s_post_incident_ids = [
"k8s_argocd_post_incident_readback:awoooi_prod",
"k8s_argocd_post_incident_readback:argocd",
"k8s_argocd_post_incident_readback:velero",
"k8s_argocd_post_incident_readback:monitoring",
]
assert_equal(
"k8s_argocd_post_incident_readback_plan.readback_candidate_ids",
[
item["post_incident_readback_candidate_id"]
for item in k8s_argocd_post_incident_readback_plan["readback_candidates"]
],
expected_k8s_post_incident_ids,
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.reviewer_checks.count",
len(k8s_argocd_post_incident_readback_plan["reviewer_checks"]),
28,
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.outcome_lanes.count",
len(k8s_argocd_post_incident_readback_plan["outcome_lanes"]),
10,
)
assert_equal(
"k8s_argocd_post_incident_readback_plan.blocked_actions.count",
len(k8s_argocd_post_incident_readback_plan["blocked_actions"]),
41,
)
for item in k8s_argocd_post_incident_readback_plan["readback_candidates"]:
assert_equal(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.readback_fields",
len(item["readback_fields"]),
36,
)
assert_equal(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.required_readback_fields",
len(item["required_readback_fields"]),
31,
)
assert_equal(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.reviewer_checks",
len(item["reviewer_checks"]),
28,
)
assert_equal(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.outcome_lanes",
len(item["outcome_lanes"]),
10,
)
assert_equal(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.blocked_actions",
len(item["blocked_actions"]),
41,
)
assert_true(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.not_approval",
item["not_approval"],
)
assert_true(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.write_capable",
item["write_capable"],
)
for false_key in [
"post_incident_readback_received",
"post_incident_readback_accepted",
"actor_attribution_accepted",
"argocd_app_health_accepted",
"argocd_sync_status_accepted",
"degraded_state_accepted",
"pending_workload_accepted",
"image_pull_or_scheduling_accepted",
"rollout_before_after_accepted",
"event_summary_accepted",
"metrics_alert_accepted",
"drift_scanner_accepted",
"cronjob_schedule_accepted",
"network_policy_service_impact_accepted",
"rbac_serviceaccount_impact_accepted",
"secret_metadata_parity_accepted",
"public_admin_route_impact_accepted",
"ai_provider_monitoring_impact_accepted",
"backup_restore_impact_accepted",
"operator_notification_accepted",
"cross_project_sync_accepted",
"recovery_or_still_degraded_accepted",
"postcheck_readback_accepted",
"recurrence_guard_accepted",
"no_false_green_accepted",
"argocd_api_read_authorized",
"argocd_sync_authorized",
"live_cluster_read_authorized",
"kubectl_action_authorized",
"helm_action_authorized",
"network_policy_change_authorized",
"nodeport_change_authorized",
"rbac_change_authorized",
"secret_value_collection_allowed",
"route_smoke_authorized",
"production_write_authorized",
"runtime_gate",
"action_buttons_allowed",
]:
assert_false(
f"k8s_argocd_post_incident_readback_plan.{item['post_incident_readback_candidate_id']}.{false_key}",
item[false_key],
)
assert_equal(
"cd_runner_secret_injection_change_evidence_acceptance.schema",
cd_runner_secret_injection_change_evidence_acceptance["schema_version"],