feat(phase25): Nemotron 主動防禦三方向 P0+P1+P2 完整實作
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 38s
Type Sync Check / check-type-sync (push) Failing after 35s

P0 - DIAGNOSE Privacy-First Routing:
- ai_router.py: _local_fallback_chain [NEMOTRON→OLLAMA→REJECT]
- DIAGNOSE 意圖 override 改為 NEMOTRON (原 OLLAMA)
- DIAGNOSE fallback 使用 local-only 鏈,不觸碰雲端
- 全部失敗時 REJECT + Telegram 通知
- config.py: NEMOTRON_DIAGNOSE_TIMEOUT_SECONDS=30, OLLAMA_DIAGNOSE_TIMEOUT_SECONDS=60
- nemotron.py: 根據 context[task_type] 選擇 timeout

P1 - Knowledge Auto-Harvesting:
- models/knowledge.py: EntryType.AUTO_RUNBOOK + ANTI_PATTERN + symptoms_hash
- EntryStatus.PUBLISHED (ANTI_PATTERN 直接發布,無需審核)
- models/playbook.py: SymptomPattern.compute_hash() (16字元確定性 hash)
- services/runbook_generator.py: NemotronRunbookGenerator (v1.1)
  - generate_runbook() → AUTO_RUNBOOK (DRAFT) + Telegram 審核 card
  - generate_anti_pattern() → ANTI_PATTERN (PUBLISHED) + Telegram 通知
  - 使用 nvidia.chat() (正確介面),Nemotron 超時時 Minimal fallback
- knowledge_service.py: check_anti_pattern(symptoms_hash, days=7)
- db/models.py: symptoms_hash VARCHAR(16) + ix_knowledge_symptoms_hash
- repositories/knowledge_repository.py: create() 支援 symptoms_hash + status
- auto_repair_service.py: anti_pattern_gate 在 decide() + runbook hook 在 execute()
- migrations/phase8_symptoms_hash.sql: ALTER TABLE + partial index + PUBLISHED constraint

P2 - Config Drift Detection:
- models/drift.py: DriftItem/DriftReport/DriftLevel/DriftIntent/DriftStatus
- services/drift_detector.py: GitStateReader + K8sStateReader + DriftDetector
- services/drift_analyzer.py: 白名單過濾 + DriftLevel 分級
- services/drift_interpreter.py: NemotronDriftInterpreter(意圖分析,不生成修復指令)
- services/drift_remediator.py: rollback(kubectl apply) + adopt(git push gitea)
- api/v1/drift.py: POST /scan, GET /reports, POST /rollback, POST /adopt
- migrations/phase9_drift_reports.sql: drift_reports 表
- k8s/drift-cronjob.yaml: 每小時自動掃描 CronJob

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-04 12:35:05 +08:00
parent 0b41df45d6
commit 3455044457
20 changed files with 1945 additions and 7 deletions

View File

@@ -0,0 +1,54 @@
-- Phase 25 P2: Config Drift Detection — drift_reports 資料表
-- 建立時間: 2026-04-04 (台北時區)
-- 建立者: Claude Code (Phase 25 P2)
-- 對應模型: apps/api/src/models/drift.py
-- 對應設計: docs/superpowers/specs/2026-04-04-nemotron-active-defense-design.md 方向三
--
-- 執行方式: psql -h 192.168.0.188 -U awoooi -d awoooi -f phase9_drift_reports.sql
CREATE TABLE IF NOT EXISTS drift_reports (
-- 識別
report_id VARCHAR(32) PRIMARY KEY,
-- 掃描資訊
namespace VARCHAR(128) NOT NULL,
triggered_by VARCHAR(64) NOT NULL DEFAULT 'cron', -- cron / webhook / api
scanned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- 計數(非正規化,避免每次 JOIN
high_count INT NOT NULL DEFAULT 0,
medium_count INT NOT NULL DEFAULT 0,
info_count INT NOT NULL DEFAULT 0,
-- 漂移項目JSONB 列表)
items JSONB NOT NULL DEFAULT '[]',
-- Nemotron 意圖分析
interpretation JSONB, -- DriftInterpretation可為 NULL尚未分析
-- 處理狀態
status VARCHAR(32) NOT NULL DEFAULT 'pending',
-- pending / acknowledged / rolled_back / adopted / ignored
-- 時間軸
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
resolved_at TIMESTAMPTZ
);
-- 索引
CREATE INDEX IF NOT EXISTS idx_drift_reports_namespace
ON drift_reports(namespace);
CREATE INDEX IF NOT EXISTS idx_drift_reports_status
ON drift_reports(status);
CREATE INDEX IF NOT EXISTS idx_drift_reports_created_at
ON drift_reports(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_drift_reports_high_count
ON drift_reports(high_count)
WHERE high_count > 0;
-- 說明:
-- 目前 API 使用 in-memory dict 暫存,此表供未來持久化使用
-- 啟用持久化後,需在 drift.py 的 _recent_reports 操作改為 DB 寫入