feat(smoke): monitor pchome signing execution preflight
Some checks failed
CD Pipeline / deploy (push) Has been cancelled

This commit is contained in:
ogt
2026-07-03 10:00:38 +08:00
parent 6ee4244079
commit 2326227fed
6 changed files with 874 additions and 18 deletions

View File

@@ -107,10 +107,10 @@ def test_system_metrics_exports_scheduled_health_summary():
Gauge,
{
"summary": {
"ok": 12,
"ok": 13,
"warning": 1,
"critical": 0,
"total": 13,
"total": 14,
"primary_human_gate_count": 0,
"writes_database_count": 0,
},
@@ -125,6 +125,7 @@ def test_system_metrics_exports_scheduled_health_summary():
{"key": "pchome_auto_policy_signing_decision_closeout", "status": "ok"},
{"key": "pchome_auto_policy_signing_issuer_guard", "status": "ok"},
{"key": "pchome_auto_policy_signing_issuer_closeout", "status": "ok"},
{"key": "pchome_auto_policy_signing_execution_preflight", "status": "ok"},
{"key": "sitewide_ui_ux_agent", "status": "ok"},
{"key": "sitewide_visual_qa", "status": "ok"},
],
@@ -132,7 +133,7 @@ def test_system_metrics_exports_scheduled_health_summary():
)
output = generate_latest(registry).decode("utf-8")
assert 'momo_ai_automation_scheduled_health_summary_total{status="ok"} 12.0' in output
assert 'momo_ai_automation_scheduled_health_summary_total{status="ok"} 13.0' in output
assert 'momo_ai_automation_scheduled_health_summary_total{status="warning"} 1.0' in output
assert (
'momo_ai_automation_scheduled_health_family_status{family="ai_automation_smoke",status="ok"} 1.0'
@@ -174,6 +175,10 @@ def test_system_metrics_exports_scheduled_health_summary():
'momo_ai_automation_scheduled_health_family_status{family="pchome_auto_policy_signing_issuer_closeout",status="ok"} 1.0'
in output
)
assert (
'momo_ai_automation_scheduled_health_family_status{family="pchome_auto_policy_signing_execution_preflight",status="ok"} 1.0'
in output
)
assert (
'momo_ai_automation_scheduled_health_family_status{family="sitewide_ui_ux_agent",status="ok"} 1.0'
in output

View File

@@ -316,6 +316,59 @@ def _auto_policy_signing_issuer_closeout_history_check(status="ok"):
}
def _auto_policy_signing_execution_preflight_history_check(status="ok"):
return {
"name": "PChome auto-policy signing execution preflight",
"status": status,
"summary": "PChome auto-policy signing execution preflight 已自動完成",
"details": {
"policy": (
"read_only_pchome_growth_auto_policy_db_apply_authorization_"
"signing_execution_preflight"
),
"result": "DB_APPLY_AUTHORIZATION_SIGNING_EXECUTION_PREFLIGHT_READY",
"signing_execution_preflight_ready_count": 1,
"signing_execution_preflight_check_count": 12,
"signing_execution_preflight_pass_count": 12,
"signing_execution_preflight_waiting_count": 0,
"signing_issuer_closeout_ready_count": 1,
"signing_issuer_closeout_check_count": 12,
"signing_issuer_closeout_pass_count": 12,
"final_signable_request_package_ready_count": 1,
"operator_held_secret_boundary_count": 1,
"signing_execution_input_requirement_count": 10,
"signing_execution_abort_condition_count": 8,
"rollback_boundary_count": 4,
"post_apply_verifier_required_count": 1,
"same_run_truth_required_count": 1,
"reads_secret_count": 0,
"executes_script_count": 0,
"executes_sql_count": 0,
"writes_database_count": 0,
"signs_database_apply_authorization_count": 0,
"primary_human_gate_count": 0,
"manual_review_mode": "exception_only",
"payload_source": "local_contract_fixture",
"execute_fetch": True,
"outbound_network": False,
"business_data_source": False,
"secret_reference_mode": "external_runtime_reference_only",
"command_preview_redacts_secret_values": True,
"command_preview_executes_in_preview": False,
"ready_for_database_apply_now": False,
"issues_database_apply_authorization": False,
"signs_database_apply_authorization": False,
"secret_material_included": False,
"secret_material_required_in_preview": False,
"ready_for_future_signing_execution_preflight": True,
"permits_future_explicit_authorization_signing_execution_lane": True,
"next_machine_action": (
"continue_to_pchome_auto_policy_signing_execution_closeout_lane"
),
},
}
def test_event_router_smoke_reports_queued_deliveries(tmp_path, monkeypatch):
from services import ai_automation_metrics as metrics
from services import ai_automation_smoke_service as smoke
@@ -359,6 +412,7 @@ def test_collect_ai_automation_smoke_uses_worst_status(monkeypatch):
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_decision_closeout_check", lambda: smoke._check("auto-policy signing closeout", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_issuer_guard_check", lambda: smoke._check("auto-policy signing issuer guard", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_issuer_closeout_check", lambda: smoke._check("auto-policy signing issuer closeout", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_execution_preflight_check", lambda: smoke._check("auto-policy signing execution preflight", "ok", "ok"))
monkeypatch.setattr(smoke, "_ai_surface_html_readback_check", lambda: smoke._check("surface", "ok", "ok"))
monkeypatch.setattr(smoke, "_sitewide_ui_ux_agent_check", lambda: smoke._check("sitewide", "ok", "ok"))
monkeypatch.setattr(smoke, "_sitewide_visual_qa_check", lambda: smoke._check("visual", "ok", "ok"))
@@ -366,7 +420,7 @@ def test_collect_ai_automation_smoke_uses_worst_status(monkeypatch):
result = smoke.collect_ai_automation_smoke(record_history=False)
assert result["status"] == "critical"
assert result["summary"] == {"ok": 16, "warning": 1, "critical": 1, "total": 18}
assert result["summary"] == {"ok": 17, "warning": 1, "critical": 1, "total": 19}
def test_pchome_controlled_apply_drift_monitor_reports_verified_zero_drift(monkeypatch):
@@ -1156,6 +1210,161 @@ def test_pchome_auto_policy_signing_issuer_closeout_reports_final_signable_no_wr
)
def test_pchome_auto_policy_signing_execution_preflight_reports_operator_secret_boundary_no_write(monkeypatch):
from services import ai_automation_smoke_service as smoke
from services import pchome_mapping_backlog_service as backlog
captured = {}
def fake_preflight(*_args, **kwargs):
captured.update(kwargs)
return {
"policy": (
"read_only_pchome_growth_auto_policy_db_apply_authorization_"
"signing_execution_preflight"
),
"result": "DB_APPLY_AUTHORIZATION_SIGNING_EXECUTION_PREFLIGHT_READY",
"source_policy": (
"read_only_pchome_growth_auto_policy_db_apply_authorization_"
"signing_issuer_closeout"
),
"summary": {
"authorization_signing_execution_preflight_ready_count": 1,
"signing_execution_preflight_check_count": 12,
"signing_execution_preflight_pass_count": 12,
"signing_execution_preflight_waiting_count": 0,
"authorization_signing_issuer_closeout_ready_count": 1,
"signing_issuer_closeout_check_count": 12,
"signing_issuer_closeout_pass_count": 12,
"final_signable_request_package_ready_count": 1,
"operator_held_secret_boundary_count": 1,
"signing_execution_input_requirement_count": 10,
"signing_execution_abort_condition_count": 8,
"rollback_boundary_count": 4,
"post_apply_verifier_required_count": 1,
"same_run_truth_required_count": 1,
"writes_script_count": 0,
"writes_artifact_count": 0,
"reads_secret_count": 0,
"executes_script_count": 0,
"executes_migration_count": 0,
"executes_endpoint_count": 0,
"executes_sql_count": 0,
"writes_database_count": 0,
"signs_database_apply_authorization_count": 0,
"primary_human_gate_count": 0,
"manual_review_required_count": 0,
},
"future_authorization_signing_execution_preflight": {
"ready_for_future_signing_execution_preflight": True,
"can_enter_future_authorization_signing_execution_lane": True,
"ready_for_database_apply_now": False,
"issues_database_apply_authorization": False,
"signs_database_apply_authorization": False,
"secret_material_included": False,
"secret_material_required_in_preview": False,
"reads_secret_in_preview": False,
},
"signing_execution_preflight_package": {
"authorization_material_type": "signing_execution_preflight_package",
"ready_for_future_signing_execution_preflight": True,
"ready_for_database_apply_now": False,
"issues_database_apply_authorization": False,
"signs_database_apply_authorization": False,
"required_nonsecret_input_count": 10,
"hash_matches": True,
"requires_post_apply_verifier": True,
"requires_fresh_production_truth_in_same_run": True,
"secret_material_included": False,
"secret_material_required_in_preview": False,
"reads_secret_in_preview": False,
"executes_shell_in_preview": False,
"executes_sql_in_preview": False,
"writes_database_in_preview": False,
"command_preview": {
"mode": "future_command_shape_only",
"redacts_secret_values": True,
"executes_in_preview": False,
"signs_database_apply_authorization": False,
"writes_database": False,
},
},
"operator_held_secret_boundary_contract": {
"secret_reference_mode": "external_runtime_reference_only",
"secret_material_included": False,
"secret_material_required_in_preview": False,
"reads_secret_in_preview": False,
"accepts_plaintext_secret": False,
"permits_secret_value_logging": False,
},
"signing_execution_preflight_contract": {
"machine_verifiable": True,
"permits_future_explicit_authorization_signing_execution_lane": True,
"issues_database_apply_authorization": False,
"ready_for_database_apply_now": False,
"signs_database_apply_authorization": False,
"writes_database": False,
"executes_in_preview": False,
"secret_material_required_in_preview": False,
},
"safety": {
"reads_secret_in_preview": False,
"writes_file": False,
"writes_script_in_preview": False,
"writes_artifact_in_preview": False,
"executes_script": False,
"executes_endpoint": False,
"executes_migration": False,
"executes_sql": False,
"writes_database": False,
"signs_database_apply_authorization": False,
"manual_review_mode": "exception_only",
},
}
monkeypatch.setattr(
backlog,
"build_pchome_auto_policy_db_apply_authorization_signing_execution_preflight",
fake_preflight,
)
result = smoke._pchome_auto_policy_signing_execution_preflight_check()
assert result["status"] == "ok"
assert captured["execute_fetch"] is True
assert captured["http_get"] is smoke._pchome_auto_policy_machine_fetch_evidence_get
assert result["details"]["signing_execution_preflight_pass_count"] == 12
assert result["details"]["signing_issuer_closeout_check_count"] == 12
assert result["details"]["final_signable_request_package_ready_count"] == 1
assert result["details"]["operator_held_secret_boundary_count"] == 1
assert result["details"]["signing_execution_input_requirement_count"] == 10
assert result["details"]["signing_execution_abort_condition_count"] == 8
assert result["details"]["rollback_boundary_count"] == 4
assert result["details"]["payload_source"] == "local_contract_fixture"
assert result["details"]["machine_fetch_evidence_source"] == "local_schema_fixture"
assert result["details"]["outbound_network"] is False
assert result["details"]["business_data_source"] is False
assert result["details"]["primary_human_gate_count"] == 0
assert result["details"]["reads_secret_count"] == 0
assert result["details"]["writes_database_count"] == 0
assert result["details"]["signs_database_apply_authorization_count"] == 0
assert result["details"]["secret_reference_mode"] == "external_runtime_reference_only"
assert result["details"]["command_preview_redacts_secret_values"] is True
assert result["details"]["command_preview_executes_in_preview"] is False
assert result["details"]["issues_database_apply_authorization"] is False
assert result["details"]["signs_database_apply_authorization"] is False
assert result["details"]["secret_material_included"] is False
assert result["details"]["secret_material_required_in_preview"] is False
assert result["details"]["ready_for_future_signing_execution_preflight"] is True
assert (
result["details"]["permits_future_explicit_authorization_signing_execution_lane"]
is True
)
assert result["details"]["next_machine_action"] == (
"continue_to_pchome_auto_policy_signing_execution_closeout_lane"
)
def test_collect_ai_automation_smoke_persists_recent_history(tmp_path, monkeypatch):
from services import ai_automation_smoke_service as smoke
@@ -1177,6 +1386,7 @@ def test_collect_ai_automation_smoke_persists_recent_history(tmp_path, monkeypat
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_decision_closeout_check", lambda: smoke._check("auto-policy signing closeout", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_issuer_guard_check", lambda: smoke._check("auto-policy signing issuer guard", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_issuer_closeout_check", lambda: smoke._check("auto-policy signing issuer closeout", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_execution_preflight_check", lambda: smoke._check("auto-policy signing execution preflight", "ok", "ok"))
monkeypatch.setattr(smoke, "_ai_surface_html_readback_check", lambda: smoke._check("surface", "ok", "ok"))
monkeypatch.setattr(smoke, "_sitewide_ui_ux_agent_check", lambda: smoke._check("sitewide", "ok", "ok"))
monkeypatch.setattr(smoke, "_sitewide_visual_qa_check", lambda: smoke._check("visual", "ok", "ok"))
@@ -1235,7 +1445,7 @@ def test_scheduled_automation_health_summary_reads_history_without_side_effects(
json.dumps({
"generated_at": datetime.now().isoformat(timespec="seconds"),
"status": "ok",
"summary": {"ok": 18, "warning": 0, "critical": 0, "total": 18},
"summary": {"ok": 19, "warning": 0, "critical": 0, "total": 19},
"checks": [
{
"name": "PChome 受控落地 drift monitor",
@@ -1257,6 +1467,7 @@ def test_scheduled_automation_health_summary_reads_history_without_side_effects(
_auto_policy_signing_decision_closeout_history_check(),
_auto_policy_signing_issuer_guard_history_check(),
_auto_policy_signing_issuer_closeout_history_check(),
_auto_policy_signing_execution_preflight_history_check(),
{
"name": "AI surface HTML readback",
"status": "ok",
@@ -1318,7 +1529,7 @@ def test_scheduled_automation_health_summary_reads_history_without_side_effects(
)
assert summary["policy"] == "read_only_ai_automation_scheduled_health_summary"
assert summary["status"] == "ok"
assert summary["summary"]["total"] == 15
assert summary["summary"]["total"] == 16
assert summary["summary"]["primary_human_gate_count"] == 0
assert summary["summary"]["writes_database_count"] == 0
assert pchome_family["status"] == "ok"
@@ -1478,6 +1689,93 @@ def test_scheduled_automation_health_summary_reads_history_without_side_effects(
]
is True
)
signing_execution_preflight_family = next(
item for item in summary["families"]
if item["key"] == "pchome_auto_policy_signing_execution_preflight"
)
assert signing_execution_preflight_family["status"] == "ok"
assert (
signing_execution_preflight_family["details"][
"signing_execution_preflight_pass_count"
]
== 12
)
assert (
signing_execution_preflight_family["details"][
"signing_issuer_closeout_check_count"
]
== 12
)
assert (
signing_execution_preflight_family["details"][
"final_signable_request_package_ready_count"
]
== 1
)
assert (
signing_execution_preflight_family["details"][
"operator_held_secret_boundary_count"
]
== 1
)
assert (
signing_execution_preflight_family["details"][
"signing_execution_input_requirement_count"
]
== 10
)
assert (
signing_execution_preflight_family["details"][
"signing_execution_abort_condition_count"
]
== 8
)
assert signing_execution_preflight_family["details"]["rollback_boundary_count"] == 4
assert (
signing_execution_preflight_family["details"]["payload_source"]
== "local_contract_fixture"
)
assert signing_execution_preflight_family["details"]["outbound_network"] is False
assert signing_execution_preflight_family["details"]["business_data_source"] is False
assert signing_execution_preflight_family["details"]["primary_human_gate_count"] == 0
assert signing_execution_preflight_family["details"]["reads_secret_count"] == 0
assert signing_execution_preflight_family["details"]["writes_database_count"] == 0
assert (
signing_execution_preflight_family["details"][
"signs_database_apply_authorization_count"
]
== 0
)
assert (
signing_execution_preflight_family["details"]["secret_reference_mode"]
== "external_runtime_reference_only"
)
assert (
signing_execution_preflight_family["details"][
"command_preview_redacts_secret_values"
]
is True
)
assert (
signing_execution_preflight_family["details"][
"command_preview_executes_in_preview"
]
is False
)
assert (
signing_execution_preflight_family["details"]["signs_database_apply_authorization"]
is False
)
assert (
signing_execution_preflight_family["details"]["secret_material_included"]
is False
)
assert (
signing_execution_preflight_family["details"][
"ready_for_future_signing_execution_preflight"
]
is True
)
surface_family = next(
item for item in summary["families"]
if item["key"] == "ai_surface_html_readback"
@@ -1512,7 +1810,7 @@ def test_scheduled_automation_health_summary_can_use_current_smoke_without_recor
current_smoke = {
"generated_at": "2026-07-02T12:00:00",
"status": "critical",
"summary": {"ok": 17, "warning": 0, "critical": 1, "total": 18},
"summary": {"ok": 18, "warning": 0, "critical": 1, "total": 19},
"checks": [
{
"name": "PChome 受控落地 drift monitor",
@@ -1528,6 +1826,7 @@ def test_scheduled_automation_health_summary_can_use_current_smoke_without_recor
_auto_policy_signing_decision_closeout_history_check(),
_auto_policy_signing_issuer_guard_history_check(),
_auto_policy_signing_issuer_closeout_history_check(),
_auto_policy_signing_execution_preflight_history_check(),
{
"name": "AI surface HTML readback",
"status": "ok",
@@ -1583,7 +1882,7 @@ def test_scheduled_automation_health_summary_falls_back_to_visual_qa_artifact(tm
json.dumps({
"generated_at": datetime.now().isoformat(timespec="seconds"),
"status": "ok",
"summary": {"ok": 16, "warning": 0, "critical": 0, "total": 16},
"summary": {"ok": 17, "warning": 0, "critical": 0, "total": 17},
"checks": [],
}, ensure_ascii=False) + "\n",
encoding="utf-8",
@@ -1629,6 +1928,11 @@ def test_scheduled_automation_health_summary_falls_back_to_visual_qa_artifact(tm
"_pchome_auto_policy_signing_issuer_closeout_check",
lambda: _auto_policy_signing_issuer_closeout_history_check(),
)
monkeypatch.setattr(
smoke,
"_pchome_auto_policy_signing_execution_preflight_check",
lambda: _auto_policy_signing_execution_preflight_history_check(),
)
monkeypatch.setattr(
surface_service,
"build_sitewide_visual_qa_readback",
@@ -1677,7 +1981,7 @@ def test_scheduled_automation_health_summary_route_returns_compact_payload(tmp_p
json.dumps({
"generated_at": datetime.now().isoformat(timespec="seconds"),
"status": "ok",
"summary": {"ok": 17, "warning": 0, "critical": 0, "total": 17},
"summary": {"ok": 18, "warning": 0, "critical": 0, "total": 18},
"checks": [],
}, ensure_ascii=False) + "\n",
encoding="utf-8",
@@ -1723,6 +2027,11 @@ def test_scheduled_automation_health_summary_route_returns_compact_payload(tmp_p
"_pchome_auto_policy_signing_issuer_closeout_check",
lambda: _auto_policy_signing_issuer_closeout_history_check(),
)
monkeypatch.setattr(
smoke,
"_pchome_auto_policy_signing_execution_preflight_check",
lambda: _auto_policy_signing_execution_preflight_history_check(),
)
app = Flask(__name__)
with app.test_request_context(
@@ -1954,6 +2263,7 @@ def test_surface_html_readback_check_is_part_of_ai_smoke(monkeypatch):
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_decision_closeout_check", lambda: smoke._check("auto-policy signing closeout", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_issuer_guard_check", lambda: smoke._check("auto-policy signing issuer guard", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_issuer_closeout_check", lambda: smoke._check("auto-policy signing issuer closeout", "ok", "ok"))
monkeypatch.setattr(smoke, "_pchome_auto_policy_signing_execution_preflight_check", lambda: smoke._check("auto-policy signing execution preflight", "ok", "ok"))
monkeypatch.setattr(smoke, "_sitewide_visual_qa_check", lambda: smoke._check(
"Sitewide visual QA readback",
"ok",
@@ -1975,7 +2285,7 @@ def test_surface_html_readback_check_is_part_of_ai_smoke(monkeypatch):
item for item in result["checks"]
if item["name"] == "Sitewide visual QA readback"
)
assert result["summary"]["total"] == 18
assert result["summary"]["total"] == 19
assert surface_check["status"] == "ok"
assert surface_check["details"]["checked_surface_count"] == 10
assert sitewide_check["status"] == "ok"