docs(aider-watch): v2 設計稿 — 完全整合 awoooi AI 自主化飛輪

統帥 2026-04-20 指示「C 路線 + 甲 bot」— v1 獨立個人工具路線與
awoooi MASTER blueprint 全景割裂,違反 feedback_ai_autonomous_direction
北極星(純記錄非自主化)。v2 重新對齊:

- DB:進主 PG,新 migration adr091 的 aider_events 表
- Telegram:走既有 telegram_gateway @tsenyangbot + Redis dedup
- Incident:aider error 自動建 incident 走既有告警鏈
- AI 學習回路:symptom_pattern 抽取 + AI Router feedback hook
- Mac client:薄殼 HTTP POST + 本機 JSONL fallback buffer

v1 產物去向:events.py/redactor.py 搬進 awoooi;其他廢棄。
@NemoTronAwoooI_Bot 轉 sandbox 用,不刪。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-04-20 03:33:55 +08:00
parent dbd4470b6d
commit 8ce8efad29
4 changed files with 351 additions and 2 deletions

View File

@@ -1,4 +1,8 @@
# aider-watch Implementation Plan # aider-watch Implementation Planv1 — ⛔ DEPRECATED 2026-04-20
> ⛔ **已被 v2 取代** — 統帥於 2026-04-20 改走「完全整合進 awoooi」路線。
> 新版 plan[2026-04-20-aider-watch-v2.md](2026-04-20-aider-watch-v2.md)
> v1 Task 0-5 已完成(~/aider-watch 8 commitsevents.py + redactor.py 會搬進 awoooi。
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

View File

@@ -1,4 +1,9 @@
# aider-watch 設計稿 # aider-watch 設計稿v1 — ⛔ DEPRECATED 2026-04-20
> ⛔ **已被 v2 取代** — 統帥於 2026-04-20 指出此設計未對齊 awoooi AI 自主化飛輪全景,
> 獨立 PG + 獨立 bot + 獨立 repo 路線與 MASTER blueprint 割裂。
> 新版 spec[2026-04-20-aider-watch-v2-design.md](2026-04-20-aider-watch-v2-design.md)
> v1 保留僅供歷史對照;實作已停在 ~/aider-watch Task 58 commits
> 統帥本機 aider CLI 的全程監控系統 > 統帥本機 aider CLI 的全程監控系統
> 2026-04-19 Brainstorm 定稿,經統帥 §1-§7 逐段批准 > 2026-04-19 Brainstorm 定稿,經統帥 §1-§7 逐段批准

View File

@@ -0,0 +1,340 @@
# aider-watch v2 設計稿 — 完全整合 awoooi 飛輪版
> **建立**2026-04-20 @ Asia/Taipei
> **取代**[v1 2026-04-19](2026-04-19-aider-watch-design.md)(已 DEPRECATED
> **觸發**:統帥 2026-04-20 指示「C 路線 + 甲 bot」— 把 aider-watch 完全整合進 awoooi AI 自主化飛輪,而非獨立個人工具
---
## 0. 為何重寫
v1 把 aider-watch 做成 **獨立個人工具**
- 獨立 repo `~/aider-watch`
- 獨立 PG DB `aider_watch`(放 188 但與 awoooi 平行)
- 獨立 Telegram bot `@NemoTronAwoooI_Bot`
- 被動記錄,無 AI 學習
**根本問題**:純記錄 ≠ AI 自主化。違反 `feedback_ai_autonomous_direction.md`(🔴🔴🔴 最高鐵律的「AI 自主化北極星」— 設計裡沒有 learning、沒有 auto-repair、沒有 decision feedback loop。
**v2 方向**(統帥批准):
- ✅ 進 awoooi 主 PG新 migration 一張 `aider_events` 表)
- ✅ 走 awoooi 既有 Telegram 告警鏈(`@tsenyangbot` + Redis dedup
- ✅ 接進 AI Router feedback loopPhase 24 ADR-052
- ✅ aider error → 自動建 `incident`(走既有事件管線)
- ✅ 從 aider events 抽 `symptom_pattern` → 餵 `playbooks` 學習
- ✅ Mac client 端保留為薄殼,純 HTTP 推送 + 本機 fallback buffer
---
## §1 架構總覽(全景)
```
┌──────────── 統帥 Mac (外部 agent, K3s 外)────────────┐
│ │
│ aiderw (Python wrapper) │
│ ├ subprocess aider + stdout tee │
│ ├ 退出時 git diff / chat_history.md canonical rebuild │
│ ├ redact secrets本地先做一遍
│ └ HTTP POST events → AWOOOI API (HMAC-signed) │
│ │
│ 本機 fallback: ~/aider-watch/buffer/*.jsonl │
API 不可達時寫這裡launchd flush job 5min 補送) │
│ │
│ 本機只留: live.log (append-only, tail -F 用) │
│ 無本機 PG無本機 report │
└──────────────┬───────────────────────────────────────────┘
│ HTTPS + HMAC-SHA256
┌────── AWOOOI API (K3s svc 192.168.0.120:32334) ──────────┐
│ │
│ api/v1/aider_events.py │
│ POST /api/v1/aider/events (HMAC verified) │
│ → push Redis stream signals:aider:events │
│ │
│ jobs/aider_event_processor_job.py (loop, 5s poll) │
│ ├ consume Redis stream │
│ ├ write aider_events table │
│ ├ classify: │
│ │ error / non-zero exit / silent_timeout │
│ │ → 建 incident走 incident_service
│ │ severity: silent=P3, error=P2, multi-error=P1 │
│ │ alert_category: aider_activity │
│ │ → incident_service 自己觸發 TG (既有 dedup 生效) │
│ │ │
│ └ 每 day 聚合: extract symptom_pattern │
│ → 寫 playbooks.symptom_pattern JSONB │
│ 例: {repo: "awoooi", model: "elephant", error_rate: 0.3} │
│ │
│ services/ai_router.py (既有, Phase 24) │
│ 新增 hook: feedback_from_aider_events() │
│ → 讀過去 7 日 aider_events
│ 哪 model × 哪 repo/task 成功率 vs 失敗率 │
│ → 調整 route() 的 provider priority │
│ │
│ services/telegram_gateway.py (既有, 不動) │
│ incident → TG @tsenyangbot + Redis dedup 10min TTL │
└──────────────────────────────────────────────────────────┘
```
**關鍵設計決定**
1. **aider error → incident → 既有鏈路**不做另一套告警機制aider 的錯誤等同 awoooi 其他來源的錯誤,統一 incident table 統一 TG 通道。
2. **Event 進 Redis stream 再處理**:沿用 Phase 6.1 Event Bus pattern。API 層快 response<50ms處理在背景。
3. **AI Router feedback 是學習閉環的核心**這就是「AI 自主化」的體現 — aider-watch 不只是記錄,是餵給 AI Router 讓 model 選擇越來越準。
4. **symptom_pattern 抽取**:日 batch job把 aider 失敗模式抽成 playbook candidate跟 Phase 7 blindspot governance 同一機制)。
5. **Mac 端盡量薄**:只做 event capture + HTTP POST + local buffer。所有商業邏輯在 server。
---
## §2 元件清單
### 2.1 AWOOOI 內新增Server 端)
| # | 檔案 | 職責 | 既有模式參考 |
|---|------|------|--------------|
| S1 | `apps/api/migrations/adr091_aider_events_schema.sql` | DB migration | 既有 `adr090_asset_inventory_foundation.sql` |
| S2 | `apps/api/src/models/aider.py` | Pydantic: `AiderEvent`, `AiderSessionStart`, `AiderFileEdit`, `AiderError`, `AiderSessionEnd`6 種 + 通用外殼) | `models/incident.py` |
| S3 | `apps/api/src/repositories/aider_event_repository.py` | CRUD aider_events + 聚合查詢 | `repositories/incident_repository.py` |
| S4 | `apps/api/src/services/aider_event_service.py` | 分類、建 incident、抽 symptom_pattern | `services/incident_service.py` |
| S5 | `apps/api/src/api/v1/aider_events.py` | POST webhook + HMAC 驗證 | `api/v1/webhooks.py` (Alertmanager) |
| S6 | `apps/api/src/jobs/aider_event_processor_job.py` | Redis stream consumer + 分類 dispatcher + 日 batch pattern extractor | `jobs/asset_scanner_job.py` |
| S7 | `apps/api/src/services/ai_router.py` 新增 `feedback_from_aider_events()` | 從 aider_events 聚合統計 → 調整 model priority | 既有檔改一個 method |
| S8 | `apps/api/src/utils/secret_redactor.py` | 泛用 secret redactor**從 v1 搬過來** | 目前 awoooi 無,新增 |
| S9 | `apps/api/src/core/config.py` 新增 3 個 settings | `AIDER_WEBHOOK_SECRET`, `AIDER_EVENTS_STREAM_KEY`, `AIDER_PATTERN_EXTRACT_INTERVAL_HOURS` | 既有 core/config.py |
| S10 | `apps/api/src/main.py` lifespan 註冊 | `asyncio.create_task(run_aider_event_processor_loop())` | 既有 378-382 pattern |
### 2.2 Mac 端Client
**位置**`awoooi/scripts/aider_watch_client/`(進 awoooi repo不是獨立 repo
| # | 檔案 | 職責 |
|---|------|------|
| M1 | `aider_watch_client/aiderw.py` | subprocess aider + event capture + HTTP POST |
| M2 | `aider_watch_client/parsers.py` | aider stdout banner / chat_history.md / git numstat從 v1 搬) |
| M3 | `aider_watch_client/api_client.py` | HTTP POST with HMAC + retry + buffer fallback |
| M4 | `aider_watch_client/buffer.py` | JSONL buffer本機 fallback |
| M5 | `aider_watch_client/install.sh` | 在 Mac 安裝pipx or venv+ 註冊 launchd flush job |
| M6 | `aider_watch_client/launchd/com.awoooi.aider-flush.plist` | 每 5min flush buffer |
### 2.3 舊 v1 產物去向
| v1 產物 | v2 處理 |
|---------|---------|
| `~/aider-watch/aider_watch/events.py` | ✅ 搬 `apps/api/src/models/aider.py`(改為 awoooi 命名) |
| `~/aider-watch/aider_watch/redactor.py` | ✅ 搬 `apps/api/src/utils/secret_redactor.py` + 同一份用於 Mac client |
| `~/aider-watch/aider_watch/telegram.py` | ❌ 廢棄(走 awoooi telegram_gateway |
| `~/aider-watch/aider_watch/config.py` | ⚠️ 拆Mac 端用的部分搬進 `aider_watch_client/`server 的改讀 awoooi `core/config.py` |
| `~/aider-watch/aider_watch/wrapper.py`(未完成) | 簡化搬進 `aider_watch_client/aiderw.py` |
| `~/aider-watch/bin/aiderw` | 搬 `aider_watch_client/bin/aiderw` |
| `~/aider-watch/pyproject.toml` | 改為 `aider_watch_client/pyproject.toml`client 端獨立 pipx 裝) |
| `~/aider-watch/tests/*` | 搬client 測試留 clientserver 測試改寫走 awoooi pytest 約定 |
| `~/aider-watch/schema.sql` + `install_pg.sh` | ❌ 廢棄v2 用 awoooi migration |
| `~/aider-watch/` repo 本身 | 保留 1 週作備份2026-04-27 後刪(或歸 archive 分支) |
---
## §3 Event Schema與 v1 一致,微調)
7 種 event typeMac 客戶端 POST 的 payload shape
```json
{
"ts": "2026-04-20T10:15:33+08:00",
"session_id": "01J7XZ...", // ULID
"host": "ogt-mac", // 將來多機器區分
"type": "session_start|file_edit|error|commit|silent_timeout|session_end|raw",
"payload": { ... type-specific ( v1 §3) }
}
```
**批次推送**`POST /api/v1/aider/events` body 接受 `{"events": [...]}` 陣列,最多 50 筆/次,降低 HTTP 往返成本。
---
## §4 DB Schema — awoooi 主 PG 新 migration
**Migration**`adr091_aider_events_schema.sql`
```sql
-- aider events raw table單一表event + 一次性 session 元資料合一用 JSONB
-- 設計參考: asset_discovery_run pattern
-- 2026-04-20 @ Asia/Taipei
CREATE TABLE IF NOT EXISTS aider_events (
id BIGSERIAL PRIMARY KEY,
session_id TEXT NOT NULL,
ts TIMESTAMPTZ NOT NULL,
type TEXT NOT NULL, -- session_start / file_edit / error / ...
host TEXT DEFAULT 'ogt-mac',
payload JSONB NOT NULL,
incident_id TEXT, -- 若觸發建 incident記 FK
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX aider_events_session_idx ON aider_events(session_id);
CREATE INDEX aider_events_type_ts_idx ON aider_events(type, ts DESC);
CREATE INDEX aider_events_ts_idx ON aider_events(ts DESC);
-- payload GIN for 查 repo / model 統計
CREATE INDEX aider_events_payload_gin ON aider_events USING GIN (payload);
-- 不另外建 sessions 表:從 events 聚合session_start + session_end 配對),
-- 查詢性能可接受session 量 <1000/day避免雙寫漂移。
```
**symptom_pattern 抽取**:不新增表,直接寫 `playbooks` 表的 `symptom_pattern` JSONB既有
```json
{
"source": "aider_watch",
"repo": "awoooi",
"model": "elephant-alpha",
"task_kind": "refactor",
"error_rate": 0.35,
"evidence_session_ids": ["01J...", "01J..."]
}
```
---
## §5 API 合約
### POST /api/v1/aider/events
**Request**:
```http
POST /api/v1/aider/events
Content-Type: application/json
X-Aider-Signature: sha256=<HMAC-SHA256 of body using AIDER_WEBHOOK_SECRET>
X-Aider-Client: aiderw/0.2.0
{
"events": [
{ "ts": "...", "session_id": "...", "type": "session_start", "payload": {...} },
...
]
}
```
**Response**:
- `202 Accepted``{"accepted": N, "stream_id": "redis-id"}`(快速 ack不等處理完成
- `401 Unauthorized` → HMAC 驗證失敗
- `400 Bad Request` → schema 驗證失敗,回具體錯誤欄位
- `429 Too Many Requests` → 超過 rate limit預設 120 req/min per client
- `503 Service Unavailable` → Redis 不可達client 必須 fallback 到 buffer
**HMAC 驗證**
```python
import hmac, hashlib
expected = "sha256=" + hmac.new(
AIDER_WEBHOOK_SECRET.encode(),
request.body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
abort(401)
```
---
## §6 AI 學習回路
### 6.1 incident 自動建立(即時)
`aider_event_service.handle_error_event(ev)`
-`type in {"error", "session_end with exit≠0", "silent_timeout"}`
- 建 incident:
- `alert_category = "aider_activity"`
- `severity = P1 if error_count>=3 else P2 if error else P3 if silent_timeout`
- `affected_services = [repo_name]`
- `signals = {source: "aider_watch", session_id, model, last_error_message}`
- incident_service 自動觸發既有 Telegram gatewaydedup 10min TTL 自動生效)
### 6.2 symptom_pattern 日 batch 抽取
`aider_event_processor_job.extract_patterns_daily()`(每日 02:30 台北):
- 聚合近 7 日 aider_events
- group by (repo, model, task_kind)
- 計算 error_rate / avg_tokens / avg_duration
-`error_rate >= 0.25``sample_n >= 3` → 寫 playbook candidate
### 6.3 AI Router feedback hook每次 route() 呼叫)
`ai_router.py` 加:
```python
def feedback_from_aider_events(repo: str, task_kind: str) -> dict[str, float]:
"""回傳 {model_name: success_rate} based on past 7 days aider usage."""
# 從 aider_event_repository 聚合
return {"elephant-alpha": 0.85, "gemini-pro": 0.92, ...}
```
`AIRouter.route()` 內:如果有 feedback data把 provider 權重乘 `success_rate`
---
## §7 Telegram 整合
**100% 複用既有 `services/telegram_gateway.py`,零新增 bot**
- aider error → incident created → `telegram_gateway.send_alert(incident)`
- 訊息格式走 awoooi SOUL.md 標準(不再自訂 🚀/🏁 emoji 模板)
- Redis dedup `telegram_sent:{incident_id}` TTL 600s 自動生效
- bot `@tsenyangbot`chat_id 從 K8s secret `TELEGRAM_CHAT_ID`
**aider 非 error 事件session_start / file_edit / commit****不推 Telegram**,只寫 aider_events 表。理由:
- awoooi Telegram 是 **告警通道**,不該塞正常活動洗版
- 統帥要看活動 → 下次加 `/api/v1/aider/activity_feed` REST 查詢或前端 dashboard
- 若你堅持要推,單獨開 `AIDER_WATCH_PUSH_ACTIVITY` flag 預設 false
### ⚠️ v1 @NemoTronAwoooI_Bot 怎麼處理
- 這支 bot 2026-04-19 才建,無生產依賴
- v2 不用它 → 建議 **deactivate****改用途**(例如 aider 測試 sandbox 用)
- 不刪 botBotFather 刪除不可逆)
---
## §8 錯誤處理 / 降級策略
| 失敗情境 | 處理 | 結果 |
|---------|------|------|
| **AWOOOI API 不可達** | Mac client 寫 `~/aider-watch/buffer/*.jsonl`launchd flush job 每 5min 重試 | 不丟資料 |
| **HMAC 驗證失敗** | API 回 401`audit_log`Mac client 留 buffer 等人工介入 | 防偽造 |
| **Redis stream 滿** | 自動 trim 10k 筆上限;溢位寫 `audit_log` warning | 不阻塞 API |
| **aider_event_processor 掛** | 既有 main.py lifespan supervisor 會重啟;消費位置從 Redis stream consumer group 恢復 | 自癒 |
| **incident_service 建 incident 失敗** | 降級:只寫 aider_events 表,不建 incidentTG 不推可接受event 還在) | 不丟資料 |
| **secret 外洩** | Mac client 進 buffer 前先 redactserver 再 redact 一次depth-in | 雙層防線 |
| **wrapper 崩潰** | aiderw 外層 try/except 全包atexit 補 session_end | aider 照跑 |
| **aider 本身崩潰** | wrapper 收 SIGCHLD → 送 error event + session_end exit≠0 | 死得清楚 |
---
## §9 測試策略
遵循 `feedback_no_mock_testing.md`
| 層級 | 範圍 | 工具 | 通過標準 |
|------|------|------|----------|
| **Unit (server)** | models schema, secret_redactor, HMAC 驗證, pattern extractor | pytest | 100% pass |
| **Unit (client)** | aiderw parsers, api_client retry, buffer write | pytest | 100% pass |
| **Integration (server)** | 真寫 PG `aider_events`, Redis stream round-trip | pytest + real PG (168 test schema) | round-trip OK |
| **Integration (client→server)** | Mac client POST events → server 消費 → 寫 DB → 查詢 | 本機 pytest + 打 awoooi API | 全流程通 |
| **E2E happy** | 真 aiderw 跑一次 aider →events 進 awoooi DB → 若 error 建 incident → TG 收到 | 手動 | TG 收到(走 @tsenyangbot 不是新 bot |
| **E2E degradation** | 拔網路跑 aiderw → buffer 有檔 → 網路恢復 + flush job 跑 → buffer 清空 + DB 補齊 | 手動 | buffer → DB 無漏 |
| **AI Router feedback** | 灌 10 場 aider session 資料 → 查 ai_router.feedback_from_aider_events 回傳值 → 驗 success_rate 合理 | pytest | 數值正確 |
---
## §10 相關 Memory 依據
- `feedback_ai_autonomous_direction.md` 🔴🔴🔴 — AI 自主化北極星(這是 v2 存在的根本原因)
- `feedback_alertmanager_awoooi_flow.md` — 告警鏈路 Alertmanager→AWOOOI API→TG
- `feedback_telegram_dedup.md` — Redis dedup 10min TTL
- `feedback_secrets_leak_incidents_2026-04-18.md` — secret 雙層 redact
- `feedback_architecture_review_gates.md` 🔴🔴 — 重大方向變更需架構 review本 v2 就是)
- `feedback_solution_adoption_checklist.md` — 解決方案導入 7 問(已對照)
- `project_master_aiops_blueprint.md` — AI 自主化 MASTER blueprint 全景
- `project_blindspot_governance.md` 🔴🔴🔴 — Phase 7 盲區治理symptom_pattern 抽取沿用)
- `project_phase24_ai_router.md` — AI Router D1-D14 決策
---
## §11 後續
本設計批准後:
1. 寫 v2 plan`2026-04-20-aider-watch-v2.md`
2. 暫停 `~/aider-watch` repo 開發Task 6 不跑 install_pg.sh
3. 按 v2 plan 執行 server + client 雙半實作
4. Mac client 部署在 awoooi repo 而非獨立

View File