Files
ewoooc/docs/phase6_critic_signoff_20260503.md
OoO 4648673423 db(p1): ai_calls/mcp_calls/budgets schema + bge-m3 signature
migrations 024/025/026 — 統一 LLM 遙測 + 預算告警 + RAG 一致性護欄
- 024: ai_calls 表 + 5 索引 + 6 CHECK constraint(H1/H2/M3/L3)
- 025: mcp_calls + ai_call_budgets + 10 種子預算(含 ollama_secondary)
- 026: ai_insights.embedding_signature + pgcrypto + CONCURRENTLY index

A11 critic 三輪審查記錄完整保留:
- Phase 1 schema review: 2 BLOCKER + 4 HIGH + 6 MEDIUM 全處理
- Phase 1 final sign-off: 0 BLOCKER + 2 HIGH + 4 MEDIUM
- Phase 6 ADR review: 5 BLOCKER + 6 HIGH 全修

Operation Ollama-First v5.0 / Phase 0+1+6 護欄

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 23:04:42 +08:00

405 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 6 Critic Sign-off — Operation Ollama-First v5.0
> **Date**: 2026-05-03
> **Reviewer**: critic-A11Phase 6 文件層收尾,第三輪)
> **Scope**: ADR-028 / ADR-029 / ADR-027 附錄 / docs/adr/README.md
> **基準**: 憲法紅線一(事實驅動,狙擊手精神)
> **任務契約**: 驗證每個具體數字、檔案行號、聲稱的決策都有 Phase 0/1/2/3 報告佐證
---
## Verdict
- [ ] APPROVED — Phase 6 ADR 可 commit
- [ ] APPROVED WITH NOTES — 統帥確認 NOTE 後 commit
- [x] **CONDITIONAL** — 修以下 BLOCKER 後 commitHIGH 可同 commit 內順便修
- [ ] REJECTED
**理由**ADR-028 / ADR-029 在「事實層」有 5 個 BLOCKER 級錯誤行號錯、caller 名虛構、provider 白名單與 DB 不一致、OpenClaw 行數錯、減幅算術不自洽)。這兩份文件一旦 commit 會被未來所有 Phase 引用,事實錯誤會成為「憲法級謬誤」傳承。憲法紅線一不容妥協 — 這幾個數字必須改正後再 merge。
ADR-027 附錄與 README 索引部分基本正確,但附錄 A 引用「寫死 IP 已全面消除」用詞過強aider_heal_executor.py:62 仍有 fallback 字面 IP降為 HIGH。
---
## 事實核驗(逐項)
### A. 程式碼行數
| 聲稱 | ADR 寫 | wc -l 實測 | 差距 | 判定 |
|---|---|---|---|---|
| `services/openclaw_strategist_service.py` | **1831 行**ADR-029:18, 113| **2677 行** | **+846+46%** | 🔴 BLOCKER |
| `services/hermes_analyst_service.py` | **573 行**ADR-029:19| **607 行** | +34+5.9% | 🟠 HIGH |
| 比率 | 4.4× | 4.41× | 湊巧仍對 | ✅ |
| 預估 A10 後 | 1300 行 | — | 但是基準錯,目標 1300 行也失準 | 🔴 連帶 |
**證據**
```
$ wc -l services/openclaw_strategist_service.py services/hermes_analyst_service.py
2677 services/openclaw_strategist_service.py
607 services/hermes_analyst_service.py
```
ADR-029 的 1831 / 573 是直接抄 phase0 audit也錯而非實際數行。狙擊手精神失守。
### B. 場景 file:line 行號
| 場景 | ADR-028 寫 | 實測 | 判定 |
|---|---|---|---|
| #1 MCP L1 Grounding | `mcp_collector_service.py:163-167` | 163-167 是 `for tools in (...)` Gemini 設定區塊 | ✅ 對得上 |
| #2 MCP L2 Grounding | `mcp_collector_service.py:185-186` | 185-186 是 except 塊內的 1.5-flash 重試 | ✅ 對得上 |
| #3 PPT generator | `routes/openclaw_bot_routes.py:2464-2477` | 2469 是 `_call_gemini` def | ✅ 對得上 |
| #4 openclaw_weekly | `services/openclaw_strategist_service.py:759` | **實際在 1340** | 🔴 BLOCKER |
| #4 openclaw_monthly | `services/openclaw_strategist_service.py:1267` | **實際在 1771** | 🔴 BLOCKER |
| #4 openclaw_annual | 「戰略月年報」(無 file:line+ caller 名 `openclaw_annual` | **caller 與 function 都不存在**grep 0 hits| 🔴 BLOCKER虛構 |
| #5 code_review_openclaw | `services/code_review_pipeline_service.py:278-286` | 278-286 是 system/user prompt 字串;實際 `_call_gemini` 在 309 | 🟠 HIGH行號偏移 |
| #6 ea_hitl_prefetch | `services/elephant_alpha_orchestrator.py`(無行號)+ caller 名 `ea_hitl_prefetch` | **caller 不存在**grep 0 hits | 🔴 BLOCKER虛構 caller |
| #7 openclaw_qa_complex_sku | `services/openclaw_strategist_service.py:56` | line 56 是 feature flag 註解caller `openclaw_qa_complex_sku` 不存在grep 0 hits | 🔴 BLOCKER虛構 caller + 行號錯) |
證據:
```
$ grep -rn "ea_hitl_prefetch\|openclaw_qa_complex\|openclaw_annual" services/ routes/
0 hits
```
ADR-028 的「鎖定 Gemini 7 個場景」表格把 7 個 caller 名直接寫入 ADR但其中 3 個(#4 annual / #6 EA HITL / #7 complex SKU**caller 名是憑空編出來的**,至今程式碼從未 emit 這些 caller。等同 ADR 治理規則指向「不存在的東西」。
### C. Provider 白名單一致性
| 來源 | provider 列表 | 數量 |
|---|---|---|
| ADR-028:104-114「Provider 白名單」表格 | `gcp_ollama` / `ollama_secondary` / `ollama_111` / `gemini` / `nim` / `nim_via_elephant` / `openrouter` | 7**不含 claude含 ollama_secondary**|
| ADR-028:114「移除原計畫的 claude provider」聲明 | 7不含 claude | 7 |
| ADR-028:208 Verification V1 期望輸出 | 7不含 claude | 7 |
| 實際 `migrations/024:92-94` `chk_ai_calls_provider` | `gcp_ollama` / `ollama_secondary` / `ollama_111` / `gemini` / `claude` / `nim` / `openrouter` / `nim_via_elephant` | **8含 claude** |
| `services/token_report_service.py:42-50` `_PROVIDER_DISPLAY` | `gcp_ollama` / `ollama_111` / `gemini` / `claude` / `nim` / `openrouter` / `nim_via_elephant` | 7**含 claude不含 ollama_secondary**|
| `migrations/025` budget 種子 monthly 列表 | 7`claude` 但缺 `ollama_secondary` | 7 |
**三處不一致**
1. ADR-028 表格寫含 `ollama_secondary` 不含 `claude`
2. DB CHECK 兩個都包含
3. token_report `_PROVIDER_DISPLAY` 與 budget 種子兩個都缺 `ollama_secondary`,含 `claude`
判定:🔴 BLOCKER。ADR-028 的 Verification V1「期望輸出」實際跑會驗證失敗會多出 `claude`、缺 `ollama_secondary`...都不是 — 8 個對照 7 個直接 mismatch`phase1_final_critic_signoff_20260503.md:26` 也記成「7 個 provider 與 _PROVIDER_DISPLAY 完全一致」— 這是上一輪 critic 的盲區,現在被 ADR-028 沿襲。
### D. OpenClaw / Hermes Token 流量估算
ADR-029 line 23-25 與 line 91-94 的算術:
- 戰前 Gemini ~50M tokens/月、Hermes ~30M tokens/月
- 任務 3/4/5 遷移省 ~12M tokens
- 任務 11 降頻省 ~3M tokens
- 戰後 Gemini ~38M tokens/月line 112
- 減幅 -23%line 112
**算術不自洽**
- 50M (12M + 3M) = **35M**(非 38M
- 50→38 = **-24%**(非 -23%
- 50→35 = **-30%**
三個數字(戰後 38、節省 15、減幅 23至少有一個錯三個都互不對齊。
判定:🔴 BLOCKER。憲法級文件出現自相矛盾的關鍵 KPI 數字。
ADR 第 119 行已誠實標示「上述為 Phase 0 audit 推算Phase 5 報表上線後以 ai_calls 實測值修訂」— 動機可諒解(沒實測),但即便是估算,三個推算值也必須互相對得上。
### E. Meta 自審 6h → 12:00
| 聲稱 | 實際 | 判定 |
|---|---|---|
| `run_scheduler.py:99` 改為每日 12:00 | line 99 `schedule.every().day.at("12:00").do(run_openclaw_meta_analysis_task)` | ✅ 已落地 |
| 月省 ~3M Gemini tokensADR-029:93| `run_scheduler.py:97` 註解寫「~1.875M」 | 🟡 LOW兩處數字不對齊但量級接近 |
| 對應 task = A10 / Phase 7-8ADR-029:104| 註解寫 Phase 4 落地 | 🟠 HIGHA10 標籤對應 Phase 與實際提交時 Phase 不一致)|
### F. 寫死 IP 是否「全面消除」
ADR-027 附錄 A 寫「寫死 IP 已全面消除aider_heal_executor.py:48-49 與 code_review_pipeline_service.py:218-225 兩處 N2/N3 修補)」。
實測:
```
$ grep -rn "192.168.0.111" services/ routes/ | grep -v "OLLAMA_HOST_FALLBACK\|test_\|resolve_ollama_host\|#"
services/aider_heal_executor.py:62: return "http://192.168.0.111:11434" ← 仍有
services/hermes_analyst_service.py:7: 模型hermes3:latest @ HERMES_URL預設 192.168.0.111:11434 ← docstring 仍寫
```
`aider_heal_executor.py:62``_default_ollama_api_base()` 的最後 except 兜底line 60-62技術上是「resolve 失敗才回退到字面 111」不是「import-time 寫死」,但「全面消除」的措辭過強。
判定:🟠 HIGH。建議改為「`import-time` 寫死 IP 已全面消除line 48-49 已改為 lazy resolveline 62 保留 except 兜底字面 IP 作為最終防線)」。
### G. 11.8% AIGenerationHistory 覆蓋率
phase0 audit Section 1.4 line 80-81 寫「4/34 ≈ 11.8%」 → ADR-028 line 19 引用一致 ✅。
### H. Phase 1 / 2 / 3 落地狀態
| Phase | ADR 寫 | 實測 | 判定 |
|---|---|---|---|
| Phase 0 | ✅ 完成 | phase0_audit + phase0_research 都存在 | ✅ |
| Phase 1 | 52/52 tests pass | phase1_final_critic_signoff 確認 | ✅ |
| Phase 2 | 13+43=56 tests pass | phase2_deploy_verify 確認 | ✅ |
| Phase 3 A7 | 已完成feature flag| `OPENCLAW_QA_OLLAMA_FIRST` env 在 openclaw_strategist_service.py:51, 61, 162-163, 259 出現,預設 false | ✅ |
| migration 024/025/026 | 存在 | `migrations/024_create_ai_calls_table.sql` / `025_create_mcp_calls_and_budgets.sql` / `026_add_embedding_signature.sql` | ✅ |
| Meta 12:00 | run_scheduler.py:99 | 確認 | ✅ |
---
## Findings
### BLOCKER事實錯誤必須改
#### B1. ADR-029 OpenClaw 行數錯 846 行(+46%
- **位置**`docs/adr/ADR-029-hermes-first-twin-tower.md:18, 113`
- **錯誤**:寫 `services/openclaw_strategist_service.py ≈ 1831 行`
- **實測**`wc -l = 2677 行`
- **影響**
- line 18 的「失衡證據」(戰前 1831失真但比率 4.4× 湊巧仍接近真實 4.41×(仍在 4× 量級)
- line 113 的「預估 1300 行A10 後)」基準錯誤 → 戰後行數要 -29% 應是 ~1900 行才合理;若仍要砍到 1300是 -51%(戰前 2677 → 1300是更激進的目標但 ADR 沒揭露
- 量化效益表的 OpenClaw 程式碼瘦身欄位失準
- **建議修法**
- 把 1831 改 2677
- 重算「-29% 後 ~1900 行」或「若仍鎖定 1300 行則應改寫為 -51%(更大重構工程)」
- line 142 的「OpenClaw 從 1831 行降至 ~1300 行A10」同步修
#### B2. ADR-028 場景 #4 行號錯759/1267 vs 1340/1771
- **位置**`docs/adr/ADR-028-llm-routing-unified-principles.md:75`
- **錯誤**「openclaw_weekly / openclaw_monthly / openclaw_annual」location 寫 `services/openclaw_strategist_service.py:759, 1267, 戰略月年報`
- **實測**
- `caller="openclaw_weekly"` 在 line 1340
- `caller="openclaw_monthly"` 在 line 1771
- `caller="openclaw_annual"` **0 hits**(不存在)
- **影響**:未來新工程師看 ADR 找 759 line 會找到 `_legacy_gemini_first_qa` 內部,誤判 caller 對應位置annual report 根本沒實作但 ADR 列為「鎖定場景」
- **建議修法**
- 759 → 13401267 → 1771
- `openclaw_annual` 從鎖定場景表移除(或改為「待實作」並引述 Phase X 計畫)
#### B3. ADR-028 場景 #6 / #7 caller 名虛構
- **位置**`docs/adr/ADR-028-llm-routing-unified-principles.md:77-78`
- **錯誤**
- 場景 #6 caller `ea_hitl_prefetch` — grep 0 hits程式碼從未 emit 此 caller
- 場景 #7 caller `openclaw_qa_complex_sku` — grep 0 hits同上
- **實測**
```
$ grep -rn "ea_hitl_prefetch\|openclaw_qa_complex" services/ routes/
(無輸出)
```
- **影響**ADR 把治理規則繫於不存在的 callerDB token report `WHERE caller='ea_hitl_prefetch'` 永遠 0 筆Phase 5 預算告警會誤判
- **建議修法**
- 若是「規劃中」,標示 `(規劃中Phase X 引入)`
- 若是「已存在但 caller 名不同」,改為實際 caller例如 EA HITL 預跑可能走 `hermes_intent` / `hermes_analyst`
- line 78 的 `services/openclaw_strategist_service.py:56` 不是 caller 而是 feature flag 註解,行號需重指
#### B4. ADR-028 Provider 白名單與 DB CHECK 不一致
- **位置**
- `docs/adr/ADR-028-llm-routing-unified-principles.md:104-114`(白名單表)
- `docs/adr/ADR-028-llm-routing-unified-principles.md:114`(移除 claude 聲明)
- `docs/adr/ADR-028-llm-routing-unified-principles.md:208`V1 期望輸出)
- **錯誤**ADR 寫 7 個 provider含 ollama_secondary不含 claude
- **實測**
- `migrations/024_create_ai_calls_table.sql:92-94` 是 **8 個**(含 claude 與 ollama_secondary
- `services/token_report_service.py:42-50` `_PROVIDER_DISPLAY` 是 7 個(**含 claude不含 ollama_secondary**
- `migrations/025` 預算種子 monthly 是 7 個(含 claude缺 ollama_secondary
- **影響**
- Verification V1 SQL 跑出來會與「期望」對不上 → 部署驗證會誤判 FAIL
- 「移除 claude」是空話 — DB 並未移除
- `ollama_secondary` 在 DB 接受但無任何程式碼會 emit → SELECT 永遠 0 筆 → Phase 5 三主機級聯可觀測性失真
- **建議修法**(三選一):
- 路線 AADR-028 改為「8 provider含 claude新增程式碼 emit `ollama_secondary` 標籤patch `code_review_pipeline_service.py:230` 與其他 Ollama caller根據 resolve 結果動態決定)
- 路線 B實際下一個 migration 移除 claude並在 _PROVIDER_DISPLAY 加 ollama_secondary讓三層真正一致
- 路線 CADR-028 加一段「Schema vs ADR 差異」誠實揭露Phase X 統一
#### B5. ADR-029 Token 流量算術不自洽38M vs 35M vs -23%
- **位置**`docs/adr/ADR-029-hermes-first-twin-tower.md:23-25, 91-94, 112`
- **錯誤**
- 戰前 50M → 任務 3/4/5 省 12M、任務 11 省 3M = 共省 15M → 戰後應 35M
- 但 line 112 寫戰後 38M、減幅 -23%
- 50→38 = -24%(非 -23%50→35 = -30%
- **影響**:戰役 v5.0 KPI「Gemini 月支出 -23%」是 README 索引line 53的明牌數字之間互不對齊讓未來無法驗收
- **建議修法**
- 三個數字選一個錨定,其他重算:
- 錨定 -23% → 戰後 38.5M → 節省 11.5Mtask 3/4/5/11 拆分需重估)
- 錨定節省 15M → 戰後 35M → 減幅 -30%README 索引也要改)
- 或加註腳「戰後 token 估算為四捨五入區間,實測誤差 ±5M」誠實揭露不確定性
### HIGH建議改不一定阻 commit
#### H1. Hermes 行數差 +5.9%
- 位置ADR-029:19
- 寫 573 vs 實測 607
- 改為「607 行」即可
#### H2. ADR-027 附錄 A「寫死 IP 全面消除」措辭過強
- 位置ADR-027 附錄 A 段尾
- 實際 `aider_heal_executor.py:62` 仍有字面 `return "http://192.168.0.111:11434"`(在 except 兜底)
- 建議改為「import-time 寫死已消除except 兜底保留 111 字面 IP 作為最終防線」
#### H3. ADR-028 場景 #5 行號偏移
- 位置ADR-028:76
- 寫 `code_review_pipeline_service.py:278-286`,實際 278-286 是 prompt 字串;`_call_gemini` 在 line 309
- 建議改 `:278-310`(涵蓋整個 Gemini 呼叫塊)或 `:309`
#### H4. ADR-028 caller 白名單列了 30+ 個但實際 emit 僅 ~16 個
- 位置ADR-028:122-138
- 實際 `grep "caller=" services/ routes/` 唯一 16 個(已驗證上方)
- 列表混雜了「已實作」與「規劃中」沒區分標示
- 建議:在每個 caller 後標示 `[A4 已落地]` / `[Phase X 規劃中]`
#### H5. `ollama_secondary` provider 沒有任何 caller emit
- 位置ADR-028:107白名單條目
- 程式碼層 0 hits — 三主機級聯實作只區分 GCPgcp_ollamavs 111ollama_111Primary/Secondary 在程式中不區分
- 建議:要嘛在 `services/ollama_service.resolve_ollama_host()` 與所有 caller 加上「根據 selected host 決定 provider tag」要嘛把 `ollama_secondary` 從白名單移除直到實作完成
#### H6. ADR-029 Phase 標籤錯亂
- 位置ADR-029:104
- 寫「A10 對應 Phase 7-8」
- run_scheduler.py:97 註解寫「Phase 4 降頻」
- ADR-028 Migration Plan line 248 也寫「Phase 7-8 OpenClaw 程式瘦身A10
- 不一致;建議在文件層統一定義 A10 的 Phase 對應
### MEDIUM
#### M1. ADR-029 第 5 行作者列「Codex / A12 planner」但戰役組織圖中 A12 是 critic不是 planner
- 位置ADR-029:6 / ADR-028:6
- planner 角色是 A8從上下文推斷但 ADR 寫 A12
- 不影響事實,但角色標籤需與 v5.0 戰役組織圖核對
#### M2. ADR-028 line 156 「Gemini 2.5 Flash vs qwen3:14b 估差 10-20%」引用 phase0_research_report Section 1但 phase0 報告 Section 1 結論是「黃燈,需 50 題黃金集 A/B 才能定論」,沒給出 10-20% 的硬數字
- 位置ADR-028:156
- phase0_research line 30-33 寫「推估 10-20%」是未驗證的推估ADR 直接當事實引用
- 建議改為「**推估** 10-20%(待 Phase 4 黃金集 A/B 確認)」
#### M3. ADR-027 附錄 A 引用「services/code_review_pipeline_service.py:218-225」但實際 218-225 是 prompt 字串
- 位置ADR-027 line 65
- 實際 `_call_gemini` 與 hermes scan 在 line 230 後
- 行號偏移phase0 audit 也錯(同樣的 inheritance 錯誤)
### LOW
#### L1. ADR-028:75 寫「`戰略月年報`」中文字摻在 file:line 列,破壞表格格式
- 位置ADR-028:75
- 應改為「(戰略月/年報function 待實作)」或拆兩行
#### L2. ADR-028 Migration Plan 列了 Phase 0-12 但 Phase 11 / 12 與其他 ADR如 ADR-026 收尾路線圖)的 Phase 編號可能重疊
- 跨 ADR 的 Phase 編號需要統一索引避免混淆
- 不阻 commit
#### L3. ADR-029 line 4 沒有 Author 欄位ADR-028 有)
- 風格不一致
---
## ADR 引用一致性
| ADR-028 / 029 引用 | 實際內容 | 判定 |
|---|---|---|
| ADR-002 pgvector 唯一向量庫 | 確實存在未被破壞memory-mcp 在 phase0 也標 🔴 不採用)| ✅ |
| ADR-003 Hermes embedding 本地化 | 存在 | ✅ |
| ADR-004 NemoTron fallback chain | 存在ADR-028 引「NIM 80 calls/day」與 ADR-004 一致 | ✅ |
| ADR-008 部署實機驗證 | 存在 | ✅ |
| ADR-013 AIOps AutoHeal | 存在 | ✅ |
| ADR-018 四 Agent 控制面 | 存在ADR-029 「ADR-018 已定四 Agent 角色,但未量化誰處理高頻」描述準確 | ✅ |
| ADR-019 Telegram Agentic Layer | 存在ADR-029 line 30 描述「openclaw_decide() 把所有用戶輸入導向」與 ADR-019 一致 | ✅ |
| ADR-021 EA HITL pre-fetch | 存在;但 ADR-028 場景 #6 caller 名與 ADR-021 內 Hermes 預跑實作不對應B3| 🔴 連帶 |
| ADR-027 「Supersedes: 無(補述 ADR-027非取代」 | 措辭合理,因 ADR-027 仍存在且新增了附錄 | ✅ |
| `migrations/024:88-91` provider CHECK | 實際 line 92-94包含 8 個 provider含 claude| 🔴 B4 |
| `migrations/024:104-109` meta/error 大小 | 已驗證(與 phase1 critic H2 一致)| ✅ |
| phase0_audit Section 1.4 11.8% | 一致 | ✅ |
| phase1_final_critic_signoff H5/H6 | 一致 | ✅ |
---
## 鎖定 Gemini 7 場景驗證LOCKED-GEMINI 註解 vs ADR-028
| # | LOCKED-GEMINI 程式碼註解 | ADR-028 場景 | 一致? |
|---|---|---|---|
| #1 | `services/mcp_collector_service.py:32` LOCKED-GEMINI: MCP 即時情報需 Google Search Grounding | 場景 #1 MCP L1 Grounding | ✅ |
| #2 | (無獨立註解,與 #1 同)| 場景 #2 MCP L2 Grounding | ✅(共享)|
| #3 | `routes/openclaw_bot_routes.py:98` LOCKED-GEMINI: PPT 簡報文案需長 context + 繁中商業敘事 | 場景 #3 PPT generator | ✅ |
| #4 | `services/openclaw_strategist_service.py:40` LOCKED-GEMINI: 週/月/年報需長 context + 繁中商業文體 | 場景 #4 weekly/monthly/annual | 🟠annual caller 不存在 — B3|
| #5 | `services/code_review_pipeline_service.py:46` LOCKED-GEMINI: Code Review 全 repo diff 可達 100K+ tokens | 場景 #5 code_review_openclaw | ✅ |
| #6 | `services/elephant_alpha_orchestrator.py:88` LOCKED-GEMINI: EA HITL 戰略決策影響統帥行動 | 場景 #6 ea_hitl_prefetch | 🟠caller 名與註解中的 "AgentCapability" 模型 `gemini-2.0-flash` 對不上 ADR 寫的 `gemini-2.5-flash`|
| #7 | (無獨立註解)| 場景 #7 openclaw_qa_complex_sku | 🔴caller 完全不存在 — B3|
**註解 vs ADR 模型不一致**
- ADR-028 場景 #6 寫 `gemini-2.5-flash`
- `services/elephant_alpha_orchestrator.py:91` AgentCapability 寫 `model="gemini-2.0-flash"`
- 哪個是真的?需校對
---
## 與既有 ADR 衝突grep 結果)
```
$ grep -rn "ADR-028\|ADR-029" docs/adr/
(除 ADR-027 / 028 / 029 / README 自身互引以外,其他 ADR-001~026 均無提及)
```
✅ 既有 ADR 沒有提到 028/029所以沒有外部引用衝突。
✅ ADR-002pgvector 唯一phase0 audit Section 2 已標 memory-mcp 🔴 不採用ADR-028 沒破壞此決策。
✅ ADR-018四 Agent 控制面ADR-029 是「補述」而非取代,措辭合理。
✅ ADR-027附錄正式承接Supersedes 標示「無(補述)」措辭正確。
---
## 核准條件CONDITIONAL → APPROVED 的必修清單)
- [ ] **B1 修**ADR-029 line 18, 113, 142 把 `1831` 改 `2677`A10 預估目標重算(建議 -29% → 1900 或維持 1300 但重標 -51%
- [ ] **B2 修**ADR-028 line 75 行號 759 → 1340、1267 → 1771
- [ ] **B3 修**ADR-028 場景 #4 移除 annual或標「規劃中」場景 #6 改用實際存在的 caller 名(如 `hermes_analyst` 或備註「Phase X 引入」);場景 #7 同
- [ ] **B4 修**ADR-028 Provider 白名單表格與 V1 期望輸出與 DB CHECK / token_report `_PROVIDER_DISPLAY` 對齊(含 claude、處理 ollama_secondary 缺口)
- [ ] **B5 修**ADR-029 line 23-25, 112 三個數字(戰前 50M / 戰後 38M / 減幅 -23% / 任務節省 12M+3M對齊建議錨定 README 索引「-23%」並回算其他兩個
修這 5 個 BLOCKER 後可 commit。HIGH 可同 commit 內順便修,不修也不阻 commit但會留入 Phase 7+ 技術債)。
---
## Sign-off
```
critic-A11 / 2026-05-03 / Phase 6 / 第三輪審查
Verdict: CONDITIONAL5 BLOCKER 待修)
Files Reviewed:
docs/adr/ADR-028-llm-routing-unified-principles.md (269 lines)
docs/adr/ADR-029-hermes-first-twin-tower.md (222 lines)
docs/adr/ADR-027-primary-ollama-on-gcp.md (114 lines, 含附錄)
docs/adr/README.md (60 lines)
Cross-checked Against:
docs/phase0_audit_report_20260503.md (262 lines)
docs/phase0_research_report_20260503.md (231 lines)
docs/phase1_db_design_20260503.md (315 lines)
docs/phase1_final_critic_signoff_20260503.md (317 lines)
docs/phase2_deploy_verify_20260503.md (205 lines)
migrations/024_create_ai_calls_table.sql
migrations/025_create_mcp_calls_and_budgets.sql
services/openclaw_strategist_service.py (2677 lines, wc -l)
services/hermes_analyst_service.py (607 lines, wc -l)
services/ollama_service.py (resolve_ollama_host + mark_unhealthy)
services/ai_call_logger.py
services/token_report_service.py (_PROVIDER_DISPLAY)
services/code_review_pipeline_service.py (LOCKED-GEMINI / provider tag)
services/mcp_collector_service.py (LOCKED-GEMINI)
services/elephant_alpha_orchestrator.py (LOCKED-GEMINI)
services/aider_heal_executor.py (lazy resolve / 兜底字面 IP)
routes/openclaw_bot_routes.py (LOCKED-GEMINI / caller emit / PPT _call_gemini)
run_scheduler.py:99 (Meta 12:00)
Discipline: 憲法紅線一(事實驅動 / 狙擊手精神)— 嚴格批評;
不修補 ADR僅標 BLOCKER / HIGH / MEDIUM / LOW
所有 finding 附 file:line 並對照 phase 報告。
```