Files
awoooi/apps/api/src/services/service_health_failure_notification_policy.py
Your Name a5934edb72
All checks were successful
CD Pipeline / tests (push) Successful in 1m28s
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Successful in 4m22s
CD Pipeline / post-deploy-checks (push) Successful in 1m54s
fix(governance): 收斂前端 redaction 語彙
2026-06-11 21:27:32 +08:00

270 lines
11 KiB
Python

"""
Service health failure-only notification policy snapshot.
Loads the latest committed, read-only service health notification policy. The
policy defines success-noise suppression, failure/action-required escalation,
message redaction, and frontend display limits. It never sends Telegram or
AwoooP notifications, writes operator events, probes live systems, restarts
services, changes endpoints, triggers workflows, reads secrets, or displays
internal conversation transcripts.
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from src.services.snapshot_paths import default_evaluations_dir
_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__))
_SNAPSHOT_PATTERN = "service_health_failure_notification_policy_*.json"
_SCHEMA_VERSION = "service_health_failure_notification_policy_v1"
_CONVERSATION_TRANSCRIPT_MARKERS = {
"# In app browser",
"My request for Codex",
"Current URL:",
"AGENTS.md instructions",
"<environment_context>",
"批准!繼續",
}
def load_latest_service_health_failure_notification_policy(
evaluations_dir: Path | None = None,
) -> dict[str, Any]:
"""Load the newest committed service health failure notification policy."""
directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
if not candidates:
raise FileNotFoundError(
f"no service health failure notification policy snapshots found in {directory}"
)
latest = candidates[-1]
with latest.open(encoding="utf-8") as handle:
payload = json.load(handle)
if not isinstance(payload, dict):
raise ValueError(f"{latest}: expected JSON object")
_require_schema(payload, _SCHEMA_VERSION, str(latest))
_require_read_only_boundaries(payload, str(latest))
_require_operation_boundaries(payload, str(latest))
_require_rollup_consistency(payload, str(latest))
_require_success_noise_suppression(payload, str(latest))
_require_failure_only_escalation(payload, str(latest))
_require_frontend_redaction_contract(payload, str(latest))
_require_no_plaintext_secret_payload_keys(payload, str(latest))
_require_no_conversation_transcript_content(payload, str(latest))
return payload
def _require_schema(payload: dict[str, Any], expected: str, label: str) -> None:
actual = payload.get("schema_version")
if actual != expected:
raise ValueError(f"{label}: expected schema_version={expected}, got {actual!r}")
def _require_read_only_boundaries(payload: dict[str, Any], label: str) -> None:
program_status = payload.get("program_status") or {}
if program_status.get("read_only_mode") is not True:
raise ValueError(f"{label}: program_status.read_only_mode must be true")
approval_boundaries = payload.get("approval_boundaries") or {}
allowed = sorted(key for key, value in approval_boundaries.items() if value is not False)
if allowed:
raise ValueError(f"{label}: approval boundaries must remain false: {allowed}")
def _require_operation_boundaries(payload: dict[str, Any], label: str) -> None:
boundaries = payload.get("operation_boundaries") or {}
if boundaries.get("read_only_policy_allowed") is not True:
raise ValueError(f"{label}: read_only_policy_allowed must be true")
blocked_flags = {
"notification_send_allowed",
"telegram_test_message_allowed",
"awooop_event_write_allowed",
"live_probe_allowed",
"external_health_probe_allowed",
"service_restart_allowed",
"endpoint_change_allowed",
"workflow_trigger_allowed",
"runtime_execution_allowed",
"secret_plaintext_allowed",
}
allowed = sorted(flag for flag in blocked_flags if boundaries.get(flag) is not False)
if allowed:
raise ValueError(f"{label}: operation boundaries must remain false: {allowed}")
def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
rules = payload.get("policy_rules") or []
rollups = payload.get("rollups") or {}
if rollups.get("total_rules") != len(rules):
raise ValueError(f"{label}: rollups.total_rules must match policy_rules")
by_decision: dict[str, int] = {}
for rule in rules:
decision = str(rule.get("decision"))
by_decision[decision] = by_decision.get(decision, 0) + 1
if rollups.get("by_decision") != by_decision:
raise ValueError(f"{label}: rollups.by_decision must match policy rule decisions")
immediate_ids = {
rule.get("rule_id")
for rule in rules
if rule.get("decision") == "escalate_immediate"
}
if set(rollups.get("immediate_escalation_rule_ids") or []) != immediate_ids:
raise ValueError(f"{label}: rollups.immediate_escalation_rule_ids must match immediate rules")
suppressed_success_ids = {
rule.get("rule_id")
for rule in rules
if rule.get("service_state") == "verified"
and rule.get("decision") == "suppress_immediate_success"
}
if set(rollups.get("suppressed_success_rule_ids") or []) != suppressed_success_ids:
raise ValueError(f"{label}: rollups.suppressed_success_rule_ids must match suppressed success rules")
action_required_ids = {
rule.get("rule_id")
for rule in rules
if rule.get("decision") == "create_action_required"
}
if set(rollups.get("action_required_rule_ids") or []) != action_required_ids:
raise ValueError(f"{label}: rollups.action_required_rule_ids must match action-required rules")
if rollups.get("notification_send_allowed_count") != 0:
raise ValueError(f"{label}: rollups.notification_send_allowed_count must remain 0")
def _require_success_noise_suppression(payload: dict[str, Any], label: str) -> None:
channels = payload.get("notification_channels") or []
noisy_channels = [
channel.get("channel_id")
for channel in channels
if channel.get("success_immediate_allowed") is not False
]
if noisy_channels:
raise ValueError(f"{label}: channels must not allow success immediate notifications: {noisy_channels}")
success_escalations = [
rule.get("rule_id")
for rule in payload.get("policy_rules") or []
if rule.get("service_state") == "verified"
and rule.get("decision") != "suppress_immediate_success"
]
if success_escalations:
raise ValueError(f"{label}: verified service health rules must suppress immediate notifications")
template_contract = payload.get("message_template_contract") or {}
success_policy = str(template_contract.get("success_message_policy") or "")
if "不得即時" not in success_policy or "Telegram / AwoooP" not in success_policy:
raise ValueError(f"{label}: success_message_policy must suppress Telegram / AwoooP success noise")
def _require_failure_only_escalation(payload: dict[str, Any], label: str) -> None:
escalation_rules = [
rule
for rule in payload.get("policy_rules") or []
if rule.get("decision") == "escalate_immediate"
]
invalid_states = sorted(
rule.get("rule_id")
for rule in escalation_rules
if rule.get("service_state") not in {"failed", "blocked"}
)
if invalid_states:
raise ValueError(f"{label}: immediate escalation must be failure-only: {invalid_states}")
telegram_non_failure = sorted(
rule.get("rule_id")
for rule in payload.get("policy_rules") or []
if "telegram_ops" in (rule.get("channels") or [])
and rule.get("decision") != "escalate_immediate"
)
if telegram_non_failure:
raise ValueError(f"{label}: telegram_ops must only appear on immediate failure escalation rules")
template_contract = payload.get("message_template_contract") or {}
required_fields = set(template_contract.get("required_fields") or [])
required = {"stage", "next_action", "blocked_reason", "target_id", "severity", "evidence_ref"}
if not required.issubset(required_fields):
raise ValueError(f"{label}: message_template_contract.required_fields missing failure context")
forbidden_fields = set(template_contract.get("forbidden_fields") or [])
required_forbidden_fields = {
"secret_value",
"token",
"authorization_header",
"work_window_transcript",
"codex_user_message",
"prompt_text",
"chain_of_thought",
"session_id",
"browser_context",
}
if not required_forbidden_fields.issubset(forbidden_fields):
raise ValueError(f"{label}: message_template_contract.forbidden_fields missing redaction boundary")
def _require_frontend_redaction_contract(payload: dict[str, Any], label: str) -> None:
contract = payload.get("display_redaction_contract") or {}
if contract.get("conversation_transcript_display_allowed") is not False:
raise ValueError(f"{label}: conversation transcript display must remain false")
if contract.get("redaction_required") is not True:
raise ValueError(f"{label}: frontend redaction must be required")
forbidden = set(contract.get("forbidden_frontend_content") or [])
required_forbidden = {
"未核准內部內容",
"未脫敏操作紀錄",
"未核准決策細節",
"工作階段脈絡",
"機密 / 權杖 / 授權標頭",
}
if not required_forbidden.issubset(forbidden):
raise ValueError(f"{label}: display_redaction_contract is missing required forbidden content")
allowed_fields = set(contract.get("allowed_frontend_fields") or [])
if "已提交證據參照" not in allowed_fields or "政策規則摘要" not in allowed_fields:
raise ValueError(f"{label}: display_redaction_contract must limit frontend to committed policy evidence")
def _require_no_plaintext_secret_payload_keys(value: Any, label: str, path: str = "$") -> None:
if isinstance(value, dict):
forbidden_key_fragments = {
"secret_value",
"token_value",
"authorization_header",
"private_key",
"webhook_secret",
"runner_token",
"api_key_value",
"password_value",
}
for key, nested in value.items():
lowered = str(key).lower()
if any(fragment in lowered for fragment in forbidden_key_fragments):
raise ValueError(f"{label}: forbidden secret payload key at {path}.{key}")
_require_no_plaintext_secret_payload_keys(nested, label, f"{path}.{key}")
elif isinstance(value, list):
for index, nested in enumerate(value):
_require_no_plaintext_secret_payload_keys(nested, label, f"{path}[{index}]")
def _require_no_conversation_transcript_content(value: Any, label: str, path: str = "$") -> None:
if isinstance(value, dict):
for key, nested in value.items():
_require_no_conversation_transcript_content(nested, label, f"{path}.{key}")
elif isinstance(value, list):
for index, nested in enumerate(value):
_require_no_conversation_transcript_content(nested, label, f"{path}[{index}]")
elif isinstance(value, str):
for marker in _CONVERSATION_TRANSCRIPT_MARKERS:
if marker in value:
raise ValueError(f"{label}: forbidden work-window conversation content at {path}")