# Tasks: KBDB Base — atomic universal table > 對應 design.md。design 待 richblack review 後才動 code。每完成一個 task 立刻標 [x],不批次。 > 來源:壓測報告暴露 self-hosted 無資料層;richblack 2026-06-07 拍板 KBDB 基礎開源 + 插件模式。 --- ## 狀態:SDD 草稿,待 review design + 拍板開放問題後才動 code - [x] Q1 專案維度[拍板 2026-06-07]:richblack 授權 CC 決定,參考 KBDB 既有實作(已有 project/parent 做法) - [x] Q2 KV vs D1 分工[拍板 2026-06-07]:KV 不全廢,按特性分——workflow YAML+recipe+成功記錄進 D1;session/verdict/credential 留 KV - [x] Q3 triplet 接點[拍板 2026-06-07]:triplet = template + 函式。手動(給文字回三元組)或自動(block 存入時叫起,安裝時同意);提供 MCP(AI-friendly,交貨帶 MCP) - [x] Q4 D1 免費不綁卡[查證 2026-06-07 CF docs]:Workers Free 可用、不需信用卡(不像 R2)。額度 5M 讀/日、100K 寫/日、5GB。用量大時 CF 自會提醒用戶。 ## Phase 0:基礎抽取與解耦 - [x] 0.1 三表 migration 抽出 arcrun/kbdb/migrations/0001_base.sql(entries/templates/entry_values + recipe_stat template seed),無 triplet/entity/vectorize 表 - [x] 0.2 萬年不動:新基礎 schema 本就不含 entity_type(那是 triplet 衍生欄位)→ 基礎 entries 無此欄,衍生屬性天然在基礎表外。原 kbdb 的 UPDATE blocks SET entity_type 屬 triplet 模組(獨立 repo),不影響 arcrun 基礎 - [x] 0.3 解耦:arcrun/kbdb 從零寫乾淨基礎(entry/template/record CRUD),不 import 任何 embed/triplet(grep 證);不去動原 kbdb repo(官方版仍用,動它有風險) - [x] 0.4 templates/records route 純淨:只依賴 record-crud(D1),無 vectorize/triplet - [x] 0.5 基礎 search = D1 LIKE(GET /entries/search?q=,mode:keyword);語義層留給 embed 模組(未在基礎) ## Phase 1:embed 模組(CF 內建,binding 開/關,不拆 repo) > 狀態:基礎已與 embed 完全解耦(不 import)。embed 模組本身(Vectorize upsert + 語義 search)尚未實作——基礎不依賴它即可,embed 待要用時再加。以下 1.x 未做。 - [ ] 1.1 embed 改可選 hook:有 env.VECTORIZE 才掛 - [ ] 1.2 search 語義層:有 Vectorize 啟用,否則降級 LIKE,API 不變 - [ ] 1.3 wrangler.toml:Vectorize/AI binding 可選 ## Phase 2:import 進 arcrun(如 MCP pattern) - [x] 2.1 基礎 KBDB Base 搬進 arcrun/kbdb/(Worker + D1):kbdb/ 已建(三表 CRUD + recipe-stats + migration),納入 find wrangler.toml deploy 掃描 - [x] 2.2 cf-api.ts 加 D1 建立(listD1Databases/ensureD1Database);deploy.ts 注入 d1DatabaseId 到 kbdb wrangler.toml - [x] 2.3 self-hosted init 建 KV + D1(Q4 已確認免綁卡):init ensureD1Database 建空 D1 → deploy 部署完對 D1 套 migrations/0001_base.sql(CF /d1/query API,idempotent)建三表 + recipe_stat seed + 注入 wrangler.toml database_id - [ ] 2.4 cypher 改用 KBDB 存專案/工作流歸屬(依 Q1/Q2,漸進)— 未做(後續) ## Phase 3:triplet 模組(獨立 repo,本 SDD 只定接點) - [ ] 3.1 確認基礎不依賴 triplet(Phase 0.3 後驗證) - [ ] 3.2 定義 triplet 掛上基礎的接點(依 Q3) - [ ] 3.3 triplet 本身 → 獨立 repo,不在本 SDD ## Phase 4:官方共用基礎(方向,搬遷另排) - [ ] 4.1 官方版改用同一份基礎 KBDB(binding 全開)→ 不維護兩套 ## Phase 5:recipe 投稿 + 帶 KBDB 成功記錄(免官方驗證)—— 本次要做(design 7) - [x] 5.1 recipe 成功記錄落地 D1:判定單位=工作流執行(n8n execution)。GraphExecutor 收集本次用到的 recipe key(usedRecipeKeys=API recipe uuid,§7.5.h 改 per-uuid;舊資料 fallback canonical_id);executeWebhookGraph 執行結束後一次性 POST KBDB /recipe-stats/record(整體成功→各+1成功、真錯非paused→各+1失敗,fire-and-forget via waitUntil)。cypher tsc exit 0 - [x] 5.2 投稿端點(cypher recipes.ts):POST /recipes/submit(需 exposure_consent、stat 存證不當門檻)。**已修正**(7.5.f):原「覆蓋同 canonical_id」→ app-store/UUID 模型「領新 uuid 新增作者版本」,同 canonical 多作者並存。cypher tsc exit 0 - [x] 5.3 CLI 接點(= 7.5.b/c/e):acr recipe push(私庫)/ pull(公→私)/ submit-p(公共庫帶暴露同意)。cli tsc exit 0 - [x] 5.4 市場機制(靠量/星數模型,design §7.3):stat 存證已做(5.2 recipe_submission entry)+ per-uuid 市場數據(5.1+7.5.h)。先市場優先、暫不強防偽(5.6 後續) - [ ] 5.5 市場同步(跨環境聚合層,§7.3 主體):self-hosted 各用戶真實成功/失敗匯總回公共市場 → recipe 星數/信用。5.1 已在各環境記錄,聚合另排 - [ ] 5.6 強防偽(只在市場失靈才做):官方 in-process 重跑投稿者工作流拿官方自己 2xx / 第二投稿者獨立回報;版本並存/舊版下架 ## Phase 7.5:公庫/私庫雙向機制(CHANGE,design §7.5)—— richblack 2026-06-07 review 通過,可執行 > richblack 指示「把兩庫所有情境想好」+「這些細節想好是可以執行」→ §7.5 review 通過,開始動 code。 > **7.5.5 拍板:recipe = 具名作者作品(app-store 模型)**——同 canonical_id 多作者並存、只有作者+admin 能改、 > 投稿=新增作者版本(非覆蓋)、向後相容不刪舊、選擇由市場數據驅動、無「公庫改私庫要不要跟」問題。 > **7.5.6 拍板:搜尋落空=創作入口**——公庫沒有→回 found:false 創作引導→CC 現做成為作者→投稿補上(閉環)。 - [x] 7.5.g 落空創作引導:GET /public-recipes(?q=) 與 GET /public-recipes/:canonical_id 落空回 { found:false, hint } 創作引導,不回空陣列。cypher tsc exit 0 - [x] 7.5.a 公庫只讀端點(cypher recipes.ts):GET /public-recipes?q=&limit=&offset=(list/search 多作者+per-uuid 市場星數)、GET /public-recipes/:canonical_id?author=(pull 取全文,多作者選市場最佳)。cypher tsc exit 0 - [x] 7.5.h **市場星數 per-uuid(§7.5.h)**:5.1 改收集 API recipe uuid(resolveRecipe,非 resolveAuthRecipe);usedRecipeServices→usedRecipeKeys;KBDB 星數記 per-uuid;public-recipes 選最佳 per-uuid 查 → 真正區分 Leo/John 版。cypher tsc exit 0 - [x] 7.5.f **recipe UUID 身份模型(app-store 核心,§7.5.5 拍板)**:recipes.ts RecipeDefinition 加 uuid/author/derived_from;installRecipeRecord helper(recipe:{uuid} + idx:canonical 清單 + idx:installed + idx:hash);POST /recipes=私庫沿用 installed uuid 就地更新;POST /recipes/submit=領新 uuid 新增作者版本(非覆蓋);resolveRecipe 向後相容(uuid→installed→fallback 舊 key,不破執行鏈);DELETE 清 uuid+索引;GET dedup;init-seed 用 UUID(author=system);POST /recipes/migrate-uuid 一次性轉舊 key(增量寫不刪舊、冪等)。cypher tsc exit 0。重複靠市場淘汰、不做檢舉、CC 不檢舉(§7.3+mindset §7) - [x] 7.5.b 公→私 pull(CLI 薄殼):acr recipe pull [--author] → GET 公庫 /public-recipes/:id → POST 自己私庫 /recipes(帶 derived_from 溯源)。cli tsc exit 0 - [x] 7.5.c 公庫搜尋(CLI 薄殼):acr recipe search → GET 公庫 /public-recipes?q=,印多作者+市場數據,落空印創作引導。cli tsc exit 0 - [x] 7.5.e submit-p(CLI 薄殼):acr recipe submit-p [--author] → GET 私庫取全文 → 暴露同意 → POST 公庫 /recipes/submit(新增作者版本)。config 加 DEFAULT_PUBLIC_LIBRARY_URL(公庫=官方 cypher,ARCRUN_PUBLIC_LIBRARY_URL 可覆蓋)。cli tsc exit 0 - [x] 7.5.i **MCP 薄殼補齊 recipe 工具(rule 07 §5)**:新增 mcp/src/tools/arcrun_recipe.ts 六工具 arcrun_recipe_search/pull/submit_p/push/list/delete(registerAllRecipeTools 註冊進 registry.ts),全用 cypherFetch 薄殼模式(無業務邏輯)。與 CLI 六能力對齊,MCP 不再落後。submit_p 帶 exposure_consent 把關。mcp tsc exit 0。註:MCP 連平台 cypher(§5.2 account-source 已知違反 pre-existing,沿用既有模式不一併修) ## Phase 8:KV list 上限威脅免費承諾 → 高頻 list 遷 D1(CHANGE,design §8)—— 待 richblack review 分期顆粒度,勿動 code > 2026-06-08 richblack CF 帳號收到 KV list 超標信(每日 1000 上限,429)。威脅免費核心承諾。 > 方向拍板:高頻 list 遷 D1(對齊 §6 Q2)。根因①cron 每分鐘 list(1440/日單獨就爆)②§7.5 新加的 recipe 搜尋 list。 > 待 review §8 分期顆粒度後才動 code。 - [x] 8.P0 **緊急止血 cron**(§8.2):scheduled.ts 每分鐘 WEBHOOKS.list('cron-idx:') → 改單一固定 key(cron-idx:_all 存 {apiKey}:{name}→cron_expr map)只 get 一次。新增 lib/cron-index.ts(readCronIndex/updateCronIndexEntry,單 key read-modify-write);webhooks-named POST/DELETE 改維護單 key;新增一次性 POST /webhooks/named/migrate-cron-index 把舊 per-key 折進集中 key(冪等、不刪舊);acr update 部署後自動呼叫 migrate(接在 seed 後,冪等、失敗不致命)→ 既有 cron 不必手動重 push。1440 list/日 → 0 list。cypher+cli tsc exit 0。**已完成 2026-06-09** - [ ] 8.P1 recipe 查詢遷 D1(§8.3):public-recipes 搜尋 + GET /recipes list(§7.5 新加的元兇)改 D1 query(LIKE/WHERE,多作者/市場排序天生適合 SQL) - [ ] 8.P2 workflow list 遷 D1:webhooks-list/webhooks-named 的 list 改 D1 query(entry_type=workflow) - [ ] 8.P3 recipe/workflow 本體完整遷 D1:resolveRecipe / KV→D1 讀寫 + migration + 雙寫過渡(KV 舊資料相容)。session/credential/exec-context 留 KV(§6 Q2) ## Phase 9:KBDB 資料層薄殼補 MCP/CLI(HANDOFF §2,design §4「交貨帶 MCP」)—— 本次做 > 核實:CLI/MCP 現在完全沒 KBDB 資料層能力(既有 arcrun_skills_examples 打的是舊 /blocks /search > v3 schema,非本基本盤三表)。基本盤 API 已完整(templates/records/entries/search)。 > 本 Phase = **薄殼暴露**,不重寫能力(rule 07)。 > **KBDB 鐵律(leo 2026-06-14)**:不提供建表/SQL tool,AI 只有「建 template(name+slots) + 填 record(slot→content)」 > 可用(類 Supabase 萬用表);薄殼只經 KBDB service binding 調基本盤 HTTP API,不直連 D1、不寫 SQL。 - [x] 9.1 **MCP 薄殼**(AI 用,插件也走這條):mcp/src/tools/kbdb_data.ts,6 工具 `kbdb_create_template`(name+slots)、`kbdb_list_templates`、`kbdb_create_record`(template+values)、 `kbdb_get_record`(record_id)、`kbdb_query`(by-template 列 records)、`kbdb_search`(entries LIKE q)。 全走既有 kbdbFetch(KBDB binding)薄殼模式,無業務邏輯。registerAllKbdbDataTools 註冊進 registry.ts。 **不含建表/SQL tool**(鐵律,grep 證 code 無 CREATE TABLE/.prepare/env.DB/SQL)。**mcp tsc exit 0**(2026-06-14)。 - [x] 9.5 **cypher KBDB proxy(9.2 的前置,2026-06-14)**:CLI 是 client 只認證到 cypher,達不到獨立 KBDB worker(MCP 走內部 service binding 可達,CLI 不行)。故在 cypher 開 `cypher-executor/src/routes/kbdb-proxy.ts` 純轉發 `/kbdb/templates|records|search` → KBDB 基本盤(沿用 KBDB_BASE_URL HTTP fetch + KBDB_INTERNAL_TOKEN, **不新增 service binding** rule02 §3.1)。**租戶隔離(leo 拍板選項①)**:X-Arcrun-API-Key 自動當 owner_id 注入 records/entries(強制覆寫 caller 自帶 owner_id 防跨租戶寫);**templates 全域共享**(虛擬表定義是 schema 非資料)。 無 SQL/建表/業務邏輯(純 proxy)。掛進 index.ts。cypher tsc exit 0。 - [x] 9.2 **CLI 薄殼**(人用,2026-06-14):`cli/src/commands/kbdb.ts` — acr kbdb template create/list、 record create/get、query、search,透過 9.5 的 cypher proxy 打基本盤(與 MCP kbdb_* 同能力,差異只來自介面慣例 rule07 §3.4)。註冊進 index.ts(`acr kbdb`)。無業務邏輯(薄殼)。cli tsc exit 0。 **未驗收**:端到端需 cypher 部署 + KBDB_BASE_URL 可達後實測(acr kbdb template create → query 回得到)。 - [x] 9.3 **基本盤 entries 加 page_name 讀過濾**(2026-06-14):listEntries 加 `page_name` 過濾 + GET /entries 接 `?page_name=`(既有欄位的便利查詢,不動表結構、不違反「表不變」鐵律)。 用途:skills/examples 用 page_name 當 idempotency key 做 get-by-key。kbdb tsc exit 0。 - [x] 9.4 **修復 LI M3 斷鏈**(2026-06-14,連動 llm-interface M3.2/M3.4):skills/examples 整條從 舊 v3 `/blocks` `/search` 改打基本盤 `/entries`(entry_type 對應)。5 個已上線的 MCP 工具原本 對死 route 回 404(假綠),現修正;sync-registry-to-kbdb.py 改打 /entries idempotent upsert。 誠實降級:基本盤無語義 search → search_examples 改 LIKE 關鍵字(embed 模組 Phase 1 上線再換回語義)。 mcp + kbdb tsc exit 0。 - [x] 9.6 **cypher proxy 補 `/kbdb/entries` CRUD(HANDOFF §2 缺口①,2026-06-15)**:9.5 proxy 只轉發 templates/records/search,**漏了基本盤的 `/entries` CRUD**——這正是 mira `_kbdb_client.py` 主線遷移 (ingest/create_block/get_by_id/get_by_page_name/patch_block)要打的端點。補 POST/GET(list)/GET(:id)/PATCH(:id) `/kbdb/entries` 純轉發到 KBDB 基本盤 `/entries`。**租戶隔離同 9.5 選項①**:寫入強制注入 owner_id、list 強制 以本租戶 owner_id 過濾(防跨租戶讀)、PATCH 剝除 caller 自帶 owner_id(防認領/踢走);by-id GET 沿用既有 records by-id 慣例(require-key)。**刻意不開 DELETE**(基本盤 delete-by-id 無 owner 檢查,經 proxy 暴露 = 跨租戶刪除風險;mira 也不需要)。無 SQL/業務邏輯(純 proxy)。**cypher tsc exit 0** + **端到端 prod 驗收綠**(2026-06-15): 無 key→401;A POST→owner_id 自動=A;GET by id 回得到;A list count=1、B list 同 type **count=0**(跨租戶隔離); PATCH 改 content 成功且 owner_id hijack→B 被剝除(仍=A、B 看不到);page_name lookup count=1(mira idempotency 路徑); POST 帶 caller owner_id=B→覆寫成 A。已部署 arcrun-cypher-executor(官方 58309bb9)。smoke 資料已清。 - [x] 9.7 **修 `arcrun_report_feedback` 死 route(HANDOFF §3b 連帶,9.4 漏網,2026-06-15)**:9.4 把 skills/examples 從舊 v3 `/blocks` 改打基本盤 `/entries`,但 `arcrun_report_feedback` 仍 POST 死掉的 `/blocks` (KBDB 基本盤只 mount entries/templates/records/recipe-stats,無 /blocks → 404 假紅)。改打 `/entries` (entry_type=agent-feedback、owner_id=用戶 namespace、source/api_key 併入 metadata_json、tags_json 不變)。 回傳 id 從基本盤 `{entry:{id}}` 取(兼容舊 `{id}`)。薄殼模式不變(kbdbFetch)。**mcp tsc exit 0** + **端到端 prod 契約驗收綠**(2026-06-15):確認舊 `/blocks`→**404**(正是原 bug、report_feedback 假紅根因); 用 9.7 實際送的 payload(entry_type=agent-feedback + metadata_json/tags_json)POST `/entries`→success、欄位保留; 經 cypher proxy 讀回 count=1。已部署 arcrun-mcp(官方 58309bb9)。注:MCP service-binding hop 由既有 kbdb_* 工具 (9.1,同 kbdbFetch 路徑,2026-06-14 已驗)佐證 binding 活;本次只修死 URL。smoke 資料已清。 ## Phase 10:base 補 record PATCH(mira-dissolve T2 `[→arcrun]`,issue #6)—— 本次做 > 來源:頂層 SDD `docs/3-specs/mira-dissolve/`(T2.1/T2.2),總管經本 repo GitHub issue #6 交辦。 > 用途:graph 插件的精耕「取代」語意(同來源檔重萃 → 舊版 deprecate)需要「改既有 record 的 slot 值」。 > **三表 append-only 不破**:deprecate = 翻 record 的 slot 值(改底層 `entries.content`),不動表結構、不加欄、不刪 row。 > **base 不知 triplet(解耦鐵律 0.3,grep-proven)**:故 base 端 **不建 `/templates/triplet` 專屬端點**。 > issue 描述的「PUT /templates/triplet 加 status/superseded_by」拆兩半(與頂層 tasks T2.2/T3.2 一致): > base 只提供**通用** template 增改 slots 能力(既有 `PATCH /templates/:id` 已替換 slots_json,本就支援); > triplet 專屬的 `status`/`superseded_by` 兩 slot 由 **T3.2 在 kbdb-graph-plugin 的 `TRIPLET_SLOTS` 補**(另一 repo,非本次)。 - [x] 10.1 **`PATCH /records/:id`(T2.1,前置硬依賴)**:改既有 record 的 slot→content 值。底層更新對應 `entries.content`(既有 slot 找 entry_value→entry 改 content);slot 不存在則補建 entry + entry_value(用 record 的 template 推算 slot 是否合法)。**三表結構一個欄位都不加**。`updateRecord` 在 record-crud.ts、route 在 records.ts。 - [x] 10.2 **template 增改 slots = 既有 `PATCH /templates/:id`(T2.2,base 端)**:核實 `updateTemplate` 已支援 `slots` 替換(record-crud.ts:44 既有)→ base 端通用能力已就緒,**無需新 code、不建 triplet 端點**。triplet 兩 slot 歸 T3.2(plugin repo)。本條=核實 + 文檔釐清,非改 code。 - [ ] 10.3 **(選)`DELETE /records/:id`(T2.3)**:暫不做。依賴頂層 T8.3「死資料自動刪除原則」(design 待觀察未定); 且 deprecated record 查詢 `where status=active` 本就濾掉 → 無此端點不阻擋 deprecate 落地。待頂層拍板再補。 ## Phase 11:self-hosted KBDB 查詢能力補缺(issue #5,普世框架視角)—— 本次做 > 來源:issue #5(原 Mira dogfood 開,Mira 已蒸發 → 當「未來任何 self-hosted 用戶都會撞的框架缺口」處理)。 > 四點分流依 leo 2026-06-26 修正指示 + 頂層 mira-dissolve 重審: > 規則判準見 07-thin-shell §3.5(issue #4 自力救濟階梯):source/DELETE 屬**自家 API 缺能力 → 補 API**。 - [x] 11.1 **source 過濾(#5 第1點,✅ 做,普世成立)**:`listEntries` 加 `source` filter, GET /entries 接 `?source=`。**零建表/零 migration**:用 SQLite `json_extract(metadata_json,'$.source')` 查既有 metadata_json TEXT 欄(**不加欄、表不變鐵律**)。cypher proxy `GET /kbdb/entries` 白名單加 `source`(隨租戶 owner_id 一起篩)。按來源篩 + 語義/關鍵字查詢都會用,ingest envelope 帶 source.uri。 kbdb+cypher tsc exit 0。**端到端待 leo21c 部署驗**(需寫一筆帶 metadata.source 的 entry → ?source= 篩回)。 - [ ] 11.2 ~~documents 聚合 GROUP BY page_name(#5 第2點)~~ **不做**(舊河道頁特例):新架構「跨 vault 的圖」 走 graph MCP traverse/neighbors,不靠 KBDB 出 SQL 聚合端點。普世用戶也不需要。頂層 R6 已否決。 - [ ] 11.3 **cypher proxy DELETE(#5 第3點)⏸ 暫擱置**:依賴頂層「死資料自動刪除原則」(mira-dissolve T8, 待觀察未定)。等 T8 拍板再補。**註**:#6 已對 records proxy 同理擱置 DELETE(裸 delete-by-id 無 owner 檢查, 經 proxy 暴露=跨租戶刪除風險,補時要先讀 entry 驗 owner_id==本租戶才放行)。 - [→#7] 11.4 **embed-on-write(#5 第4點)併入 #7**:開 embed module + `kbdb_embed:true` 後寫入是否自動 embed,由 #7 embed 模組定義(module 職責,前端不該手動戳 process-page)。不在 #5 單獨處理。 - [x] 11.5 **能力對照文件(#5 第二部分)**:`docs/4-guides/kbdb-capabilities.md` — self-hosted arcrun-kbdb 現有查詢能力清單 + 端點對照。**不寫「documents/process-page 待移植」** (舊河道視角,新架構不移植)。 ## Phase 12:optional embed 模組 + vectorize 開關 + 語義查詢(issue #7 / mira-dissolve T2.4)—— 本次做 > 來源:issue #7(總管,全包 4 件)+ 頂層 mira-dissolve T2.4 系列。普世框架能力(任何 self-host 用戶可選開語義查詢)。 > 鐵律:embedding 屬 **base optional 模組**(非 graph/ingest);CF Vectorize+AI binding 開/關,不拆 repo; > **不裝保持輕**(free-tier 友善);不對每個 block 地毯式 embed(精耕:只 embed 標 embed:true 的 entry)。 > 解鎖下游:ingest embed(第二階段)+ graph 詞+gloss 語義 normalize(T3.2c)等此。 - [x] 12.1 **base embed 模組(T2.4,從零做)**:`kbdb/src/embed.ts`——`embedEnabled()`(VECTORIZE+AI binding 都在才算開)、 `embedOnWrite()`(寫入時對標 `metadata_json.embed:true` 的 entry 做 Workers AI `@cf/baai/bge-base-en-v1.5` 768 維 → `VECTORIZE.upsert`,標 is_embedded=1,**不動表結構**)、`semanticSearch()`(query 向量 + metadata filter owner_id/source)。**base 對內容語意無知**:用通用 `embed:true` flag 而非寫死 entry_type 白名單(不破解耦)。 wrangler.toml 加註解版 `[[vectorize]]+[ai]`(deploy 開時取消註解)。 - [x] 12.2 **entries route 接 embed(含 #5 第4點 embed-on-write)**:POST/PATCH 用 `executionCtx.waitUntil` fire-and-forget embed(模組開 + entry embeddable 才做,失敗不致命);DELETE 連帶刪向量(避孤兒); **GET /entries/search 加 `mode=keyword|semantic`**:semantic 需模組開,未開→**誠實降級 keyword + `capability_hint` 告知「叫 CC 幫開 vectorize」**(發現閉環,#7 第4點 + 不假綠)。kbdb tsc exit 0。 - [x] 12.3 **vectorize 開關從零做(T2.4c)**:`.arcrun.yaml`/config 加 `kbdb_embed`(config.ts interface + env override ARCRUN_KBDB_EMBED 布林);`deploy.ts` 加 `DeployContext.kbdbEmbed`:開時 `ensureVectorizeIndex`(REST `POST /vectorize/v2/indexes` dims=768/cosine,冪等)+ `injectWranglerConfig` 取消 kbdb toml 的 vectorize/ai 註解 (**置於 stripOfficialOnlyBindings 之後**,否則 [ai] 被 strip 清掉——已驗);`acr init` 互動加問「要不要開語義查詢」 (預設關);存進 config 讓 acr update 維持一致。cli tsc exit 0。 - [x] 12.4 **KBDB MCP 加語義查詢(T2.4b)**:`kbdb_search` 加 `mode`/`source` 參數透傳 + 把 base 的 `capability_hint` 當 next-step 回給 AI(語義/關鍵字同一 KBDB MCP,D17 邊界)。薄殼模式不變(kbdbFetch)。mcp tsc exit 0。 - [x] 12.5 **CC 幫開 vectorize(T2.4d,第一版)**:路徑=CC 寫 config `kbdb_embed:true` + `acr update`(已接 kbdbEmbed → 建 index + 注入 binding redeploy)。base 查詢回應的 `capability_hint` 是發現入口。Pages 設定頁不做(leo 排未來)。 - [ ] 12.V **端到端驗收 ⏳ 待 leo21c 部署驗**(需官方/leo21c 帳號開 Vectorize index):開 kbdb_embed → acr update → 寫一筆帶 `metadata.embed:true` 的 entry → `?mode=semantic` 搜回;未開時 `?mode=semantic` 回 keyword+capability_hint。 本次只到 **tsc exit 0(kbdb/cypher/cli/mcp 全綠)+ toml 注入 dry-run 驗證**,不假裝端到端綠(mindset §7)。 ## 驗收 - [ ] V1 純 D1(無 Vectorize/AI)能 CRUD entries/templates/records + LIKE search - [ ] V2 開 Vectorize 語義啟用、關掉降級 LIKE,API 不變 - [ ] V3 基礎 blocks/templates/records grep 無 vectorize/triplet import - [ ] V4 self-hosted init 建 D1 成功、不綁卡 - [ ] V5 列出某專案下所有工作流可行 - [ ] V6 各 worker tsc exit 0 ## Notes - 插件模型對標 PostgreSQL:基礎核心=psql core;embed=PGVector;triplet=Apache AGE。 - embed 不拆 repo(CF 內建、binding 開關);triplet 拆獨立 repo(IP、action 多)。 - 官方與 self-hosted 共用同一基礎,差別只在 binding → 只維護一套。 - recipe 投稿入口是另一條線(registry),不在本 SDD。