feat(Phase 5): Declarative 修復抽象化 + Blast Radius 分控 全部完成
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
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:
@@ -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-086:DeclarativeSpec 執行結果寫入學習記錄,
|
||||
讓 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:
|
||||
"""
|
||||
根據歷史學習,推薦最佳修復方案
|
||||
|
||||
Reference in New Issue
Block a user