Files
Arcrun/docs/HANDOFF-matrix-rearrange.md
uncle6me-web 5d00e71275 chore: D22 落地——docs/SDD/wiki/CLAUDE.md 進 repo(Gitea private 預設全 push)
頂層 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>
2026-07-03 07:13:33 +08:00

152 lines
14 KiB
Markdown
Raw Permalink 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.
# HANDOFF: Matrix 重整交棒給 arcrun2026-06-13
來源:InkStoneCo 頂層 `.agents/specs/matrix-rearrange/`。本檔是該重整交給 arcrun 的待辦清單。
**指針式考古**:整合素材真身在 InkStoneCo `_archive/`,照路徑去挖,不複製進此檔。
---
## 1. cypher-executor 整合進 arcrun 後**關掉**leo 2026-06-13:整合後只剩 arcrun
`matrix/cypher-executor` 是 diverged 副本,**整合進 arcrun/cypher-executor 後就關掉/封存**,之後 cypher 只有 arcrun 一份。
### 如何整合(勘查 2026-06-13
**A. matrix 版獨有、arcrun 缺的 5 檔 → 補進 arcrun**(皆非 SaaS 遺留,是 self-hosted 核心):
- `src/actions/version-selector.ts`:零件版本選擇策略 floating/stable/pinned
- `src/actions/autoPublishMissing.ts`missing 零件用 Workers AI 自動生成上架
- `src/lib/component-dispatcher.ts`:雙模式路由 wasm/cypher_binding/service_binding
- `src/lib/wasm-executor.ts`WASM 執行
- `src/routes/proxy.ts`proxy 路由
**B. 兩邊都有但內容不同的 10 檔 → 逐檔比對合併**(取較完整/正確的一邊,保留 arcrun 較新的 auth 演進):
`cypher-handlers` / `execution-evaluator` / `execution-logger` / `graph-builder` / `search-nodes` / `triplet-parser` / `webhook-graph-resolver` / `webhook-handlers` / `graph-executor` / `index`
**C. 保留 arcrun 獨有的**(不要被舊版覆蓋):`credential-injector` / `auth-dispatcher` / `auth-recipe-seeds` / `api-recipe-seeds`arcrun 較新的 Auth Recipe 演進)。
**素材真身**`matrix/cypher-executor/`(降級後仍在原地)。整合完成、驗證通過後,**封存 matrix/cypher-executor 進 `_archive/`cypher 之後只有 arcrun 一份**。先讀對應 SDD 再動。
## 2. KBDB 插件化 + 補 CLI/MCP 薄殼(arcrun 端只留基本盤 + 暴露能力)
`arcrun/kbdb` **留 3 表基本盤 + API**(已完整:templates/entries/records/search)。它是刻意設計的基本盤(0001_base.sql 註釋 plugin model),**不升 v3、不加 blocks 表**。triplet/graph 由 `matrix/kbdb-graph-plugin` 抽成獨立 repo KBDB-graph。
**KBDB 鐵律(leo 2026-06-14**:任何人不准動表;新類型=建 template(走 API);插件/AI/人全走 API,禁 SQL;基本盤不提供建表 API。詳見頂層 `DECISION-kbdb-v3-baseplane.md`
**arcrun 端待辦(核實:CLI/MCP 現在完全沒 KBDB 能力)**
- **補 MCP 薄殼**(AI 用,含插件):`kbdb_create_template`(name+slots)、`kbdb_create_record`(填 slot)、`kbdb_query`/`kbdb_search` 等,調基本盤現有 API。**不提供建表 tool,只給 template/slot**——類 Supabase 萬用表,AI 想建表時只有 template/slot 可用。
- **補 CLI 薄殼**(人用,後補):對應命令。
- 能力真身在基本盤 API(已有),CLI/MCP 只薄殼暴露(arcrun 薄殼原則)。
對方交棒見 `matrix/kbdb-graph-plugin/docs/HANDOFF-kbdb-plugin.md`
## 3. leo21c self-hosted 部署(Mira dogfood 用)
leo 用 leo21c CF 帳號部署 self-hosted arcrun`MULTI_TENANT=false`),Mira 改 dogfood 這套。
依現有 `scripts/local-deploy.sh` + `docs/3-specs/arcrun/sdk-and-website/self-hosted-init.md`。namespace 明碼非 api key。
### 3b. ⚠️ MCP self-hosted 認證失敗(mira CC 2026-06-14 回報,跨專案問題)
**一句話**MCP worker 還走舊 partner-key 認證(`mcp/src/middleware/partner-auth.ts`,每個端點都掛 `partnerAuthMiddleware`),但 self-hosted 認證是 namespace 明碼。導致 Claude Code 連 self-hosted MCP 一律 401。**CLI 全通**(走 cypher-executor,已支援 `MULTI_TENANT=false`)。
**根因**MCP 的 `partner-auth.ts` 沒跟上 cypher-executor 的 self-hosted 認證改版。這是 `07-thin-shell.md §4` 已記的「MCP 帳號來源違反」的具體症狀(SDD proposal 已存在:`docs/3-specs/arcrun/sdk-and-website/mcp-account-source.md`)。
**診斷證據(curl `arcrun-mcp.leo21c.workers.dev/mcp`mira CC 實測)**
- GET /mcp → 200worker 活);MCP initialize 無 auth → 401Bearer ak_(舊 uncle6 key)→ 401 Invalid partner keyBearer leonamespace 明碼)→ 401X-Namespace header → 401
- cypher-executor / → 200CLI 走這條,通)
- `acr mcp-setup` 生成的 `.mcp.json` 是裸的(無 headers),就算有 key 也沒地方帶
**修法(三選一,arcrun 端決策)**
1. MCP worker 加 self-hosted 認證:接受 namespace 明碼(與 cypher-executor 一致),或 self-hosted 模式 MCP 免 partner key。
2. `acr mcp-setup` 把有效認證寫進 `.mcp.json` headers(前提:self-hosted 有可用 key 機制)。
3. 對齊完成前,官方文件明說 self-hosted MCP 暫不可用、請用 CLI(避免使用者困惑)。
**影響範圍**:任何 self-hosted dogfoodmira、未來 product)都踩,非 mira 獨有。屬 arcrun 框架側待修,走 SDD 協議(對應 `mcp-account-source.md`,動工前宣告)。
**mira 現況**:全靠 acr CLI 即可推進,不卡。`.mcp.json` 留著等上游修好自動能連。
---
### 3b-2. ⚠️ 第一次端到端實測:修補 code 對,但 `MULTI_TENANT` 沒注入 MCP worker2026-06-14 晚,mira 推 leo21c + 總管核實)
mira 把 release@main 推上 leo21cdeployment 14:31version 7de919d6),**仍 401 `Invalid or expired partner key`**。總管核實了真因(不是 code bug,是部署機制 bug):
-**修補 code 在且正確**`mcp/src/middleware/partner-auth.ts:19` `if (c.env.MULTI_TENANT === 'false')` 確實擋在 partner-key 查詢之前。
- ☠️ **真因:`mcp/wrangler.toml` 的 `MULTI_TENANT = "false"` 是注釋掉的(第 13-14 行 `# [vars]` / `# MULTI_TENANT`**。部署後 worker 的 `c.env.MULTI_TENANT === undefined ≠ 'false'` → if 不成立 → 走 partner-key 查詢 → 401。
- 🔍 **更深層:self-hosted 部署(`acr init`/`acr update`)沒把 `MULTI_TENANT=false` 注入 MCP worker 的 vars**`cli/src/` grep `MULTI_TENANT` 只有 config 定義 + 註釋,**無「部署時注入 worker env」的 code**。對照:cypher-executor 通是因它把 key 當不驗證 opaque(不依賴 MULTI_TENANT);MCP 依賴此 env 才走 namespace 分支,故漏注入就斷。
- 類比:self-hosted-init.md 注入了 `WORKER_SUBDOMAIN`,但**漏注入 `MULTI_TENANT`**(同一類部署注入機制的缺口)。
**修法(arcrun 端,二選一或都做)**
1. `acr init/update` 部署 MCP(及需要的 worker)時,依 config `multi_tenant: false` 注入 `MULTI_TENANT=false` 到 worker vars(與注入 WORKER_SUBDOMAIN 同套機制,self-hosted-init.md)。
2. 短期:文件指引 self-hosted 用戶手動 `wrangler secret put MULTI_TENANT`(或取消 mcp/wrangler.toml 那兩行註釋)——但這違反「用戶零填寫」,①才是正解。
**驗收**leo21c MCP worker 設好 MULTI_TENANT=false 後,`curl -H "Authorization: Bearer leo" .../mcp` initialize → 200(非 401)。
## 4. arcrun-gui 併入 + arcrun.dev 降官網
arcrun-gui 不再獨立,GUI 併入 arcrun repo(用戶下載即有)。arcrun.dev 降級為框架官網,移除 /mira/ 寄居(Mira 搬 mira.uncle6.me)。
## 5. arcrun-mcp → 已整進 arcrun/mcp**直接關掉**leo 2026-06-13
勘查確認(2026-06-13):`arcrun/mcp` 已是真身,**比 matrix/arcrun-mcp 多 `arcrun_recipe.ts` + `arcrun_whoami.ts`,且 matrix/arcrun-mcp 無任何 arcrun/mcp 缺的東西**`Only in arcrun-mcp` 為空)= **已全部整進去**
動作:`matrix/arcrun-mcp` **直接關掉**——封存進 `_archive/` 即可,不遷帳號(舊 repo richblack/arcrun-mcp 留歷史)。無需整合,arcrun/mcp 就是現役。
## 6. KBDB 資料層遷移:3 個框架缺口(mira CC 2026-06-14 回報 + 總管核實,擋 mira 遷移)
mira 實測 leo21c self-hosted KBDB**好消息 entries 表 block-compatible**content/entry_type/parent_id/page_name/refs_json/tags_json/task_status/metadata_json = mira block 模型),河道/wiki/triplet 可直接落 entries,不必改資料模型。但卡 3 個 arcrun 缺口:
**① 主缺口(擋遷移):cypher proxy 漏 `/kbdb/entries`** — 核實屬實。
- `cypher-executor/src/routes/kbdb-proxy.ts` 只實作 `/kbdb/templates` + `/kbdb/records`(注釋自稱含 entries,實際沒有)。基本盤 `arcrun/kbdb``/entries`index.ts:18),proxy 沒轉發。
- 結果 mira 三者湊不齊:直連 kbdb worker /entries=有 block CRUD 但裸開無隔離;cypher /kbdb/*=有認證+owner_id 隔離但無 /entries。
- **修法**:比照 `/kbdb/records` 的 owner_id 注入模式,補 `/kbdb/entries`POST/GET filters/GET :id/PATCH/DELETE)。守鐵律(只轉發 API,不開 SQL/建表)。補好 mira `_kbdb_client.py` 改走 `cypher.leo21c/kbdb/entries` + X-Arcrun-API-Key namespace 隔離 → 完成解耦。
**② MCP 的 KBDB service binding 壞** — 核實屬實。
- mcp/wrangler.toml 有 `{ binding="KBDB", service="arcrun-kbdb" }`kbdb-client 用 `env.KBDB.fetch`,但 mira 報 `Cannot read properties of undefined (reading 'fetch')` = **`env.KBDB` undefined**self-hosted 部署時 binding 沒正確建/worker 名對不上 leo21c 的 kbdb)。
- 連帶:官方回報管道 `arcrun_report_feedback`(MCP tool)也因此送不出 → 這份回報只能靠總管轉。**修這個才恢復 self-hosted 的 MCP 回報能力。**
- **修法**self-hosted 部署確保 KBDB service binding 正確指向 leo21c kbdb worker(或改 HTTP fetch via KBDB_BASE_URL,與插件同模式,避免 self-hosted service binding 名稱耦合)。
**③(非阻擋)mcp-setup namespace 不一致** — 核實屬實。
- `cli/src/commands/mcp-setup.ts:53``config.api_key`。self-hosted 若 api_key 存的是舊 ak_(非 namespace),則 MCP 與 CLI 讀寫不同分區。
- **修法**self-hosted 下 mcp-setup 優先用 NAMESPACEconfig.namespace),與 CLI 同一分區。
對應 SDDmira 端記在 mira SDD 14-A(標 🚧 待對端);arcrun 端走協議(kbdb-proxy 屬既有 SDD 範圍)。
---
## 6b. ⚠️ 部署斷層:code 已補但 leo21c 未重部署(總管本地模擬核實 2026-06-15
總管不靠 Hetzner、從本機直接 curl leo21c 端點驗證,發現 **①② 的 code 已 commit 進 arcrun repo,但對應 worker 沒部署到 leo21c CF**
| 證據(本機 curl leo21cnamespace=leo | 結果 | 判讀 |
|---|---|---|
| `GET cypher/kbdb/templates` | 200 | cypher-executor 活著(舊版) |
| `GET cypher/kbdb/entries` | **404** | 新 route 未上線(`b1e302b``/kbdb/entries` 沒部署) |
| `GET cypher/kbdb/records` | **404** | 連既有 records proxy 都 404 → leo21c 上的 cypher 版本落後 |
| 直連 `kbdb.leo21c/entries`(裸開) | 200 | kbdb worker 本體活著,entries 表在 |
| arcrun repo `kbdb-proxy.ts` | 含完整 `/kbdb/entries` CRUD(行 144-184 | **source 正確,純粹是沒 deploy** |
**結論**:缺口①②的 code 修正屬實(commit `b1e302b` `/kbdb/entries` + `1af7655` KBDB service binding),但**卡在「部署到 leo21c」這一步**。在 leo21c cypher-executor 重新部署前,mira `_kbdb_client.py` 即使改好也 smoke 必 404。
**交棒 taskarcrun CC,依協議走既有 SDD + 鐵律「部署繞開 GitHub、wrangler 直推 CF」)**
1. 確認 leo21c 帳號(`CLOUDFLARE_API_TOKEN` 指 leo21c `51a01bfa…`)下 cypher-executor 是哪個版本、為何落後(`acr update` 漏部署 cypher?還是只部署了部分 worker?)。
2. 重新部署 cypher-executor+ 確認 mcp worker 的 KBDB service binding 一併上線,缺口②)到 leo21c。
3. 自驗:`curl -H 'X-Arcrun-API-Key: leo' https://arcrun-cypher-executor.leo21c.workers.dev/kbdb/entries?limit=1` 應回 200(非 404)。回 200 才算缺口①真正清空,mira 14-A 才解鎖。
**接力鏈**arcrun 部署 cypher6b)→ 端點 200 → mira 改 `_kbdb_client.py`14A.1)→ smoke 讀寫 leo21c → 解耦完成。
### 6b-解決(arcrun CC 2026-06-15,已部署 + 自驗 200
**根因不是 GitHub lag**`origin/main` == 本地 4d6e77f,含 `/kbdb/entries` route)。兩層真因:
1. **`acr update` 的 content-hash manifest 跳過機制**`cli/src/lib/deploy.ts:198-225`)把 cypher 當「未變動」跳過 → 落後。解:`acr update --force` 清空 manifest 強制全部重部。
2. **`.env` line 3 的 `CLOUDFLARE_ACCOUNT_ID=58309bb9…`(官方帳號)被 CLI 載入並覆蓋 config.yaml 的 leo21c `51a01bfa…`**env > 全域 config`config.ts:174`)→ leo21c token 對官方帳號認證 → KV 解析「Authentication error」→ update 中止。解:部署時 `CLOUDFLARE_ACCOUNT_ID=51a01bfa… node cli/dist/index.js update --force` 強制 account 對齊 leo21c token。
- ⚠️ **遺留陷阱**repo `.env` 是「官方帳號」部署脈絡用的;對 leo21c self-hosted 部署必須覆蓋 `CLOUDFLARE_ACCOUNT_ID`,否則 leo21c token vs 官方 account 不匹配。見記憶 [[cf-account-official-vs-loadtest]]。
**部署結果**23/23 worker 全部 ✓(含 cypher-executor / kbdb / mcp),seed ✓(10 API + 23 auth recipe),cron index migrate ✓。用本地 build CLI 1.3.12(全域 acr 仍 1.3.11,未 npm publish)。
**自驗(本機 curl leo21cnamespace=leo**
- `GET /kbdb/entries?limit=1`**200** `{"success":true,"entries":[],"count":0}`(真轉發 kbdb worker,非假綠)✅ ← 缺口①清空,**mira 14-A 解鎖**
- `GET /kbdb/templates` → 200 ✅
- `GET /kbdb/records?limit=1`**404(非回歸,by design**proxy 只有 `POST /records``GET /records/by-template/:t``GET /records/:id`**本就無 bare list route**。HANDOFF 原以 records 404 當「cypher 舊版」訊號,但該路由從未存在。
- 缺口②:MCP `initialize``Bearer leo`)→ **200**(非 401`MULTI_TENANT=false` 已注入,KBDB binding 隨 mcp worker 上線)✅
---
> 每項動工前依 `.claude/rules/00-sdd-protocol.md` 宣告已讀 SDD。本 HANDOFF 是「有哪些事」,不是「繞過 SDD 的捷徑」。