# ADR-056: Config Drift Detection — GitOps 守門員架構

> **狀態**: ✅ 已批准
> **日期**: 2026-04-04
> **決策者**: 統帥 + 首席架構師
> **首席架構師評分**: 技術背書
> **關聯 ADR**: ADR-052, ADR-057 (adopt() Gitea PR API)
> **實作**: Phase 25 P2 — commit 3455044

---

## 背景

### 問題陳述

K8s 叢集實際狀態可能因以下原因與 Git YAML 產生漂移：

1. 緊急 Hotfix 直接 kubectl 操作而未提交 Git
2. 人為誤操作（kubectl edit / kubectl set image）
3. CI/CD 部分失敗導致 Rollout 中斷

目前無系統性機制偵測此類漂移，也無法自動修復。

---

## 決策

### D1: 四層架構（Detector → Analyzer → Interpreter → Remediator）

```
GitStateReader ─┐
                ├─→ DriftDetector.scan() → raw DriftReport
K8sStateReader ─┘
                              ↓
                    DriftAnalyzer.classify() → HIGH/MEDIUM/INFO
                              ↓
               NemotronDriftInterpreter.analyze() → intent + explanation
                              ↓
                    DriftRemediator.rollback() / adopt()
```

**職責邊界**：
- Detector: 事實比對（Git vs K8s），不做判斷
- Analyzer: 分級（白名單過濾、嚴重度分類）
- Interpreter: AI 意圖分析，**只輸出意圖判斷，不輸出修復指令**
- Remediator: 確定性修復執行，不使用 AI 決定修復策略

### D2: AI 只做意圖分析，確定性程式碼做修復

NemotronDriftInterpreter 分析漂移意圖（emergency_hotfix / human_error / automated_change / unknown），為人工決策提供參考。

修復由確定性程式碼執行（`kubectl apply` / `git push`），不允許 AI 生成 kubectl 指令。

**理由**: AI 生成的修復指令無法保證正確性，對 K8s 叢集的破壞難以回滾。

### D3: rollback() 使用 kubectl apply（覆蓋回 Git 狀態）

```python
cmd = ["kubectl", "apply", "-f", target, "-n", namespace, "--dry-run=none"]
```

- `resource_key` 參數支援精細範圍（按 Kind/Name 匹配 YAML 檔）
- 失敗時只通知，不重試（避免重複操作）

### D4: adopt() 端點暫停開放（見 ADR-057）

API Pod 內執行 `git add -A` 有安全風險：

1. API Pod 通常無 Git 認證（SSH key / token）
2. `git add -A` 可能誤提交敏感檔案
3. 多副本部署下 git 操作不安全

暫回傳 501，ADR-057 完成後改由 Gitea PR API 實作。

### D5: CronJob 每小時自動掃描

```yaml
schedule: "0 * * * *"
concurrencyPolicy: Forbid        # 防並發
activeDeadlineSeconds: 300       # 5 分鐘超時
backoffLimit: 0                  # 失敗不重試
```

### D6: 漂移報告暫存（in-process dict，Phase 1）

```python
_recent_reports: dict[str, DriftReport] = {}  # 最多 50 筆，FIFO
```

此為 Phase 1 設計，多副本部署下不一致。

**升級路徑**: Phase 2 遷移至 `drift_reports` DB 表（migration phase9 已就緒）。

---

## 後果

### 正面影響

- 漂移偵測自動化，每小時一次無需人工
- 四層架構職責清晰，各層可獨立替換
- AI 只做分析不做決策，保持確定性修復

### 負面影響 / 風險

- `_recent_reports` 多副本不一致（Phase 1 已知限制）
- adopt() 功能暫停，承認漂移需要手動 git 操作

### 未決事項

- C3: `_recent_reports` 遷移至 DB（見 Phase 2 計畫）
- I4: `_is_allowlisted` / `_is_critical` field_path 比對邏輯需整合測試覆蓋
- ADR-057: adopt() Gitea PR API 實作

---

## 替代方案

| 方案 | 理由未採用 |
|------|-----------|
| AI 生成 kubectl patch 指令執行修復 | AI 生成指令不可控，破壞難以回滾 |
| 只記錄漂移不修復 | 缺少閉環，漂移長期積累 |
| GitOps operator (Flux/ArgoCD) 完全接管 | 引入外部依賴，與現有架構整合成本高 |
