feat(smoke): monitor pchome decision closeout
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
This commit is contained in:
@@ -239,6 +239,11 @@ def build_scheduled_automation_health_summary(
|
||||
if not auto_policy_preflight or not auto_policy_preflight_details:
|
||||
auto_policy_preflight = _pchome_auto_policy_decision_preflight_check()
|
||||
auto_policy_preflight_details = auto_policy_preflight.get("details") or {}
|
||||
auto_policy_closeout = _find_check(source_result, "PChome auto-policy decision closeout")
|
||||
auto_policy_closeout_details = auto_policy_closeout.get("details") or {}
|
||||
if not auto_policy_closeout or not auto_policy_closeout_details:
|
||||
auto_policy_closeout = _pchome_auto_policy_decision_closeout_check()
|
||||
auto_policy_closeout_details = auto_policy_closeout.get("details") or {}
|
||||
surface_readback = _find_check(source_result, "AI surface HTML readback")
|
||||
surface_details = surface_readback.get("details") or {}
|
||||
sitewide_readback = _find_check(source_result, "Sitewide UI/UX Agent readback")
|
||||
@@ -414,6 +419,69 @@ def build_scheduled_automation_health_summary(
|
||||
"writes_database": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"key": "pchome_auto_policy_decision_closeout",
|
||||
"label": "PChome auto-policy decision closeout",
|
||||
"status": auto_policy_closeout.get("status") or "warning",
|
||||
"summary": (
|
||||
auto_policy_closeout.get("summary")
|
||||
or "PChome auto-policy decision closeout has no latest check."
|
||||
),
|
||||
"next_machine_action": auto_policy_closeout_details.get("next_machine_action")
|
||||
or (
|
||||
"continue_pchome_auto_policy_decision_closeout_monitoring"
|
||||
if auto_policy_closeout.get("status") == "ok"
|
||||
else "refresh_pchome_auto_policy_decision_closeout"
|
||||
),
|
||||
"details": {
|
||||
"policy": auto_policy_closeout_details.get("policy"),
|
||||
"result": auto_policy_closeout_details.get("result"),
|
||||
"decision_closeout_ready_count": int(
|
||||
auto_policy_closeout_details.get("decision_closeout_ready_count") or 0
|
||||
),
|
||||
"decision_preflight_ready_count": int(
|
||||
auto_policy_closeout_details.get("decision_preflight_ready_count") or 0
|
||||
),
|
||||
"decision_closeout_check_count": int(
|
||||
auto_policy_closeout_details.get("decision_closeout_check_count") or 0
|
||||
),
|
||||
"decision_closeout_pass_count": int(
|
||||
auto_policy_closeout_details.get("decision_closeout_pass_count") or 0
|
||||
),
|
||||
"decision_closeout_waiting_count": int(
|
||||
auto_policy_closeout_details.get("decision_closeout_waiting_count") or 0
|
||||
),
|
||||
"post_apply_verifier_required_count": int(
|
||||
auto_policy_closeout_details.get("post_apply_verifier_required_count") or 0
|
||||
),
|
||||
"same_run_truth_required_count": int(
|
||||
auto_policy_closeout_details.get("same_run_truth_required_count") or 0
|
||||
),
|
||||
"reads_secret_count": int(auto_policy_closeout_details.get("reads_secret_count") or 0),
|
||||
"executes_sql_count": int(auto_policy_closeout_details.get("executes_sql_count") or 0),
|
||||
"writes_database_count": int(
|
||||
auto_policy_closeout_details.get("writes_database_count") or 0
|
||||
),
|
||||
"primary_human_gate_count": int(
|
||||
auto_policy_closeout_details.get("primary_human_gate_count") or 0
|
||||
),
|
||||
"manual_review_mode": auto_policy_closeout_details.get("manual_review_mode"),
|
||||
"payload_source": auto_policy_closeout_details.get("payload_source"),
|
||||
"execute_fetch": bool(auto_policy_closeout_details.get("execute_fetch")),
|
||||
"outbound_network": bool(auto_policy_closeout_details.get("outbound_network")),
|
||||
"business_data_source": bool(auto_policy_closeout_details.get("business_data_source")),
|
||||
"ready_for_database_apply_now": bool(
|
||||
auto_policy_closeout_details.get("ready_for_database_apply_now")
|
||||
),
|
||||
"issues_database_apply_authorization": bool(
|
||||
auto_policy_closeout_details.get("issues_database_apply_authorization")
|
||||
),
|
||||
"permits_future_authorization_decision_lane": bool(
|
||||
auto_policy_closeout_details.get("permits_future_authorization_decision_lane")
|
||||
),
|
||||
"writes_database": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"key": "ai_surface_html_readback",
|
||||
"label": "AI surface HTML readback",
|
||||
@@ -1400,6 +1468,161 @@ def _pchome_auto_policy_decision_preflight_check() -> Dict[str, Any]:
|
||||
)
|
||||
|
||||
|
||||
def _pchome_auto_policy_decision_closeout_check() -> Dict[str, Any]:
|
||||
"""Read-only monitor for the future authorization decision closeout package."""
|
||||
try:
|
||||
from services import pchome_mapping_backlog_service as backlog
|
||||
from services.ai_exception_contract import (
|
||||
LEGACY_REVIEW_REQUIRED_COUNT_KEY,
|
||||
PRIMARY_HUMAN_GATE_COUNT_KEY,
|
||||
)
|
||||
|
||||
payload = _pchome_auto_policy_decision_preflight_contract_payload()
|
||||
closeout = backlog.build_pchome_auto_policy_db_apply_authorization_decision_closeout(
|
||||
payload,
|
||||
batch_size=max(1, min(_PCHOME_AUTO_POLICY_DECISION_PREFLIGHT_BATCH_SIZE, 50)),
|
||||
execute_fetch=True,
|
||||
timeout_seconds=max(1, min(_PCHOME_AUTO_POLICY_DECISION_PREFLIGHT_TIMEOUT_SECONDS, 30)),
|
||||
http_get=_pchome_auto_policy_machine_fetch_evidence_get,
|
||||
)
|
||||
summary = closeout.get("summary") or {}
|
||||
decision = closeout.get("future_authorization_decision_closeout") or {}
|
||||
package = closeout.get("future_authorization_decision_package") or {}
|
||||
contract = closeout.get("decision_closeout_contract") or {}
|
||||
safety = closeout.get("safety") or {}
|
||||
result = str(closeout.get("result") or "UNKNOWN")
|
||||
|
||||
closeout_ready_count = int(summary.get("authorization_decision_closeout_ready_count") or 0)
|
||||
preflight_ready_count = int(
|
||||
summary.get("authorization_decision_preflight_ready_count") or 0
|
||||
)
|
||||
check_count = int(summary.get("decision_closeout_check_count") or 0)
|
||||
pass_count = int(summary.get("decision_closeout_pass_count") or 0)
|
||||
waiting_count = int(summary.get("decision_closeout_waiting_count") or 0)
|
||||
input_requirement_count = int(summary.get("decision_input_requirement_count") or 0)
|
||||
rejection_reason_count = int(summary.get("decision_rejection_reason_count") or 0)
|
||||
verifier_required_count = int(summary.get("post_apply_verifier_required_count") or 0)
|
||||
same_run_truth_count = int(summary.get("same_run_truth_required_count") or 0)
|
||||
reads_secret_count = int(summary.get("reads_secret_count") or 0)
|
||||
executes_sql_count = int(summary.get("executes_sql_count") or 0)
|
||||
writes_database_count = int(summary.get("writes_database_count") or 0)
|
||||
primary_human_gate_count = int(summary.get(PRIMARY_HUMAN_GATE_COUNT_KEY) or 0)
|
||||
manual_review_required_count = int(summary.get(LEGACY_REVIEW_REQUIRED_COUNT_KEY) or 0)
|
||||
side_effect_count = reads_secret_count + executes_sql_count + writes_database_count
|
||||
risk_detected = any(
|
||||
[
|
||||
side_effect_count,
|
||||
primary_human_gate_count,
|
||||
manual_review_required_count,
|
||||
safety.get("reads_secret_in_preview") is not False,
|
||||
safety.get("executes_sql") is not False,
|
||||
safety.get("writes_database") is not False,
|
||||
contract.get("issues_database_apply_authorization") is not False,
|
||||
contract.get("ready_for_database_apply_now") is not False,
|
||||
contract.get("writes_database") is not False,
|
||||
package.get("ready_for_database_apply_now") is not False,
|
||||
package.get("issues_database_apply_authorization") is not False,
|
||||
decision.get("ready_for_database_apply_now") is not False,
|
||||
decision.get("issues_database_apply_authorization") is not False,
|
||||
]
|
||||
)
|
||||
closeout_contract_present = (
|
||||
closeout_ready_count == 1
|
||||
and preflight_ready_count == 1
|
||||
and check_count >= 12
|
||||
and pass_count == check_count
|
||||
and waiting_count == 0
|
||||
and input_requirement_count == 8
|
||||
and rejection_reason_count == 10
|
||||
and verifier_required_count == 1
|
||||
and same_run_truth_count == 1
|
||||
and decision.get("ready_for_future_authorization_decision_closeout") is True
|
||||
and package.get("ready_for_future_authorization_decision_package") is True
|
||||
and package.get("requires_post_apply_verifier") is True
|
||||
and package.get("requires_fresh_production_truth_in_same_run") is True
|
||||
and contract.get("machine_verifiable") is True
|
||||
and contract.get("permits_future_authorization_decision_lane") is True
|
||||
and safety.get("manual_review_mode") == "exception_only"
|
||||
)
|
||||
|
||||
if risk_detected:
|
||||
status = "critical"
|
||||
summary_text = "PChome auto-policy decision closeout 偵測到 secret、SQL、DB write 或人工主 gate 風險"
|
||||
next_machine_action = "halt_pchome_auto_policy_decision_closeout_and_inspect_risk"
|
||||
elif closeout_contract_present:
|
||||
status = "ok"
|
||||
summary_text = (
|
||||
"PChome auto-policy decision closeout 已自動完成 "
|
||||
f"{pass_count}/{check_count} checks,post-apply verifier 已綁定,DB apply authorization=0"
|
||||
)
|
||||
next_machine_action = "continue_to_pchome_auto_policy_authorization_issuer_gate"
|
||||
else:
|
||||
status = "warning"
|
||||
summary_text = "PChome auto-policy decision closeout 尚未達自動監控契約"
|
||||
next_machine_action = "refresh_pchome_auto_policy_decision_closeout"
|
||||
|
||||
return _check(
|
||||
"PChome auto-policy decision closeout",
|
||||
status,
|
||||
summary_text,
|
||||
{
|
||||
"policy": closeout.get("policy"),
|
||||
"result": result,
|
||||
"source_policy": closeout.get("source_policy"),
|
||||
"decision_closeout_ready_count": closeout_ready_count,
|
||||
"decision_preflight_ready_count": preflight_ready_count,
|
||||
"decision_closeout_check_count": check_count,
|
||||
"decision_closeout_pass_count": pass_count,
|
||||
"decision_closeout_waiting_count": waiting_count,
|
||||
"decision_input_requirement_count": input_requirement_count,
|
||||
"decision_rejection_reason_count": rejection_reason_count,
|
||||
"post_apply_verifier_required_count": verifier_required_count,
|
||||
"same_run_truth_required_count": same_run_truth_count,
|
||||
"reads_secret_count": reads_secret_count,
|
||||
"executes_sql_count": executes_sql_count,
|
||||
"writes_database_count": writes_database_count,
|
||||
"primary_human_gate_count": primary_human_gate_count,
|
||||
"manual_review_required_count": manual_review_required_count,
|
||||
"manual_review_mode": safety.get("manual_review_mode"),
|
||||
"payload_source": "local_contract_fixture",
|
||||
"machine_fetch_evidence_source": "local_schema_fixture",
|
||||
"http_get_adapter": "_pchome_auto_policy_machine_fetch_evidence_get",
|
||||
"execute_fetch": True,
|
||||
"outbound_network": False,
|
||||
"business_data_source": False,
|
||||
"ready_for_database_apply_now": bool(package.get("ready_for_database_apply_now")),
|
||||
"issues_database_apply_authorization": bool(
|
||||
package.get("issues_database_apply_authorization")
|
||||
),
|
||||
"permits_future_authorization_decision_lane": bool(
|
||||
contract.get("permits_future_authorization_decision_lane")
|
||||
),
|
||||
"requires_post_apply_verifier": bool(package.get("requires_post_apply_verifier")),
|
||||
"requires_fresh_production_truth": bool(
|
||||
package.get("requires_fresh_production_truth_in_same_run")
|
||||
),
|
||||
"writes_database": False,
|
||||
"next_machine_action": next_machine_action,
|
||||
},
|
||||
)
|
||||
except Exception as exc:
|
||||
return _check(
|
||||
"PChome auto-policy decision closeout",
|
||||
"warning",
|
||||
f"PChome auto-policy decision closeout 例行監控暫時無法讀取:{exc}",
|
||||
{
|
||||
"writes_database": False,
|
||||
"writes_database_count": 0,
|
||||
"primary_human_gate_count": 0,
|
||||
"execute_fetch": True,
|
||||
"outbound_network": False,
|
||||
"business_data_source": False,
|
||||
"payload_source": "local_contract_fixture",
|
||||
"next_machine_action": "refresh_pchome_auto_policy_decision_closeout",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def _ai_surface_html_readback_check() -> Dict[str, Any]:
|
||||
"""Read-only AI product surface guardrail readback."""
|
||||
try:
|
||||
@@ -1629,6 +1852,7 @@ def collect_ai_automation_smoke(*, record_history: bool = True, history_limit: i
|
||||
_pchome_controlled_apply_drift_monitor_check(),
|
||||
_pchome_auto_policy_authorization_guard_check(),
|
||||
_pchome_auto_policy_decision_preflight_check(),
|
||||
_pchome_auto_policy_decision_closeout_check(),
|
||||
_ai_surface_html_readback_check(),
|
||||
_sitewide_ui_ux_agent_check(),
|
||||
_sitewide_visual_qa_check(),
|
||||
|
||||
Reference in New Issue
Block a user