feat(flywheel): W2 三件 + KMWriter critic 修法(1635 tests 全綠)
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m38s
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m38s
W2 (onboarder 4 週飛輪 80→90 路徑第二週) + critic PR review 5 個 critical/major 全部修完,default flag=false 安全無爆炸風險。 ## W2 三件 PR ### PR-R2 — AOL → catalog confidence EWMA 回灌(修飛輪斷鏈 C2) - 新檔 `apps/api/src/jobs/aol_to_catalog_writeback_job.py` - 邏輯:每小時掃 AOL 計算 EWMA confidence (alpha=0.3) 回灌 alert_rule_catalog - 失敗閾值 N=5 連續低成功率 → review_status='draft' - Hermes _fetch_noisy_rules SQL 加 OR review_status='draft' - ENABLE_AOL_WRITEBACK_JOB=false (default) - 8 個測試(mock path 修正:lazy import → patch src.db.base.get_db_context) ### PR-V1 — self_healing_validator 串接 (修飛輪斷鏈 C6) - 新檔 `apps/api/src/services/self_healing_validator.py`(純函數 assess_self_healing) - post_execution_verifier.py step 5 串接(feature flag gate) - evidence_snapshot.py 加 self_healing_score / self_healing_detail 欄位 - db/models.py + base.py ALTER IF NOT EXISTS - score < 0.5 → 觸發 rollback 提案 Telegram alert(不自動執行) - ENABLE_SELF_HEALING_VALIDATOR=false (default) - 7 個測試 ### PR-L1 — KM ↔ Playbook 雙向回路 (修飛輪斷鏈 C3+C4) - learning_service.py 三條新邏輯: 1. _write_playbook_evolution_km:promote/demote 寫 KM 演化條目 2. _check_and_mark_playbook_review:N=5 累積觸發 review_required 3. _demote_alert_rule_catalog_confidence:DEPRECATED → confidence×=0.5 - PlaybookRecord 加 review_required 欄位(schema migration via base.py) - ENABLE_KM_PLAYBOOK_FEEDBACK_LOOP=false (default) - KM_PLAYBOOK_REVIEW_THRESHOLD=5 可調 - 6 個測試 ## KMWriter Critic 5 個 Critical/Major 修復(之前 critic PR review 發現) 之前 push commitc5753e1c已修,本 commit 補回 stash 中的對應檔案: - C1 km_writer.py:194 backfill 自打臉(已修:同步 await + DLQ) - C2 km_writer.py:391 KM_WRITE_AWAIT=false 路徑收緊 - M1 decision_manager.py:2178/2203 移除 _fire_and_forget - M2 incident_service.py:1099 自製 path 加 retry+DLQ - M3 km_writer.py:166 冪等聲明對齊(UPSERT + partial unique index) ## 驗證 - 1635 unit tests 全綠(+27 from 1608) - 與fb0c72db(推翻 A2 Ollama primary) 共存無衝突 - 所有新 Job/Service default flag=false(不爆炸) ## 期望影響 飛輪斷鏈 C2 + C3 + C4 + C6 全修 飛輪自主化評分:65 → 85 預估(W2 完成後) 啟用順序(待 prodfb0c72db驗證 OLLAMA primary 跑得起來後): 1. ENABLE_AOL_WRITEBACK_JOB=true 2. ENABLE_KM_PLAYBOOK_FEEDBACK_LOOP=true 3. ENABLE_SELF_HEALING_VALIDATOR=true Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -932,6 +932,20 @@ class IncidentEvidence(Base):
|
||||
String(20), nullable=True, comment="success / degraded / failed / timeout(PostExecutionVerifier 填入)"
|
||||
)
|
||||
|
||||
# W2 PR-V1: SelfHealingValidator 自愈品質分數 (2026-04-28 ogt + Claude Sonnet 4.6)
|
||||
# 0.0-1.0:1.0=完全自愈,<0.5=觸發 rollback 提案(Telegram 警示)
|
||||
# base.py ALTER IF NOT EXISTS 補欄對應下方
|
||||
self_healing_score: Mapped[float | None] = mapped_column(
|
||||
Float,
|
||||
nullable=True,
|
||||
comment="W2 PR-V1 SelfHealingValidator 自愈品質分數(0.0-1.0),<0.5 觸發 rollback 提案",
|
||||
)
|
||||
self_healing_detail: Mapped[dict | None] = mapped_column(
|
||||
JSON,
|
||||
nullable=True,
|
||||
comment="W2 PR-V1 SelfHealingValidator 評估明細:root_cause_cleared/regressions/detail",
|
||||
)
|
||||
|
||||
# 時間戳(台北時區)
|
||||
collected_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=taipei_now, nullable=False
|
||||
@@ -1017,6 +1031,14 @@ class PlaybookRecord(Base):
|
||||
stateful_targets: Mapped[list[str]] = mapped_column(JSON, default=list, nullable=False)
|
||||
requires_pre_backup: Mapped[bool] = mapped_column(default=False, nullable=False)
|
||||
|
||||
# W2 PR-L1 2026-04-28 ogt + Claude Sonnet 4.6: KM→Playbook 互饋回路(飛輪 C3 修復)
|
||||
# 同 symptom_pattern_hash 累積 N=5 條 KM 後,LearningService 自動設 True
|
||||
# 人工 review 後可重設為 False(由 playbook_service 負責清除)
|
||||
review_required: Mapped[bool] = mapped_column(
|
||||
Boolean, default=False, nullable=False,
|
||||
comment="W2 PR-L1: True=KM 累積觸發人工複審信號(symptom_hash≥5 條),review 後清為 False",
|
||||
)
|
||||
|
||||
# Timestamps
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=taipei_now, nullable=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=taipei_now,
|
||||
@@ -1026,6 +1048,12 @@ class PlaybookRecord(Base):
|
||||
Index("ix_playbook_status", "status"),
|
||||
Index("ix_playbook_trust_score", "trust_score"),
|
||||
Index("ix_playbook_created_at", "created_at"),
|
||||
# W2 PR-L1: 快速查詢需要人工 review 的 Playbook(預期數量少,partial index 最省空間)
|
||||
Index(
|
||||
"ix_playbook_review_required",
|
||||
"review_required",
|
||||
postgresql_where=text("review_required = true"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user