feat(km): P1-1 KMWriter 統一契約 + 5 caller 切換 + M4 反查鏈補齊
12-Agent 全景診斷揪出 KM 寫入鏈路 5 條入口無統一契約,fire-and-forget 在 Pod recycle 時會丟失條目。本次抽 KMWriter 強制 7 條契約。 ## 7 條契約強制 1. 同步底線:強制 await asyncio.wait_for(timeout) 2. 重試:3 次指數退避 1s/2s/4s(OperationalError / 網路類例外) 3. 失敗回收:3 次後寫 Redis DLQ km:dlq + log 4. 觀測:structlog event + 預留 metric hook(P1-3 補 emitter) 5. 冪等:incident_id + path_type 為 unique key 6. 禁止吞例外:except 必須 log + raise/DLQ 7. M4 反查鏈:payload 含 approval_id 時自動填 related_approval_id 並回填 Path A ## Caller 切換(5 條入口統一介面) - incident_service.py:1086 Path A(KB extractor + km_conversion) - approval_execution.py:771 Path B-人工 - decision_manager.py:2178 Path B-自動成功(消除跨類私有方法調用 M1) - decision_manager.py:2200 Path B-自動失敗(修 B2 早期吞例外) - playbook_service.py:210 PlaybookKM(兩份 T0 報告都漏的第三條) ## M4 反查鏈補齊 - knowledge.py + models.py: 補 related_approval_id ORM 欄位 - 對齊 phase26_incident_km_integration.sql:20 schema(partial index 已存在) - approval↔KM 雙向反查鏈完整(dual-path 縫合線) ## Feature Flag (rollback 保險) - KM_WRITE_AWAIT=true (default): await + timeout + DLQ 強制 - KM_WRITE_AWAIT=false: fire-and-forget(舊行為) ## 測試 - apps/api/tests/test_km_writer.py: 18 測試全綠 覆蓋 success / timeout / retry / DLQ / 冪等 / KMWriteError / on_failure=raise / 反查鏈回填 - 1552 unit tests 全綠(無回歸) ## 驗收 飛輪閉環核心 — KM 寫入不再靜默丟失,AI 學習鏈不斷裂。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2172,11 +2172,10 @@ class DecisionManager:
|
||||
)
|
||||
|
||||
# 2026-04-25 ogt + Claude Sonnet 4.6: 飛輪閉環 — auto_execute 路徑補 KM 寫入
|
||||
# 根因:Explore agent 確認 _write_execution_result_to_km 只在人工審核路徑呼叫
|
||||
# auto_execute 路徑執行完成後沒有 KM 回寫 → 學習飛輪斷鏈
|
||||
# 修法:複用 executor._write_execution_result_to_km,與人工路徑共享同一 KM schema
|
||||
# P1-1 2026-04-28 ogt + Claude Sonnet 4.6: 改用 write_execution_result_to_km(公開)
|
||||
# KMWriter 統一契約,feature flag KM_WRITE_AWAIT 控制 await/fire-and-forget
|
||||
_fire_and_forget(
|
||||
executor._write_execution_result_to_km(approval, _exec_success, None)
|
||||
executor.write_execution_result_to_km(approval, _exec_success, None)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
@@ -2198,11 +2197,10 @@ class DecisionManager:
|
||||
)
|
||||
|
||||
# P1.1 fix 2026-04-27 ogt + Claude Sonnet 4.6: 失敗路徑補 KM 寫入
|
||||
# 根因:auto_execute 拋出例外時,學習飛輪完全拿不到失敗記錄
|
||||
# 修法:若 executor/approval 已建立,fire-and-forget 寫入失敗 KM;未建立則跳過
|
||||
# P1-1 2026-04-28 ogt + Claude Sonnet 4.6: 改用 write_execution_result_to_km(公開)
|
||||
if _km_executor is not None and _km_approval is not None:
|
||||
_fire_and_forget(
|
||||
_km_executor._write_execution_result_to_km(
|
||||
_km_executor.write_execution_result_to_km(
|
||||
_km_approval, False, str(e)
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user