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>
22 KiB
Phase 6 Critic Sign-off — Operation Ollama-First v5.0
Date: 2026-05-03 Reviewer: critic-A11(Phase 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
- CONDITIONAL — 修以下 BLOCKER 後 commit;HIGH 可同 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 |
三處不一致:
- ADR-028 表格寫含
ollama_secondary不含claude - DB CHECK 兩個都包含
- 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 tokens(ADR-029:93) | run_scheduler.py:97 註解寫「~1.875M」 |
🟡 LOW(兩處數字不對齊但量級接近) |
| 對應 task = A10 / Phase 7-8(ADR-029:104) | 註解寫 Phase 4 落地 | 🟠 HIGH(A10 標籤對應 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 resolve;line 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 1340caller="openclaw_monthly"在 line 1771caller="openclaw_annual"0 hits(不存在)
- 影響:未來新工程師看 ADR 找 759 line 會找到
_legacy_gemini_first_qa內部,誤判 caller 對應位置;annual report 根本沒實作但 ADR 列為「鎖定場景」 - 建議修法:
- 759 → 1340,1267 → 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(同上)
- 場景 #6 caller
- 實測:
$ grep -rn "ea_hitl_prefetch\|openclaw_qa_complex" services/ routes/ (無輸出) - 影響:ADR 把治理規則繫於不存在的 caller;DB 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 三主機級聯可觀測性失真
- 建議修法(三選一):
- 路線 A:ADR-028 改為「8 provider(含 claude)」,新增程式碼 emit
ollama_secondary標籤(patchcode_review_pipeline_service.py:230與其他 Ollama caller,根據 resolve 結果動態決定) - 路線 B:實際下一個 migration 移除 claude,並在 _PROVIDER_DISPLAY 加 ollama_secondary,讓三層真正一致
- 路線 C:ADR-028 加一段「Schema vs ADR 差異」誠實揭露,Phase X 統一
- 路線 A:ADR-028 改為「8 provider(含 claude)」,新增程式碼 emit
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.5M(task 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 — 三主機級聯實作只區分 GCP(gcp_ollama)vs 111(ollama_111),Primary/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:91AgentCapability 寫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-002(pgvector 唯一):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: CONDITIONAL(5 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 報告。