fix(automation): enforce durable alert closure
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m32s
CD Pipeline / build-and-deploy (push) Successful in 8m2s
CD Pipeline / post-deploy-checks (push) Successful in 2m22s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m32s
CD Pipeline / build-and-deploy (push) Successful in 8m2s
CD Pipeline / post-deploy-checks (push) Successful in 2m22s
Restore D037 durable incident readback without weakening database failure semantics. Fence Agent99 dispatch and terminal learning to canonical identities, durable leases, verifier receipts, and reconciler-owned checkpoints. Drain backup and restore legacy receipts in bounded cohorts with strict transport, claim, projection, and no-false-green controls. Keep SSH service refusal visible while separating it from broker network-policy reachability.
This commit is contained in:
@@ -22,7 +22,7 @@ C-Suite 戰略會議決議 (2026-03-22):
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
from typing import Literal
|
||||
from typing import Literal, cast, get_args
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
@@ -70,6 +70,33 @@ class IncidentStatus(str, Enum):
|
||||
ESCALATED = "escalated" # 已升級 - 需要人工介入
|
||||
|
||||
|
||||
# Signal sources are a durable contract: values written by the host sensor and
|
||||
# the public signal ingress can remain in PostgreSQL long after a producer is
|
||||
# upgraded. Keep this list bounded, but include every repo-owned producer
|
||||
# vocabulary instead of silently rewriting provenance during readback.
|
||||
SignalSource = Literal[
|
||||
"prometheus",
|
||||
"signoz",
|
||||
"alertmanager",
|
||||
"manual",
|
||||
"telegram",
|
||||
"journal",
|
||||
"node-exporter",
|
||||
"sensor-probe",
|
||||
"sensor-agent",
|
||||
]
|
||||
SIGNAL_SOURCE_VALUES: frozenset[str] = frozenset(get_args(SignalSource))
|
||||
|
||||
|
||||
def parse_signal_source(value: object) -> SignalSource:
|
||||
"""Return a canonical known source or reject an unowned durable value."""
|
||||
|
||||
normalized = str(value or "").strip().lower()
|
||||
if normalized not in SIGNAL_SOURCE_VALUES:
|
||||
raise ValueError("unsupported_signal_source")
|
||||
return cast(SignalSource, normalized)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Signal (原始告警)
|
||||
# =============================================================================
|
||||
@@ -89,9 +116,7 @@ class Signal(BaseModel):
|
||||
)
|
||||
alert_name: str = Field(..., description="告警名稱 (如 HighCPUUsage)")
|
||||
severity: Severity = Field(..., description="告警嚴重度")
|
||||
source: Literal["prometheus", "signoz", "alertmanager", "manual", "telegram"] = (
|
||||
Field(..., description="告警來源")
|
||||
)
|
||||
source: SignalSource = Field(..., description="告警來源")
|
||||
fired_at: datetime = Field(..., description="告警觸發時間")
|
||||
resolved_at: datetime | None = Field(None, description="告警解除時間")
|
||||
labels: dict[str, str] = Field(
|
||||
@@ -107,9 +132,26 @@ class Signal(BaseModel):
|
||||
description="告警指紋 Hash,用於去重與聚合",
|
||||
)
|
||||
|
||||
@field_validator("source", mode="before")
|
||||
@classmethod
|
||||
def validate_source(cls, value: object) -> SignalSource:
|
||||
return parse_signal_source(value)
|
||||
|
||||
# [首席架構師] 移除 json_encoders (Pydantic v2 已 deprecated),原生序列化輸出格式與 .isoformat() 一致 v1.1 2026-04-01 Asia/Taipei
|
||||
|
||||
|
||||
class IncidentReadDegradation(BaseModel):
|
||||
"""Public-safe metadata for one durable row excluded from a response."""
|
||||
|
||||
incident_id: str
|
||||
reason_code: Literal[
|
||||
"incident_signal_source_unsupported",
|
||||
"incident_signal_schema_invalid",
|
||||
"incident_record_schema_invalid",
|
||||
]
|
||||
quarantined_from_response: bool = True
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# AI Decision Chain (CISO 要求:可稽核性)
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user