""" Core Constants ============== ADR-027: Incident-Approval 同步架構 統一定義系統常量,避免散落各處的 magic numbers。 版本: v1.0 建立: 2026-03-26 (台北時區) """ # ============================================================================= # TTL Settings (秒) # ============================================================================= # Working Memory TTL: 7 天 INCIDENT_TTL_SECONDS = 7 * 24 * 3600 # 604800 APPROVAL_TTL_SECONDS = 7 * 24 * 3600 # 604800 # Decision Token TTL: 24 小時 DECISION_TTL_SECONDS = 24 * 3600 # 86400 # ============================================================================= # Redis Key Prefixes # ============================================================================= REDIS_KEY_INCIDENT = "incident:" REDIS_KEY_APPROVAL = "approval:" REDIS_KEY_PENDING = "pending_approvals" REDIS_KEY_DECISION = "decision:" # ============================================================================= # Status Mappings (ADR-027) # ============================================================================= # Approval 狀態 → Incident 狀態 APPROVAL_TO_INCIDENT_STATUS = { "pending": "investigating", "approved": "resolved", "rejected": "escalated", "expired": "escalated", } # Incident 狀態 → 是否活躍 INCIDENT_ACTIVE_STATUSES = frozenset({"investigating", "mitigating"}) # ============================================================================= # Terminal Service Settings (Phase 19.4 P1) # 2026-03-30 Claude Code: 首席架構師審查 - 常數提取 # ============================================================================= # SSE 事件間隔 (秒) - 避免前端過載 SSE_DELAY_SECONDS = 0.3 # Approval 清單顯示上限 MAX_APPROVAL_DISPLAY = 5 # 錯誤訊息截斷長度 (安全性) ERROR_MESSAGE_MAX_LENGTH = 100 ERROR_MESSAGE_DISPLAY_LENGTH = 50 # ============================================================================= # CI/CD Alert Detection (2026-03-30 P1 配置化) # ============================================================================= # CI/CD 告警 alertname 前綴 CICD_ALERT_PREFIXES = ( "CD_", "CI_", "E2E_", "SmokeTest", "Build_", "Test_", "Deploy_", ) # CI/CD 告警 alertname 後綴 CICD_ALERT_SUFFIXES = ( "_Build", "_Test", "_Deploy", "_E2E", ) # CI/CD 告警關鍵字 (不區分大小寫) CICD_ALERT_KEYWORDS = ("CI/CD", "cicd") # ============================================================================= # Heartbeat/Watchdog Alert Detection (2026-04-10 Claude Sonnet 4.6 Asia/Taipei) # 心跳/看門狗告警不觸發自動修復飛輪 — 這類告警代表監控系統狀態,不是服務故障 # ============================================================================= HEARTBEAT_ALERT_NAMES = frozenset({ "Watchdog", "DeadMansSwitch", "NoAlertsReceived", "NoAlertsReceived2Hours", "AlertmanagerDown", "PrometheusNotConnectedToAlertmanager", }) HEARTBEAT_ALERT_KEYWORDS = ("NoAlertsReceived", "Watchdog", "DeadMansSwitch", "Heartbeat") def is_heartbeat_alertname(alertname: str) -> bool: """ 判斷 alertname 是否為心跳/看門狗告警 心跳告警代表監控系統自身健康狀態,不是服務故障, 不應進入自動修復飛輪(不存在對應的 Playbook 修復動作)。 """ return ( alertname in HEARTBEAT_ALERT_NAMES or any(kw in alertname for kw in HEARTBEAT_ALERT_KEYWORDS) ) def is_cicd_alertname(alertname: str) -> bool: """ 判斷 alertname 是否為 CI/CD 告警 Args: alertname: Alertmanager alertname 標籤值 Returns: True 如果是 CI/CD 告警 """ return ( alertname.startswith(CICD_ALERT_PREFIXES) or alertname.endswith(CICD_ALERT_SUFFIXES) or any(kw in alertname for kw in CICD_ALERT_KEYWORDS) or "cicd" in alertname.lower() ) def sanitize_error_message(error: str, max_length: int = ERROR_MESSAGE_MAX_LENGTH) -> str: """ 安全化錯誤訊息 - 截斷並移除敏感資訊 2026-03-30 Claude Code: 首席架構師審查 - 錯誤訊息安全化 Args: error: 原始錯誤訊息 max_length: 最大長度 (預設 100) Returns: 安全化後的錯誤訊息 """ if not error: return "Unknown error" # 移除可能的敏感資訊模式 sensitive_patterns = [ "password", "token", "secret", "api_key", "apikey", "credential", "bearer", ] sanitized = error for pattern in sensitive_patterns: # 不區分大小寫替換 import re sanitized = re.sub( rf"({pattern})\s*[:=]\s*\S+", f"{pattern}=[REDACTED]", sanitized, flags=re.IGNORECASE, ) # 截斷 if len(sanitized) > max_length: return sanitized[:max_length - 3] + "..." return sanitized