fix(aiops): fallback and escalate automation blockers
Some checks failed
CD Pipeline / tests (push) Successful in 2m41s
Code Review / ai-code-review (push) Successful in 24s
CD Pipeline / build-and-deploy (push) Successful in 7m51s
CD Pipeline / post-deploy-checks (push) Failing after 2m15s

This commit is contained in:
Your Name
2026-04-30 14:13:57 +08:00
parent 82649c2cbb
commit 80defbed7c
10 changed files with 311 additions and 10 deletions

View File

@@ -54,6 +54,26 @@ def _fire_and_forget(coro) -> asyncio.Task:
return task
def _phase2_fallback_reason(package: Any) -> str | None:
"""Return why a Phase 2 package should continue to Playbook/LLM fallback.
Phase 2 is a deliberation layer, not the final brake. If the debate times
out or produces no actionable recommendation, the flywheel must still try
deterministic Playbook/LLM/expert paths before opening a manual gate.
"""
status = getattr(package, "session_status", None)
status_value = status.value if status and hasattr(status, "value") else str(status or "")
if status_value in {"timeout", "failed"}:
return f"session_{status_value}"
if getattr(package, "all_agents_degraded", False):
return "all_agents_degraded"
action = str(getattr(package, "recommended_action", "") or "").strip()
if not action and getattr(package, "requires_human_approval", False):
return "empty_action_requires_human"
return None
# =============================================================================
# Phase 31 (ADR-067 2026-04-10): Log 異常摘要 — NemoTron deepseek-r1:14b
# =============================================================================
@@ -2455,13 +2475,26 @@ class DecisionManager:
# evidence_snapshot 攜帶進 proposal_data避免 singleton 並發污染
_p2_result = _package_to_proposal_data(package)
_p2_result["_evidence_snapshot_ref"] = p2_snapshot
return _p2_result
_p2_fallback = _phase2_fallback_reason(package)
if not _p2_fallback:
return _p2_result
logger.warning(
"p2_degraded_fallback_to_playbook_llm",
incident_id=incident.incident_id,
reason=_p2_fallback,
confidence=_p2_result.get("confidence"),
blocked_reason=_p2_result.get("blocked_reason", ""),
)
# snapshot 仍為 None → 降級繼續走原路徑(不阻塞)
logger.warning("p2_no_snapshot_fallback", incident_id=incident.incident_id)
if p2_snapshot is None:
logger.warning("p2_no_snapshot_fallback", incident_id=incident.incident_id)
# Phase 7.5: 先嘗試 Playbook 匹配
playbook_result = await self._try_playbook_match(incident)
if playbook_result:
if evidence_snapshot is not None:
playbook_result["_evidence_snapshot_ref"] = evidence_snapshot
return playbook_result
# MCP Phase 4c: Playbook 無命中 → 非同步產生 AI 草稿 Playbook (2026-04-11 Claude Sonnet 4.6)