Your Name
c22e5f334e
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>
2026-04-29 10:44:39 +08:00
..
2026-04-25 03:29:38 +08:00
2026-04-27 14:57:16 +08:00
2026-03-26 16:06:20 +08:00
2026-04-25 02:33:43 +08:00
2026-04-05 14:45:02 +08:00
2026-03-31 16:25:00 +08:00
2026-04-10 11:22:57 +08:00
2026-04-06 11:49:24 +08:00
2026-04-27 08:15:53 +08:00
2026-04-27 08:15:53 +08:00
2026-04-27 20:04:49 +08:00
2026-04-22 01:33:30 +08:00
2026-04-20 04:13:02 +08:00
2026-04-22 01:41:34 +08:00
2026-04-20 19:40:01 +08:00
2026-04-20 19:40:01 +08:00
2026-04-14 14:39:14 +08:00
2026-04-14 15:10:10 +08:00
2026-04-25 00:14:07 +08:00
2026-03-29 15:27:49 +08:00
2026-04-14 14:39:14 +08:00
2026-03-29 15:27:49 +08:00
2026-04-27 08:11:40 +08:00
2026-04-27 15:22:31 +08:00
2026-04-14 20:43:40 +08:00
2026-03-29 15:48:03 +08:00
2026-04-12 22:50:20 +08:00
2026-04-27 08:11:40 +08:00
2026-04-27 08:11:40 +08:00
2026-04-27 16:12:30 +08:00
2026-04-27 19:46:56 +08:00
2026-04-27 08:11:40 +08:00
2026-04-11 22:05:52 +08:00
2026-04-27 14:42:29 +08:00
2026-04-27 08:11:40 +08:00
2026-04-26 20:56:19 +08:00
2026-03-31 12:16:54 +08:00
2026-04-15 12:44:53 +08:00
2026-04-14 18:43:29 +08:00
2026-04-11 21:33:19 +08:00
2026-04-26 20:17:17 +08:00
2026-04-01 11:11:50 +08:00
2026-04-28 15:27:33 +08:00
2026-04-27 15:06:58 +08:00
2026-04-07 11:17:40 +08:00
2026-03-31 16:16:16 +08:00
2026-04-27 14:54:19 +08:00
2026-04-29 10:44:39 +08:00
2026-04-26 20:44:19 +08:00
2026-03-31 12:20:29 +08:00
2026-04-26 20:18:33 +08:00
2026-03-26 16:06:20 +08:00
2026-04-15 13:08:38 +08:00
2026-04-12 13:32:42 +08:00
2026-04-27 14:57:16 +08:00
2026-04-27 14:58:46 +08:00
2026-03-29 20:49:23 +08:00
2026-04-03 14:00:21 +08:00
2026-04-26 20:18:33 +08:00
2026-04-27 15:47:41 +08:00
2026-04-26 20:18:33 +08:00
2026-04-16 00:13:00 +08:00
2026-04-27 08:11:40 +08:00
2026-04-27 08:17:59 +08:00
2026-04-09 08:55:21 +08:00
2026-04-05 00:14:50 +08:00
2026-04-05 00:14:50 +08:00
2026-03-26 16:06:20 +08:00
2026-04-14 15:19:54 +08:00
2026-04-15 13:08:38 +08:00
2026-04-15 13:08:38 +08:00
2026-03-31 14:17:36 +08:00
2026-04-27 19:56:51 +08:00
2026-03-29 16:23:30 +08:00
2026-03-23 23:51:37 +08:00
2026-04-14 14:39:14 +08:00
2026-04-27 16:08:50 +08:00
2026-04-15 13:08:38 +08:00
2026-04-20 04:23:09 +08:00
2026-04-27 08:24:59 +08:00
2026-04-27 16:00:00 +08:00
2026-04-09 09:01:59 +08:00
2026-04-27 14:42:29 +08:00
2026-04-10 01:12:00 +08:00
2026-04-26 20:48:51 +08:00
2026-04-27 19:56:51 +08:00
2026-04-12 21:08:48 +08:00
2026-04-12 21:20:16 +08:00
2026-03-31 16:16:16 +08:00
2026-04-22 01:27:39 +08:00
2026-04-27 08:24:37 +08:00
2026-04-27 08:11:40 +08:00
2026-04-27 15:06:58 +08:00