fix(cd-blocker): 補 knowledge_entries 防禦性 ALTER(解 CD #1115-1117 全 failure)
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m38s

🚨 真根因:CD pipeline 從昨天 push fb0c72db 起,4 個 commit (1114-1117) 全 failure
prod pod 28 小時沒更新 → 統帥 17:33/17:35 看到的 Telegram 告警仍是「llm_failed」
不是 ai_router 沒推翻 A2,是**部署根本沒上 prod**。

## CD 失敗證據(gitea actions API)

```
#1117 7b471e7a failure  Gemini sanitize
#1116 3668d49f failure  W2 三件 + KMWriter critic
#1115 fb0c72db failure  推翻 A2 DIAGNOSE Ollama primary
#1114 8d24f151 failure  PR-R1 4 Major 修
#1113 681b5ac9 success  PR-R1 規則→Playbook 遷移  ← 最後一次成功
```

## 失敗 Stack Trace(job 1267 logs)

```
sqlalchemy.exc.ProgrammingError: column "related_approval_id"
of relation "knowledge_entries" does not exist
SQL: INSERT INTO knowledge_entries (..., related_approval_id, path_type, ...)
test: tests/integration/test_b5_core_flows.py::test_knowledge_entry_view_count
```

## 根因

commit c22e5f33 (KMWriter) 加 ORM 欄位 `related_approval_id` + `path_type`:
- `models.py` ORM Mapped 欄位 
- `knowledge.py` Pydantic schema 
- `migrations/p1_1_km_idempotent_path_type.sql` 加 path_type 
- **但 `db/base.py:init_db()` 沒對應 ALTER**

CI integration test 用 prod schema 建 PG → 既有表沒有新欄位 → INSERT 失敗。
我之前只補了 `timeline_events.incident_id` 的 ALTER,漏了 `knowledge_entries`。

## 修法

`db/base.py:init_db()` 補 3 條防禦性 SQL(同 timeline_events 模式):
```sql
ALTER TABLE knowledge_entries
    ADD COLUMN IF NOT EXISTS related_approval_id VARCHAR(64),
    ADD COLUMN IF NOT EXISTS path_type VARCHAR(50);
CREATE UNIQUE INDEX IF NOT EXISTS uix_knowledge_incident_path
    ON knowledge_entries(related_incident_id, path_type)
    WHERE related_incident_id IS NOT NULL AND path_type IS NOT NULL;
CREATE INDEX IF NOT EXISTS ix_knowledge_related_approval
    ON knowledge_entries(related_approval_id)
    WHERE related_approval_id IS NOT NULL;
```

## 驗證

- 1635 unit tests 全綠
- 預期 CD #1118 (本 commit) 解 4 個失敗 commit 的部署 backlog
- 部署完成後 prod ai_router fb0c72db 推翻 A2 才會真的生效

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-04-29 20:44:23 +08:00
parent 7b471e7ae2
commit c5b1810172

View File

@@ -242,6 +242,30 @@ async def init_db() -> None:
""")
)
# 2026-04-29 ogt + Claude Opus 4.7: M4 KMWriter 反查鏈 + 冪等補欄
# CD #1115-1117 全 failure 根因commit c22e5f33 加 ORM 欄位但無對應 ALTER
# 錯誤column "related_approval_id" of relation "knowledge_entries" does not exist
# 補防禦性 ALTER同 timeline_events 模式)+ 對應 index
await conn.execute(
text("""
ALTER TABLE knowledge_entries
ADD COLUMN IF NOT EXISTS related_approval_id VARCHAR(64),
ADD COLUMN IF NOT EXISTS path_type VARCHAR(50);
""")
)
# M3 冪等 unique index (incident_id + path_type)
await conn.execute(text(
"CREATE UNIQUE INDEX IF NOT EXISTS uix_knowledge_incident_path "
"ON knowledge_entries(related_incident_id, path_type) "
"WHERE related_incident_id IS NOT NULL AND path_type IS NOT NULL;"
))
# M4 反查鏈 partial indexapproval_id → KM 反查)
await conn.execute(text(
"CREATE INDEX IF NOT EXISTS ix_knowledge_related_approval "
"ON knowledge_entries(related_approval_id) "
"WHERE related_approval_id IS NOT NULL;"
))
# W2 PR-L1 2026-04-28 ogt + Claude Sonnet 4.6: KM→Playbook 互饋回路(飛輪 C3 修復)
# PlaybookRecord 新增 review_required 欄位
# 已存在表不會被 create_all 重建,必須手動 ALTER