feat(flywheel): W1 PR-R1 規則→Playbook 遷移 + PR-K1 timeline 防禦 ALTER
W1 第二波:onboarder 飛輪 80→90 路徑剩餘兩件 PR。 ## PR-R1 — 25 條 yaml 規則 → DRAFT Playbook 遷移 斷鏈背景(onboarder C2):alert_rules.yaml 25 條規則 68% 寫死 RESTART, 沒有對應 Playbook → RAG 永遠 generic_fallback → 規則命中率沒回饋給 catalog。 修法: - 新建 services/rule_to_playbook_migrator.py - 自動從 alert_rules.yaml 解析每條 rule - 產生 PlaybookRecord(status=DRAFT, ai_confidence=0.3, source=YAML_RULE) - 誠實標示信心 0.3(非假 1.0,違反 feedback_confidence_truthfulness) - INSERT ON CONFLICT 冪等(name LIKE 'AutoMigrated: %' 去重,不擾動 seed) - 新建 scripts/migrate_rules_to_playbooks.py(CLI: --dry-run/--commit/--disable-flag) - ENABLE_RULE_MIGRATION_DRAFT=true(rollback flag) - 23 測試覆蓋(parse / build_dict / idempotent / dry_run / action_type / severity_map / feature_flag / wildcard_filter / partial_existing 等) ## PR-K1 — timeline_events 防禦性 ALTER(db-expert finding) 任務原前提錯誤:onboarder 報告的 C7 斷鏈(incident_id 欄位)在 2026-04-24 P1.6 已修復 ORM。但生產環境若在 P1.6 前已建表,create_all 跳過 已存在的表 → ORM 寫入 SELECT 仍可能找不到 column。 修法: - db/base.py:init_db() 補防禦性 ALTER: ALTER TABLE timeline_events ADD COLUMN IF NOT EXISTS incident_id VARCHAR(64); CREATE INDEX IF NOT EXISTS ix_timeline_incident_id ON timeline_events(incident_id); - IF NOT EXISTS 為 no-op 安全(已有 column 不做事) - stage 欄位是任務描述的幻覺(codebase 0 writer),不新增 未做: - alembic migration(專案不用 alembic,遵循既有 init_db ALTER pattern) - onboarder C7 在 ORM 層已修,本 commit 確保 prod schema 對齊 ## 驗證 - 1608 unit tests 全綠(+23 from 1585) - PR-R1 23 個測試獨立通過 ## 期望影響 - 飛輪 RAG 終於有 25 條 DRAFT Playbook 可查 → +5 分 - prod schema 對齊保險 → 防 ORM SELECT 失敗 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -220,6 +220,21 @@ async def init_db() -> None:
|
||||
""")
|
||||
)
|
||||
|
||||
# 2026-04-29 ogt + Claude Opus 4.7: PR-K1 防禦性 ALTER (db-expert finding)
|
||||
# P1.6 (2026-04-24) ORM 已加 timeline_events.incident_id,但 prod 若在 P1.6 前
|
||||
# 已建表,create_all 跳過已存在的表 → ALTER 不會跑 → ORM 寫入 SELECT 找不到欄位
|
||||
# 補防禦性 IF NOT EXISTS(已有 column 為 no-op,安全)
|
||||
await conn.execute(
|
||||
text("""
|
||||
ALTER TABLE timeline_events
|
||||
ADD COLUMN IF NOT EXISTS incident_id VARCHAR(64);
|
||||
""")
|
||||
)
|
||||
await conn.execute(text(
|
||||
"CREATE INDEX IF NOT EXISTS ix_timeline_incident_id "
|
||||
"ON timeline_events(incident_id);"
|
||||
))
|
||||
|
||||
# 2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 6 自我治理閉環
|
||||
# ADR-087: ai_governance_events 不可變 Event Sourcing 表
|
||||
# asyncpg 不允許 prepared statement 內多條指令,必須分開 execute
|
||||
|
||||
Reference in New Issue
Block a user