test(iwooos): 強化 gateway 變更 metadata gate [skip ci]
This commit is contained in:
@@ -112,10 +112,10 @@ ARTIFACT_SPECS = [
|
||||
"status": "owner_response_acceptance_ledger_ready_no_runtime_action",
|
||||
"list_counts": {
|
||||
"acceptance_candidates": 3,
|
||||
"blocked_actions": 18,
|
||||
"reviewer_checks": 12,
|
||||
"blocked_actions": 22,
|
||||
"reviewer_checks": 16,
|
||||
"outcome_lanes": 7,
|
||||
"required_owner_response_fields": 12,
|
||||
"required_owner_response_fields": 16,
|
||||
},
|
||||
"summary_counts": {
|
||||
"acceptance_candidate_count": 3,
|
||||
|
||||
@@ -42,6 +42,10 @@ ACCEPTANCE_FIELDS = [
|
||||
"maintenance_window",
|
||||
"rollback_owner",
|
||||
"postcheck_plan",
|
||||
"change_actor_or_source_ref",
|
||||
"change_time_window",
|
||||
"cross_project_impact_ref",
|
||||
"communication_sync_ref",
|
||||
"reviewer_outcome",
|
||||
"followup_owner",
|
||||
"not_approval",
|
||||
@@ -59,6 +63,10 @@ REQUIRED_OWNER_RESPONSE_FIELDS = [
|
||||
"maintenance_window",
|
||||
"rollback_owner",
|
||||
"postcheck_plan",
|
||||
"change_actor_or_source_ref",
|
||||
"change_time_window",
|
||||
"cross_project_impact_ref",
|
||||
"communication_sync_ref",
|
||||
"followup_owner",
|
||||
]
|
||||
|
||||
@@ -107,6 +115,22 @@ REVIEWER_CHECKS = [
|
||||
"check_id": "rollback_owner_present",
|
||||
"instruction": "rollback owner 與 rollback ref 必須存在,且不可指向 raw secret。",
|
||||
},
|
||||
{
|
||||
"check_id": "change_actor_or_source_ref_present",
|
||||
"instruction": "若曾有手動或緊急變更,必須提供脫敏 actor / source ref;不得要求個人帳密或 raw shell history。",
|
||||
},
|
||||
{
|
||||
"check_id": "change_time_window_present",
|
||||
"instruction": "必須提供變更或事故時間窗,讓 route smoke、告警與跨專案影響可對齊。",
|
||||
},
|
||||
{
|
||||
"check_id": "cross_project_impact_review_present",
|
||||
"instruction": "必須提供跨產品 / 跨專案影響 ref,避免只修單一路由卻讓其他服務斷線。",
|
||||
},
|
||||
{
|
||||
"check_id": "communication_sync_ref_present",
|
||||
"instruction": "必須提供通知或協調 ref,證明相關專案 owner 已收到影響與回復狀態。",
|
||||
},
|
||||
{
|
||||
"check_id": "counts_transition_safe",
|
||||
"instruction": "只有 reviewer record 可更新 received / accepted / rejected;不得同時開 runtime gate。",
|
||||
@@ -161,6 +185,10 @@ BLOCKED_ACTIONS = [
|
||||
"modify_dns_tls_config",
|
||||
"change_public_route",
|
||||
"write_production_host",
|
||||
"accept_unknown_change_actor",
|
||||
"accept_missing_change_time_window",
|
||||
"skip_cross_project_impact_review",
|
||||
"skip_incident_communication_sync",
|
||||
"open_runtime_gate",
|
||||
"add_action_button",
|
||||
]
|
||||
@@ -208,6 +236,10 @@ def acceptance_candidate(diff_gate: dict[str, Any]) -> dict[str, Any]:
|
||||
"maintenance_window": "pending_owner_response",
|
||||
"rollback_owner": "pending_owner_response",
|
||||
"postcheck_plan": "pending_owner_response",
|
||||
"change_actor_or_source_ref": None,
|
||||
"change_time_window": "pending_owner_response",
|
||||
"cross_project_impact_ref": None,
|
||||
"communication_sync_ref": None,
|
||||
"reviewer_outcome": "waiting_owner_response",
|
||||
"followup_owner": "pending_owner_response",
|
||||
"acceptance_fields": ACCEPTANCE_FIELDS,
|
||||
@@ -300,6 +332,10 @@ def build_report(
|
||||
"certbot_renew_authorized_count": 0,
|
||||
"maintenance_window_accepted_count": 0,
|
||||
"rollback_owner_accepted_count": 0,
|
||||
"change_actor_identified_count": 0,
|
||||
"change_time_window_accepted_count": 0,
|
||||
"cross_project_impact_accepted_count": 0,
|
||||
"communication_sync_accepted_count": 0,
|
||||
"runtime_gate_count": 0,
|
||||
"action_button_count": 0,
|
||||
},
|
||||
@@ -333,6 +369,7 @@ def build_report(
|
||||
"等待 owner response;未收到前不得更新 accepted count。",
|
||||
"收到回覆後先走 raw payload / secret / scope / evidence ref 檢查,不合格即隔離、拒收或補件。",
|
||||
"metadata 合格也只能進 rendered diff reviewer review;`nginx -t`、reload、route smoke 與 production write 仍需獨立人工批准。",
|
||||
"若涉及手動或緊急 gateway 變更,必須先補 change actor/source、time window、cross-project impact 與 communication sync refs。",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -5574,11 +5574,11 @@ def validate(root: Path) -> None:
|
||||
"acceptance_candidate_count": 3,
|
||||
"c0_acceptance_candidate_count": 2,
|
||||
"c1_acceptance_candidate_count": 1,
|
||||
"acceptance_field_count": 23,
|
||||
"required_owner_response_field_count": 12,
|
||||
"reviewer_check_count": 12,
|
||||
"acceptance_field_count": 27,
|
||||
"required_owner_response_field_count": 16,
|
||||
"reviewer_check_count": 16,
|
||||
"outcome_lane_count": 7,
|
||||
"blocked_action_count": 18,
|
||||
"blocked_action_count": 22,
|
||||
"request_sent_count": 0,
|
||||
"recipient_confirmed_count": 0,
|
||||
"owner_response_received_count": 0,
|
||||
@@ -5600,6 +5600,10 @@ def validate(root: Path) -> None:
|
||||
"certbot_renew_authorized_count": 0,
|
||||
"maintenance_window_accepted_count": 0,
|
||||
"rollback_owner_accepted_count": 0,
|
||||
"change_actor_identified_count": 0,
|
||||
"change_time_window_accepted_count": 0,
|
||||
"cross_project_impact_accepted_count": 0,
|
||||
"communication_sync_accepted_count": 0,
|
||||
"runtime_gate_count": 0,
|
||||
"action_button_count": 0,
|
||||
}
|
||||
@@ -5639,6 +5643,10 @@ def validate(root: Path) -> None:
|
||||
"route_smoke_plan_present",
|
||||
"maintenance_window_present",
|
||||
"rollback_owner_present",
|
||||
"change_actor_or_source_ref_present",
|
||||
"change_time_window_present",
|
||||
"cross_project_impact_review_present",
|
||||
"communication_sync_ref_present",
|
||||
"counts_transition_safe",
|
||||
]
|
||||
assert_equal(
|
||||
@@ -5677,6 +5685,10 @@ def validate(root: Path) -> None:
|
||||
"modify_dns_tls_config",
|
||||
"change_public_route",
|
||||
"write_production_host",
|
||||
"accept_unknown_change_actor",
|
||||
"accept_missing_change_time_window",
|
||||
"skip_cross_project_impact_review",
|
||||
"skip_incident_communication_sync",
|
||||
"open_runtime_gate",
|
||||
"add_action_button",
|
||||
]
|
||||
@@ -5689,17 +5701,17 @@ def validate(root: Path) -> None:
|
||||
assert_equal(
|
||||
f"public_gateway_owner_response_acceptance.{item['acceptance_candidate_id']}.field_count",
|
||||
len(item["acceptance_fields"]),
|
||||
23,
|
||||
27,
|
||||
)
|
||||
assert_equal(
|
||||
f"public_gateway_owner_response_acceptance.{item['acceptance_candidate_id']}.required_owner_response_fields",
|
||||
len(item["required_owner_response_fields"]),
|
||||
12,
|
||||
16,
|
||||
)
|
||||
assert_equal(
|
||||
f"public_gateway_owner_response_acceptance.{item['acceptance_candidate_id']}.reviewer_checks",
|
||||
len(item["reviewer_checks"]),
|
||||
12,
|
||||
16,
|
||||
)
|
||||
assert_equal(
|
||||
f"public_gateway_owner_response_acceptance.{item['acceptance_candidate_id']}.outcome_lanes",
|
||||
@@ -5709,7 +5721,7 @@ def validate(root: Path) -> None:
|
||||
assert_equal(
|
||||
f"public_gateway_owner_response_acceptance.{item['acceptance_candidate_id']}.blocked_actions",
|
||||
len(item["blocked_actions"]),
|
||||
18,
|
||||
22,
|
||||
)
|
||||
assert_true(
|
||||
f"public_gateway_owner_response_acceptance.{item['acceptance_candidate_id']}.not_approval",
|
||||
|
||||
Reference in New Issue
Block a user