2026-04-18 晚(台北時區)— ogt + Claude Opus 4.7 (1M) MASTER §7.1 15 個北極星 KPI 實測對標發現 5 個斷鏈: #3 fine-tune JSONL /week — finetune_exports 表不存在 #4 MCP 呼叫/24h — timeline_events 沒 mcp_call event_type #6 Declarative 修復使用率 — remediation_events 表不存在 #7 general 兜底 17.3% — classify_alert_early 漏 5 類 #10 notification_outcomes /week — 表不存在 本 commit 全修。 ## 1. Migration: adr090d_kpi_data_sources.sql (3 張表) - finetune_exports — P3 Fine-tune JSONL 追蹤 - remediation_events — P5 Declarative 修復追蹤 - notification_outcomes — 通知品質 + RLHF 語料 Idempotent (CREATE TABLE IF NOT EXISTS), 已 apply 進 prod。 ## 2. classify_alert_early 擴 4 類規則 (降 general 兜底) - test 攔截: Test*/FPTest/FingerprintTest/ADR089*Test/L4Closure*/*FreshUniq* → category='test', TYPE-1 純通知 - High*CPU/Memory/Disk/Load → host_resource - TLS*/SSL*/*ProbeFailure* → ssl_cert - PostgreSQL*/MySQL*/MongoDB*/*DiskGrowthRate → database 預期 general 17.3% → 3-5% (達標 <10%)。 ## 3. finetune_exporter DB 寫入 _run_export() 結尾寫 finetune_exports 一筆,含 checksum/size/record_count。 ## 4. declarative_remediation DB 寫入 evaluate() 後 fire-and-forget _log_remediation_event() 寫 remediation_events (status='pending', remediation_type 依 tier 自動判為 declarative/imperative/gitops_pr)。 ## 5. telegram_gateway DB 寫入 (send_approval_card) _send_request 成功返回 message_id 後寫 notification_outcomes 一筆, channel='telegram', delivery_status='delivered|failed'。未來人類按鈕時 update user_action → RLHF 訓料黃金。 ## 6. pre_decision_investigator MCP 呼叫追蹤 _call_single_tool() finally 寫 timeline_events event_type='mcp_call', 含 provider/tool/status/duration_ms/error。24h 內 MCP 呼叫可 SQL 量測。 ## 預期量化改善 | KPI | 修前 | 修後 24h 後應見 | |-----|------|----------------| | #3 fine-tune /week | 0 (表不存在) | >=10 (每週 cron 跑) | | #4 MCP 呼叫/24h | 0 | >0 (實測將寫 timeline) | | #6 declarative 使用率 | 表不存在 | 有資料 (pending/success/failed 分佈) | | #7 general 兜底 | 17.3% | <10% | | #10 notification_outcomes | 0 | 每次 approval card 寫一筆 | Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
150 lines
8.0 KiB
SQL
150 lines
8.0 KiB
SQL
-- ADR-090-D: MASTER §7.1 北極星 KPI 資料源建立
|
|
-- 建立時間: 2026-04-18 晚 (台北時區)
|
|
-- 建立者: ogt + Claude Opus 4.7 (1M)
|
|
--
|
|
-- 背景:
|
|
-- MASTER §7.1 15 個 KPI 對標發現 4 張關鍵表根本沒建立,導致以下 KPI 永遠
|
|
-- 量不到:
|
|
-- #3 fine-tune JSONL /week → finetune_exports 表
|
|
-- #6 Declarative 修復使用率 → remediation_events 表
|
|
-- #10 notification_outcomes → notification_outcomes 表
|
|
--
|
|
-- 此 migration 補齊 3 張資料源表(idempotent)。
|
|
--
|
|
-- 對應 MASTER § 指標:
|
|
-- §3.3 D3 修復抽象(Imperative → Declarative)
|
|
-- §3.4 D4 學習深度(Fine-tune)
|
|
-- §3.6 D6 自我治理(通知品質)
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
-- 1. finetune_exports — Phase 3 Fine-tune JSONL 產出追蹤
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
|
|
CREATE TABLE IF NOT EXISTS finetune_exports (
|
|
export_id BIGSERIAL PRIMARY KEY,
|
|
export_type TEXT NOT NULL, -- 'evidence_snapshot' | 'agent_session' | 'decision_outcome'
|
|
source_table TEXT, -- 來源表名 (incidents / agent_sessions ...)
|
|
source_ids TEXT[], -- 涵蓋的 source record ids
|
|
file_path TEXT, -- 匯出的 JSONL 檔案路徑
|
|
record_count INT NOT NULL DEFAULT 0,
|
|
size_bytes BIGINT,
|
|
checksum_sha256 TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
CONSTRAINT finetune_export_type_valid CHECK (export_type IN (
|
|
'evidence_snapshot','agent_session','decision_outcome',
|
|
'incident_rca','playbook_outcome','rlhf_trace'
|
|
))
|
|
);
|
|
|
|
COMMENT ON TABLE finetune_exports IS
|
|
'ADR-090-D: MASTER §7.1 #3 Fine-tune JSONL 產出追蹤。每次 finetune_exporter 匯出寫一筆。';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_finetune_exports_created
|
|
ON finetune_exports(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_finetune_exports_type
|
|
ON finetune_exports(export_type);
|
|
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
-- 2. remediation_events — Phase 5 Declarative 修復追蹤
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
|
|
CREATE TABLE IF NOT EXISTS remediation_events (
|
|
event_id BIGSERIAL PRIMARY KEY,
|
|
incident_id TEXT,
|
|
approval_id TEXT,
|
|
remediation_type TEXT NOT NULL, -- 'declarative' | 'imperative' | 'gitops_pr' | 'kubectl'
|
|
action_name TEXT,
|
|
target_resource TEXT, -- deployment/awoooi-api 等
|
|
namespace TEXT,
|
|
dry_run BOOLEAN NOT NULL DEFAULT false,
|
|
status TEXT NOT NULL, -- 'pending' | 'success' | 'failed' | 'rolled_back'
|
|
error_message TEXT,
|
|
blast_radius_score INT,
|
|
duration_ms INT,
|
|
executed_by TEXT, -- 'ai_agent' | 'human:ogt' | 'cron'
|
|
triggered_by_op_id UUID, -- 指向 automation_operation_log.op_id
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
completed_at TIMESTAMPTZ,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
CONSTRAINT remediation_type_valid CHECK (remediation_type IN (
|
|
'declarative','imperative','gitops_pr','kubectl','ansible','helm','argocd_sync'
|
|
)),
|
|
CONSTRAINT remediation_status_valid CHECK (status IN (
|
|
'pending','success','failed','rolled_back','dry_run_ok','dry_run_failed'
|
|
))
|
|
);
|
|
|
|
COMMENT ON TABLE remediation_events IS
|
|
'ADR-090-D: MASTER §7.1 #6 Declarative 修復使用率。每次 declarative_remediation 執行寫一筆。';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_remediation_events_time
|
|
ON remediation_events(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_remediation_events_type
|
|
ON remediation_events(remediation_type);
|
|
CREATE INDEX IF NOT EXISTS idx_remediation_events_incident
|
|
ON remediation_events(incident_id) WHERE incident_id IS NOT NULL;
|
|
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
-- 3. notification_outcomes — 通知成果追蹤
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
|
|
CREATE TABLE IF NOT EXISTS notification_outcomes (
|
|
outcome_id BIGSERIAL PRIMARY KEY,
|
|
incident_id TEXT,
|
|
approval_id TEXT,
|
|
channel TEXT NOT NULL, -- 'telegram' | 'email' | 'slack' | 'webhook'
|
|
notification_type TEXT, -- TYPE-1/2/3/4/4D/5S/6B/7E/8M
|
|
recipient TEXT, -- chat_id / email / user
|
|
message_id TEXT, -- telegram message_id 等
|
|
sent_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
delivery_status TEXT NOT NULL, -- 'delivered' | 'failed' | 'pending'
|
|
delivery_error TEXT,
|
|
-- 人類互動追蹤 (RLHF 語料黃金)
|
|
user_action TEXT, -- 'approved' | 'rejected' | 'silenced' | 'ignored' | 'no_response'
|
|
user_action_at TIMESTAMPTZ,
|
|
user_comment TEXT,
|
|
-- 通知品質
|
|
snoozed_count INT NOT NULL DEFAULT 0,
|
|
time_to_action_sec INT, -- 收到到按鈕按下的秒數
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
CONSTRAINT notif_channel_valid CHECK (channel IN (
|
|
'telegram','email','slack','webhook','sms','discord'
|
|
)),
|
|
CONSTRAINT notif_delivery_valid CHECK (delivery_status IN (
|
|
'delivered','failed','pending','rate_limited'
|
|
))
|
|
);
|
|
|
|
COMMENT ON TABLE notification_outcomes IS
|
|
'ADR-090-D: MASTER §7.1 #10 notification_outcomes 追蹤。每次 telegram_gateway 推送寫一筆,用戶按鈕觸發時 update user_action。';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_notification_outcomes_sent
|
|
ON notification_outcomes(sent_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_notification_outcomes_incident
|
|
ON notification_outcomes(incident_id) WHERE incident_id IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_notification_outcomes_approval
|
|
ON notification_outcomes(approval_id) WHERE approval_id IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_notification_outcomes_pending_action
|
|
ON notification_outcomes(sent_at DESC)
|
|
WHERE user_action IS NULL AND delivery_status='delivered';
|
|
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
-- 驗收 (執行後可手動跑)
|
|
-- ═══════════════════════════════════════════════════════════════════
|
|
|
|
-- SELECT table_name FROM information_schema.tables
|
|
-- WHERE table_schema='public'
|
|
-- AND table_name IN ('finetune_exports','remediation_events','notification_outcomes')
|
|
-- ORDER BY table_name;
|
|
-- 預期: 3 筆
|
|
|
|
-- SELECT conname FROM pg_constraint WHERE conrelid IN (
|
|
-- 'finetune_exports'::regclass,
|
|
-- 'remediation_events'::regclass,
|
|
-- 'notification_outcomes'::regclass
|
|
-- ) AND contype='c' ORDER BY conname;
|