fix(sre): finalize local automation release candidate
Some checks failed
CD Pipeline / select-latest-carrier (push) Successful in 1m33s
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 3m28s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 35s
CD Pipeline / build-and-deploy (push) Failing after 39m13s
CD Pipeline / revalidate-post-deploy-carrier (push) Failing after 10m44s
AI 技術雷達監控 / ai-technology-watch (push) Failing after 11m56s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Failing after 48s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Some checks failed
CD Pipeline / select-latest-carrier (push) Successful in 1m33s
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 3m28s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 35s
CD Pipeline / build-and-deploy (push) Failing after 39m13s
CD Pipeline / revalidate-post-deploy-carrier (push) Failing after 10m44s
AI 技術雷達監控 / ai-technology-watch (push) Failing after 11m56s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Failing after 48s
CD Pipeline / post-deploy-checks (push) Has been cancelled
This commit is contained in:
@@ -133,7 +133,8 @@ class RecommendedAction:
|
||||
label: str # UI 顯示文字(如「查 Pod 日誌」)
|
||||
emoji: str # UI 圖示(如「📋」)
|
||||
mcp_provider: Literal[ # MCP provider 限制在已知清單
|
||||
"k8s", "ssh", "prometheus", "signoz", "database", "internal"
|
||||
"k8s", "ssh", "prometheus", "signoz", "database", "internal",
|
||||
"controlled",
|
||||
]
|
||||
mcp_tool: str # MCP tool 名(必須在 B2 allowlist)
|
||||
params: dict[str, str] # 參數模板(支援 {labels.xxx} / {incident_id})
|
||||
|
||||
@@ -92,7 +92,7 @@ _CALLBACK_SPEC_PATH = Path(__file__).parent.parent / "services" / "callback_acti
|
||||
|
||||
# 有效的 mcp_provider 清單(與 RecommendedAction schema 對應)
|
||||
_VALID_MCP_PROVIDERS = frozenset(
|
||||
{"k8s", "ssh", "prometheus", "signoz", "database", "internal"}
|
||||
{"k8s", "ssh", "prometheus", "signoz", "database", "internal", "controlled"}
|
||||
)
|
||||
|
||||
# 有效的 risk 等級(與 RecommendedAction schema 對應)
|
||||
@@ -710,7 +710,7 @@ blast_radius 參考:
|
||||
recommended_actions 規則(北極星 §1.1 修復多樣性):
|
||||
- 第一個動作必須是診斷/查看類(低風險),讓 SRE 先確認情況
|
||||
- 不要全部是 restart 類動作
|
||||
- mcp_provider 必須是以下之一:k8s | ssh | prometheus | signoz | database | internal
|
||||
- mcp_provider 必須是以下之一:k8s | ssh | prometheus | signoz | database | internal | controlled
|
||||
- risk 必須是以下之一:low | medium | high | critical
|
||||
- params 中可使用模板:{{labels.namespace}} / {{labels.pod}} / {{incident_id}}
|
||||
|
||||
|
||||
@@ -86,7 +86,9 @@ def test_medium_telegram_card_is_automation_progress_not_action_required() -> No
|
||||
assert "AI CONTROLLED AUTOMATION" in rendered
|
||||
assert "ACTION REQUIRED" not in rendered
|
||||
assert "awaiting_approval" not in rendered
|
||||
assert "check>apply>verify>writeback" in rendered
|
||||
assert "流程進度" in rendered
|
||||
assert "執行:<code>controlled_queue_evaluation</code>" in rendered
|
||||
assert "驗證:<code>not_started</code>" in rendered
|
||||
|
||||
|
||||
def test_critical_telegram_card_stays_break_glass() -> None:
|
||||
|
||||
@@ -117,7 +117,7 @@ def test_loader_returns_fixed_architecture_provider_order_and_agent99_bridge() -
|
||||
"by_priority": {"P0": 16, "P1": 2},
|
||||
"by_status": {
|
||||
"source_implemented_runtime_pending": 17,
|
||||
"planned": 1,
|
||||
"in_progress": 1,
|
||||
},
|
||||
"source_implemented_items": 17,
|
||||
"runtime_closed_items": 0,
|
||||
|
||||
@@ -136,7 +136,8 @@ class TestTelegramMessageStructure:
|
||||
assert "api-service" in result
|
||||
assert "INC-20260321-0001" in result
|
||||
assert "後端" in result
|
||||
assert "88%" in result
|
||||
assert "AI 結果未附 durable provider receipt" in result
|
||||
assert "88%" not in result
|
||||
|
||||
def test_telegram_message_with_signoz_metrics(self):
|
||||
"""✅ 含 SignOz 指標的訊息格式"""
|
||||
|
||||
@@ -2460,9 +2460,11 @@ class TestTelegramMessageFormat:
|
||||
assert "處置狀態" in result
|
||||
assert "規則建議待 AI controlled policy 判定" in result
|
||||
assert "AI 自動化鏈路" in result
|
||||
assert "OpenClaw" in result
|
||||
assert "NemoTron" in result
|
||||
assert "ElephantAlpha" in result
|
||||
assert "分析:<code>not_observed</code>" in result
|
||||
assert "Agent:<code>not_observed</code>" in result
|
||||
assert "OpenClaw" not in result
|
||||
assert "NemoTron" not in result
|
||||
assert "ElephantAlpha" not in result
|
||||
assert "自動化資產沉澱" in result
|
||||
assert "KM" in result
|
||||
assert "PlayBook" in result
|
||||
@@ -2471,6 +2473,39 @@ class TestTelegramMessageFormat:
|
||||
assert "Verifier" in result
|
||||
assert len(result) <= 4096 # Telegram HTML message limit
|
||||
|
||||
def test_telegram_message_names_only_receipt_backed_ai_and_agent(self):
|
||||
msg = TelegramMessage(
|
||||
status_emoji="⚠️",
|
||||
risk_level="MEDIUM",
|
||||
resource_name="backup_restore",
|
||||
root_cause="Backup freshness evidence verified",
|
||||
suggested_action="NO_ACTION",
|
||||
estimated_downtime="none",
|
||||
approval_id="INC-20260719-AI-RECEIPT",
|
||||
automation_quality={
|
||||
"verdict": "diagnostic_only",
|
||||
"facts": {
|
||||
"analysis_receipt_observed": True,
|
||||
"analysis_provider": "ollama_gcp_a:qwen3",
|
||||
"execution_actors": ["Agent99 BackupCheck (read-only)"],
|
||||
"latest_execution_backend": "Agent99",
|
||||
"latest_operation_type": "BackupCheck",
|
||||
"latest_operation_status": "completed",
|
||||
"verification_result": "passed",
|
||||
"knowledge_entries": 1,
|
||||
"mcp_gateway_total": 1,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
result = msg.format()
|
||||
|
||||
assert "分析:<code>ollama_gcp_a:qwen3</code>" in result
|
||||
assert "Agent99 BackupCheck (read-only)" in result
|
||||
assert "Executor:<code>Agent99</code>" in result
|
||||
assert "Verifier:<code>passed</code>" in result
|
||||
assert "Learning:KM <code>1</code> / MCP <code>1</code>" in result
|
||||
|
||||
def test_telegram_message_ai_proposal_marks_controlled_apply(self):
|
||||
"""有 AI 信心分數的修復建議必須排入 controlled apply。"""
|
||||
msg = TelegramMessage(
|
||||
|
||||
Reference in New Issue
Block a user