feat(Phase 5): Declarative 修復抽象化 + Blast Radius 分控 全部完成
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled

## Phase 5 交付(ADR-086)

### 新增服務(4 個)
- blast_radius_calculator.py: 爆炸半徑計算器(0-100 純函數)
  - 18 種 kubectl 動作基礎分 + 命名空間倍率 + 特殊 flag 修正
  - HARD_RULES 永擋:delete ns/pv/pvc/clusterrole + rm -rf + DROP TABLE
  - 分級:≤10 auto / 11-50 human / 51-99 dual / 100 blocked
- declarative_remediation.py: DeclarativeSpec 不可變規格(frozen dataclass)
  - evaluate() 封裝 Blast Radius + dry-run + rollback_plan + constraints
  - rollback_plan 從 kubectl 動作類型自動推導(不呼叫 LLM)
- gitops_pr_service.py: Gitea Issue 高風險修復審核(tier=dual)
  - 含 Blast Radius + 目標狀態 + 回滾計畫 + 雙人審核流程
  - AIOPS_P5_GITOPS_PR flag 守衛
- rollback_manager.py: 驗證失敗自動回滾
  - 先驗 rollout history ≥ 2 revision,防止無版本可回滾
  - kubectl rollout undo + 120s 收斂等待

### decision_manager.py 接線(AIOPS_P5_BLAST_RADIUS_CHECK)
- _auto_execute() 在安全守衛後、ApprovalRequest 前插入分級守衛
- blocked → 永擋 + 人工審核通知
- dual → 非同步 GitOps Issue + 升級人工審核
- human → 升級人工審核(不自動執行)
- auto(≤10)→ 原有自動執行流程
- 失敗降級:計算異常 → 保守升人工

### learning_service.py
- record_declarative_outcome(): 記錄 DeclarativeSpec 執行結果
  anomaly_key=declarative:{incident_id},含 blast_radius_score/tier/rollback

2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 5 全部完成

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-15 16:06:45 +08:00
parent 53344c201e
commit 655d1a568a
6 changed files with 1130 additions and 0 deletions

View File

@@ -586,6 +586,65 @@ class LearningService:
execution_time_seconds=execution_time_seconds,
)
async def record_declarative_outcome(
self,
incident_id: str,
action: str,
blast_radius_score: int,
blast_radius_tier: str,
success: bool,
rollback_triggered: bool = False,
execution_time_seconds: float | None = None,
) -> bool:
"""
記錄 DeclarativeSpec 執行結果到學習系統。
Phase 5 ADR-086DeclarativeSpec 執行結果寫入學習記錄,
讓 AI 能從 Blast Radius 分級的執行歷史中學習。
Args:
incident_id: 關聯 Incident ID
action: 執行的 kubectl 命令
blast_radius_score: 爆炸半徑分數0-100
blast_radius_tier: 執行分級auto/human/dual/blocked
success: 是否執行成功
rollback_triggered: 是否觸發了回滾
execution_time_seconds: 執行耗時
Returns:
bool: 是否成功記錄
2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 5 初始建立
"""
import json
from src.utils.timezone import now_taipei
try:
anomaly_key = f"declarative:{incident_id}"
fix_desc = json.dumps({
"blast_radius_score": blast_radius_score,
"blast_radius_tier": blast_radius_tier,
"rollback_triggered": rollback_triggered,
"recorded_at": now_taipei().isoformat(),
}, ensure_ascii=False)
return await self._repository.record_repair(
anomaly_key=anomaly_key,
repair_action=action[:200],
success=success,
root_cause=f"blast_radius_tier={blast_radius_tier}",
fix_description=fix_desc,
execution_time_seconds=execution_time_seconds,
)
except Exception as e:
import structlog as _structlog
_structlog.get_logger(__name__).warning(
"record_declarative_outcome_failed",
incident_id=incident_id,
error=str(e),
)
return False
async def get_recommended_fix(self, anomaly_key: str) -> dict:
"""
根據歷史學習,推薦最佳修復方案