5d00e71275
頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定, Gitea private=除機敏值/build 產物/.github 外全 push。 解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。 機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
101 lines
7.9 KiB
Markdown
101 lines
7.9 KiB
Markdown
# HANDOFF: arcrun config 寫入端 + 讓 AI 看懂 scope + KBDB Vectorize 開關
|
||
|
||
> 來源:InkStoneCo 頂層總管,2026-06-15。mira self-hosted dogfood 踩出的兩條框架缺口。
|
||
> 兩條都是 `change`,走 SDD 協議(先讀對應 SDD、宣告、改 tasks.md)。
|
||
> 觸發實證:mira(一個 AI)被交代遷移時**沒看懂 scope 存在**,差點誤部官方帳號。
|
||
|
||
---
|
||
|
||
## 缺口 1:config 讀分層完整、寫只能全域 + AI 看不懂 scope
|
||
|
||
### C.1 補 `acr init` 專案層寫入端
|
||
|
||
`cli/src/lib/config.ts` 讀取分層完整(`findProjectConfig()` env > 專案層 > 全域,8/8 測試),但**寫入只有 `saveConfig()`(config.ts:208)寫死全域** `~/.arcrun/config.yaml`(config.ts:38)。`acr init` 4 處呼叫(init.ts:93/142/278)全寫全域。
|
||
- → `acr init` 無法寫專案層。leo 意圖 project scope 卻被迫污染全域 → 怕誤打官方 uncle6me。
|
||
|
||
**修法**:
|
||
- `saveConfig()` 加 scope 參數(`'global' | 'project'`);project 寫 `./.arcrun.yaml`(`process.cwd()`)。
|
||
- `acr init` / `acr config set` 加 `--project` flag。
|
||
- 預設是否翻轉(init 預設寫專案層)由 richblack 定(影響既有使用者)。
|
||
- 參考既有範式:`mcp-setup.ts` §7.8 已有 project scope 寫 `.mcp.json` 概念,比照。
|
||
|
||
### C.2 ★ 改 `cli/harness/CLAUDE.block.md` 讓操作 AI 看懂 scope(最重要)
|
||
|
||
**病根**:arcrun 是 AI 操作的工具(mindset §2),但 harness block(全文 41 行)對 scope / 帳號歸屬 / 誤部風險 **0 字提及**。AI 讀完完全不知道有 scope 這層 → mira 把「資料遷移」跟「在哪 scope 部署」混為一談。
|
||
|
||
在 harness block 加「部署落點與帳號安全」段:
|
||
1. **scope 模型**:分層 `env > 專案層 .arcrun.yaml > 全域 ~/.arcrun/config.yaml`。**部到哪個 CF 帳號取決於當前資料夾解析到哪份設定**。動手前先 `acr config --where`。
|
||
2. **多帳號警示**:同機可能多個 CF 帳號(dogfood / prod);`.env` 可能並存多組 `CLOUDFLARE_*`(含 `*_UNCLE6` 後綴)。部署/遷移前必須明確目標 account_id,挑錯=打到正式環境(不可逆)。
|
||
3. **遷移 ≠ scope**:搬資料(A 帳號→B 帳號)和「我用哪個帳號」是兩件獨立的事。
|
||
4. **fallback 陷阱**:任一層都沒 `mode` → `acr` 靜默當 `local`(config.ts:176),不報錯。看到「成功」但無雲端 trace 先查 `acr config --where`。
|
||
5. **無設定就停手**:`--where` 顯示無設定 / fallback local 而意圖 self-hosted → 停下問人。
|
||
|
||
> harness block 是 AI 的 mindset 入口,比 CLI `--help` 重要(AI 偏好讀 harness)。scope 安全屬「動手前世界觀」,必在這層。
|
||
|
||
**對應 SDD**:`docs/3-specs/arcrun/sdk-and-website/config-layering.md`。
|
||
|
||
---
|
||
|
||
## 缺口 2(任務 D):KBDB Vectorize(embed)無環境開關
|
||
|
||
### 病根
|
||
|
||
KBDB 分 `base`(D1 only,免費)+ `embed` module(Vectorize+AI binding,語意搜尋)。但 `acr init/update` 完全沒處理 embed(grep `vectorize|embed` 在 `cli/src/` = 0 命中);只活在 `kbdb/src/index.ts:5` 註解。→ **沒有 config 欄位 / 指令讓使用者或 AI 表達「要不要開 Vectorize」**。
|
||
|
||
### 設計哲學(leo 2026-06-15):降級要優雅,但「完整體驗」要有門
|
||
|
||
> 「最好是我自己這套可以語義搜尋;不開就降級;**但想完整體驗卻沒有門**。」
|
||
|
||
- **預設降級且能跑**:沒開 embed → base 仍可關鍵字搜尋(不是壞掉)。
|
||
- **降級要明示不能無聲**:跑 base 時要讓人知道「語意搜尋未開」。無聲降級=用戶以為這就是全部=bug。
|
||
- **★ 升級要有門**:config 欄位 + `acr` 提示「想語意搜尋?這樣開」。現在連「有更完整版本可選」都不可見。
|
||
|
||
### 修法(config 欄位 + 部署條件注入,比照 MULTI_TENANT)
|
||
|
||
1. **config 加欄位**:`ArcrunConfig`(config.ts:11)加 `kbdb_embed?: boolean`(預設 false=base 免費)。leo dogfood 設 true。
|
||
2. **部署條件注入**:`acr update` 部 KBDB worker 時 `kbdb_embed: true` → 注入 Vectorize+AI binding + 部 embed module;false 只部 base。比照 `deploy.ts:395` MULTI_TENANT 注入、`deploy.ts:380` WORKER_SUBDOMAIN 注入。
|
||
3. **降級可見**:`acr config --where` / 部署摘要顯示「KBDB: base(語意搜尋未開)」或「embed(Vectorize 啟用)」;base 時提示升級門。
|
||
4. **AI 認知**:harness block(C.2 那段)一併說「KBDB 預設 base(D1 免費僅關鍵字);語意搜尋需 `kbdb_embed: true`(Vectorize 計費)。功能需語意搜尋但這套是 base → 別假裝有,明示降級指出升級門」。呼應 mindset §7 誠實。
|
||
|
||
**對應 SDD**:KBDB 模組化屬 `docs/3-specs/` kbdb spec;部署注入屬 `sdk-and-website/self-hosted-init.md`。
|
||
|
||
---
|
||
|
||
## 任務 E(★ 急,擋 mira 14-E load):給 mira「leo21c kbdb worker 實際綁的 D1 id」
|
||
|
||
> 總管裁定(2026-06-15):mira 14-E load 撞 Workers 每日 10萬 request 牆(逐筆 API 病根)→ 改走 `wrangler d1 import`(資料層搬遷=用戶 CF 權限,繞 API)。**但 mira 需要 D1 id 才能灌對庫。**
|
||
|
||
**為什麼 mira 自己查不到**:
|
||
- cypher-executor **無** D1 binding,轉發給 **kbdb worker**。
|
||
- kbdb worker 的 D1 id 是 **deploy.ts 部署時動態注入**(`kbdb/wrangler.toml` 靜態值 `0c580910…` 是官方 prod,self-hosted 部署會覆蓋)。
|
||
- → leo21c 上 kbdb worker 實際綁的 D1 id ≠ mira `wrangler` 直連的 `arcrun-kbdb`(`1099d0f3…`)。這是「wrangler 查 0 筆、cypher 有 11 萬筆」的真相(兩個同名不同 id 的 D1)。
|
||
|
||
**你要做**:用 leo21c CF token 查 leo21c 上 **kbdb worker 部署時實際注入的 D1 database_id**(看 deploy.ts 注入邏輯 / 查 leo21c worker runtime binding),告訴 mira。mira 拿到才能 `wrangler d1 import <該 id>` 灌對庫。
|
||
|
||
## 任務 F(B,框架缺口,非急):cypher `/kbdb/entries` 補批次端點
|
||
|
||
> 總管裁定 B:應用層大批寫入該有批次 API。**未來每個 self-hosted 用戶大批匯入都撞 10萬 request 牆**(不只 mira)——逐筆 POST 每筆 1 request,~5萬筆燒光免費 worker 當日配額。
|
||
|
||
- `POST /kbdb/entries` 收陣列(`[{...},{...}]` 或 `{entries:[...]}`),1 request 寫 N 筆 → 45.8萬筆只要 ~900 requests。
|
||
- 守鐵律(只轉發 API、不開 SQL/建表;owner_id 仍自動注入每筆)。
|
||
- 對應 SDD:kbdb-proxy 屬既有範圍。
|
||
|
||
## 任務 G(雜項,mira 14-E 踩出的 cypher 框架特性,記著)
|
||
|
||
mira load 踩出,記給框架修(非急):
|
||
1. CF WAF 1010:Python urllib 預設 UA 被擋 → 文件提醒帶 UA。
|
||
2. 重複 id → 500(非 409):UNIQUE 衝突宜回 409 友善處理。
|
||
3. 零星單筆 500:某些 block 穩定 500、同 content 換 id 卻 200=邊緣 bug(疑 metadata_json/refs_json 某字元觸發,未定位)。
|
||
4. `?id=` query 被忽略(回前 100 筆不過濾);查單筆只能 `/entries/:id` 路徑——文件宜明示。
|
||
5. **DELETE `/kbdb/entries/:id` route 缺**(OPTIONS 卻宣告支援 DELETE,CORS 宣告與實作不一致)。
|
||
6. cypher 綁的 D1 與同名 `arcrun-kbdb` database_id 不一致(見任務 E)——self-hosted 文件宜說明「wrangler 直連 ≠ cypher 綁的庫」。
|
||
|
||
## 共通教訓
|
||
|
||
任務 C、D 同類:**把「該是環境設定的選擇」從 code 註解提升到 AI/使用者可表達的層級**。arcrun 是 AI 操作的工具,凡影響「部到哪、開什麼功能」的選擇都必須在 config + harness 可見,不能只活在實作裡。
|
||
任務 E/F 同類:**資料層搬遷(用戶 CF 權限 d1 import)vs 應用層大批寫入(cypher 批次 API)是不同層級,都該存在**——逐筆 API 推大批資料是把「資料遷移」做成「應用層寫入」,撞 worker 請求上限。
|
||
|
||
## 依賴
|
||
|
||
mira 側(建專案層 .arcrun.yaml + 移全域)先行,見 mira repo `docs/HANDOFF-arcrun-config-project-scope.md`。本框架補強讓「未來不再污染全域 / AI 不再看不懂 scope」,是根治,非阻擋 mira 當前解耦。
|