# HANDOFF: Matrix 重整交棒給 arcrun（2026-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 → 200（worker 活）；MCP initialize 無 auth → 401；Bearer ak_（舊 uncle6 key）→ 401 Invalid partner key；Bearer leo（namespace 明碼）→ 401；X-Namespace header → 401
- cypher-executor / → 200（CLI 走這條，通）
- `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 dogfood（mira、未來 product）都踩，非 mira 獨有。屬 arcrun 框架側待修，走 SDD 協議（對應 `mcp-account-source.md`，動工前宣告）。
**mira 現況**：全靠 acr CLI 即可推進，不卡。`.mcp.json` 留著等上游修好自動能連。

---

### 3b-2. ⚠️ 第一次端到端實測：修補 code 對，但 `MULTI_TENANT` 沒注入 MCP worker（2026-06-14 晚，mira 推 leo21c + 總管核實）

mira 把 release@main 推上 leo21c（deployment 14:31，version 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 優先用 NAMESPACE（config.namespace），與 CLI 同一分區。

對應 SDD：mira 端記在 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 leo21c，namespace=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。

**交棒 task（arcrun 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 部署 cypher（6b）→ 端點 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 leo21c，namespace=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 的捷徑」。
