Files
Arcrun/system-dev/docs/3-specs/pending-changes.md
T
uncle6me-web 3d3973ecbc feat(storage): 工作流與 recipe 的家搬到 KBDB,KV 降成可丟棄的快取(Arcrun#16+#17)
leo 08-12:「我要的是寫進 KBDB,不是 KV,他的 Recipes、Cypher 是一段話,文字,
數據,一個 entry」「如果零件和工作流的 recipe 不見了,是很可怕的事情」。
同日實害:一次例行更新讓九支工作流在畫面上全部消失。#97 已修掉直接原因
(別再照名字猜使用者的資源、別再擅自新建一顆空的綁上去);這裡修更下面那一句——
**資產本來就不該只存在於一個會被換掉的暫存層裡**。

做法(換 binding,不改四十幾處呼叫端):
- lib/asset-keys.ts    哪些 KV key 是資產、對應 KBDB 哪一列。**唯一**要人看懂的那張表。
- lib/durable-store.ts 讀=KV 先行、miss 回源 KBDB 並補快取;寫=先 KBDB 再 KV,
                       KBDB 失敗就拋錯(禁假綠);**列舉一律回源**——空 KV 列出來是
                       「零筆」而不是「查不到」,那正是東西消失的形狀。
- index.ts             入口把 WEBHOOKS/RECIPES 換成上面那層。逐處改寫一定會漏,
                       而漏掉的那一處就是下一次「東西不見了」的入口。
- routes/storage.ts    /storage/audit(搬前搬後各數一次)+ /storage/migrate-to-kbdb
                       (只增不刪、冪等、逐筆回報成敗)。
- kbdb                 migration 0005 seed 四列 template(零 schema 異動,手法同 0003/0004)
                       + PUT /entries/:id 指定 id 的整列 upsert(通用原語,不是為誰開特例)。
- 衍生資料(idx:*、cron-idx:_all)不進 KBDB,讀不到就從資產重算。

⚠️ 狀態=◐ 半通,**別因為程式碼看起來完整就先合併**。
已實測:5 份 migration 在本機 D1 全數套用(含 0005);兩顆 worker 都能以改動後的
程式碼在本機開起來;tsc 錯誤數 7→7(既有,未新增)。
**沒跑到**:「砍掉 KV、資產還在」那一次端到端驗證——本次施工環境的權限閘不放行
執行 vitest/node/curl。那一次已寫成 scripts/verify-kv-retirement.sh,
在能執行的機器上跑一次就是證據。建議順序:先跑腳本、綠了再合併。

規格層依 D35 走 pending-changes.md「P-KV」提案,等 leo confirm(現行 active SDD
是 workflow-discovery,本案不在它的 tasks 內,故不自建 SDD、不改 rules 那張儲存表)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 16:51:58 +08:00

47 KiB
Raw Blame History

Pending Changes(規格變更緩衝區)

規則來源:SDD-LIFECYCLE.md 第 3、4 條。 規格層變更(核心設計/方向改變)只有這一條路CC 把 change proposal 寫進「待裁決」—— 變更摘要與觸發原因+影響分析(現行 SDD 哪些任務作廢/修改/不受影響/尚未完成)——然後停止, 等使用者明說「confirm」才依第 4 條開新 SDD;沒 confirm 就繼續依現行 SDD 工作。 多個 proposal 可並存,由人一次裁決。本檔不是 SDD,不掛 status。

待裁決

P-KVKV 退休:工作流與 recipe 的家搬到 KBDBLeo/Arcrun#16 + #17)— 2026-08-12

觸發leo 2026-08-12 原話——

「我要的是寫進 KBDB,不是 KV,他的 Recipes、Cypher 是一段話,文字,數據,一個 entry」 「因為對 KV 的使用有禁令,但卻會把資產放在這裡,這不是違法嗎?」 「現在是我幫他寫工作流,未來是他的 AI 自己寫工作流, 如果零件和工作流的 recipe 不見了,是很可怕的事情

同日實害:一次例行更新讓使用者的九支工作流在畫面上全部消失(Arcrun#97)。 #97 已修掉直接原因(cli/src/lib/resource-resolver.ts:不再照名字猜使用者的資源、 不再擅自新建一顆空的綁上去)。本案修的是更下面那一句:使用者的資產本來就不該 只存在於一個會被換掉的暫存層裡——#97 修的是「別再換錯」,這裡修的是「換了也不會怎樣」。

為什麼要走規格層(D35.claude/rules/01-tech-stack.md「資料儲存」那張表把 workflow 定義寫在 WEBHOOKS KV、recipe 寫在 RECIPES KV。改掉真相來源=改規格。 現行 active SDD 是 workflow-discovery,本案不在它的 tasks 內,故依 D35 第 3 條 寫 proposal 停下等 leo confirm。#16 已被多份 SDD 引用為前提 arcrun/artifact-sharing/ design K2「KBDB 是唯一公庫後端」、requirements Out of Scope、 tasks 1.55.2 都寫明「遷移本體由 #16 負責」),所以這不是新方向,是那些卷等的那一塊落地。

提議的規格(三句)

  1. 資產的真相來源=KBDBD1 entries 一列一份資產)。KV 降級為可丟棄的快取。
  2. 零 SQL、永不加表D38):新增四個 entry_type workflow_def / api_recipe / auth_recipe / prompt_recipe), 各在 templates 表 seed 一列定義(kbdb/migrations/0005_arcrun_asset_templates.sql, 手法同 0003/0004)。定義本體打包進 metadata_json,比照 execution_logrecipe_stat 既有先例。
  3. 衍生資料不進 KBDBidx:*recipe 反查)、cron-idx:_all 算得回來, 留在 KV,讀不到就從 KBDB 重算(不讓 KBDB 長出垃圾列)。

實作形狀(已寫在 feat/kv-retire-recipes-16-17 分支,未合併)

  • 換 binding 而不是改呼叫端:src/index.ts 入口把 WEBHOOKSRECIPES 換成 KBDB 撐腰的包裝(src/lib/durable-store.ts),四十幾處呼叫端一行不動。 理由:逐處改寫一定會漏,漏掉的那一處就是下一次「東西不見了」的入口
  • 「哪些 key 是資產」集中成一張表(src/lib/asset-keys.ts),是唯一需要人看懂的東西。
  • 讀=KV 先行、miss 回源 KBDB 並補快取;寫=先 KBDB 再 KV,KBDB 失敗就拋錯(禁假綠); 列舉一律走 KBDB——空 KV 列出來是「零筆」而不是「查不到」,那正是消失的形狀。
  • 搬遷與盤點:GET /storage/auditPOST /storage/migrate-to-kbdb(只增不刪、冪等、逐筆回報)。
  • KBDB 端只加一個通用原語:PUT /entries/:id(指定 id 的整列 upsert),零 schema 異動。

影響分析

  • 現行 active SDD workflow-discovery不受影響。它的 entry_type='workflow' 搜尋 entry 照舊雙寫,本案刻意用另一個型別 workflow_def 存定義本體、且不標 embed, 以免同一支工作流嵌兩份向量。search/backfill 兩支端點一行未動。
  • artifact-sharing:本案就是它 K2 等的 #16。落地後可拆 tasks 1.5 的 KV 過渡轉接(5.2)。
  • credential不碰。憑證走 CF Workers Secrets D1 目錄(rule 01),不在本案範圍。
  • 匿名 webhookwebhooks.tsput(token, record)):目前沒搬,仍是 KV-only。 它也是使用者建出來的東西,但不在 #16/#17 的字面範圍內——在此列出,請 leo 裁要不要納入。
  • 效能:資產讀取多一層快取判斷;快取命中時與現況相同,miss 時多一次 KBDB 往返。 list 一律回源,但會順手把整批補進快取,所以「列出來再逐筆讀」總共只多一次往返。

尚未完成/誠實限制(決定要不要 confirm 前請先看這段)

  • 端到端證據沒跑。實作環境(雲端工人沙箱)不放行執行測試與 HTTP (vitestnodecurl 皆被權限閘擋下),所以「砍掉 KV、資產還在」這一次 我沒有真的做出來給你看。已跑到的只有:5 份 migration 在本機 D1 全部套用成功、 兩顆 worker 都能以改動後的程式碼在本機開起來、tsc 錯誤數與改動前一致(7 個既有錯,未新增)。
  • 那一次驗證已經寫成可執行的腳本 scripts/verify-kv-retirement.sh (開空實例 → 放 9 支工作流+3 份 recipe → 數一次 → 砍掉整個 KV 層重建 → 再數一次 → 真的觸發一支確認跑得動),在能執行的機器上跑一次就是那個證據
  • 因此本案的狀態是 ◐ 半通:程式碼與遷移路徑齊備,證據缺一份。 建議 confirm 的順序是「先跑那支腳本、綠了再合併」,不要因為程式碼看起來完整就先併—— 這件事的整個重點就是不要再有「看起來好好的,其實東西不見了」。

⏸ 停在這裡等 leo 裁: ① 方向 confirm 嗎(資產真相來源改 KBDB、KV 降快取)? ② 匿名 webhook 要不要一起納入? ③ KV 舊資料要不要清(本案只增不刪,清是另一個決定)?


P2|fan-out 並行執行(一個節點的多條出邊目前是循序跑)— 2026-08-03

觸發:leo 08-03 原話——「這是在測試中的計畫,希望體驗很好,我發現用 gemma4 的反應非常慢。」 把 rag_chat 的生成端換成 Workers AI 之後(16.87 s → 2.2 s),一量才發現 慢的大頭根本不是 LLM

實測(1.4.4 實例,逐段疊加、每段取兩次的較快值)

① prepcode                    208 ms
② +kw_search                    1,383 ms   (+1,175)
③ +sem_search                   3,240 ms   (+1,857)
④ +fetch_triplets               5,198 ms   (+1,958)
⑤ +fetch_blocks a/b/c           7,793 ms   (+2,595)
⑥ +assemblecode              8,421 ms   (+628)
   +ask_llmWorkers AI        ≈10,400 ms (+2,000)

6 個 KBDB 檢索節點合計約 7.6 s,佔全鏈 73%;LLM 只佔 20%。 而這 6 個節點彼此完全獨立kwsemtripletsblocks×3 誰都不吃誰的輸出), 只是因為 flow 被寫成一條鏈才一個接一個跑。

根因在引擎,不在 workflowcypher-executor/src/graph-executor.ts):

  • 起點節點已經是並行的(:85 Promise.all(startNodes.map(...))
  • fan-in 已經支援:78-84 入度 >1 的節點等所有上游到齊)
  • 出邊是循序的:427 for (const edge of outEdges),迴圈內 await executeNode ⇒ 一個節點分岔出 6 條 ON_SUCCESS,是一條跑完才跑下一條。 ⇒ 改 workflow 解不了:把 6 個節點都掛在 prep 底下,只是把「鏈」變成「6 條循序出邊」,一樣慢。

提案(擇一,我建議 A

  • A. 出邊並行 + 沿用既有 fan-in:把 :427 那個迴圈改成 「同型別、無條件分支的出邊」用 Promise.all 併發,其餘(ON_TRUEON_FALSEON_BRANCHON_FAIL 維持原樣。rag_chat 的 6 個檢索節點改掛在 prep 底下、匯流進 assemble(入度 6,fan-in 現成) ⇒ 預估 7.6 s → 約 2 s,全鏈約 10.4 s → 4.5 s⚠️ 這是引擎核心、風險最高(照本 repo 自己的規矩:先寫測試再改)。 需要先講清楚的語意:多條邊並行時 result 怎麼合併(現行是「後一條覆蓋前一條」的隱含語意)、 任一條失敗時的行為、trace 的順序。既有 workflow 行為必須零變化,且要跑一次證明。

  • B. 只砍節點數(完全不動引擎)kw_searchsem_search 在 v2 計分裡只是小加分 (kw 命中 +2、sem 前十 +0.4,主導權在 IDF 字面重疊)⇒ 拿掉這兩個節點可省約 3 s。 代價是檢索品質(少了兩個佐證訊號),屬產品取捨,不是我能裁的。

  • C. 不做:接受目前的 10 s。

影響分析

  • 現行 active SDD workflow-discoveryA 屬引擎能力,與 3.9ON_TRUEON_FALSE 走邊)同一塊, 是新增任務,不作廢任何既有任務。
  • B 只動 arcrun-rag/workflows/rag-chat.local.yaml,不碰本 repo。
  • 三者都不影響已完成的 3.12recipe 三層)與本次 Workers AI 換源。

⏸ 停在這裡等 leo 裁:回「A」我就先寫測試再改引擎;回「B」我只改 workflow;回「C」就記著不做。

P1|host fn 二進位通道(解開「零件無法處理非文字檔」的框架級限制)— 2026-07-27

觸發leo 07-27 原話(arcrun-rag t73 收尾時)——

解析各種檔案的零件還是要開發的,要記下來,雖然跟現在無關, 是因為這次我用他本機來跑閃掉了。」

現況=框架級硬牆(2026-07-27 實測,非推論) Arcrun 的 host function 邊界是 UTF-8 文字通道 64 KB 上限 outBuf 64KBres.text()host fn 內 TextDecoder)。後果:

  1. 零件拿不到二進位 ⇒ PDF/docx/圖片這類檔案,做不出解析零件
  2. 雲端 workflow 的 fetch_raw 走同一顆 http_request ⇒ 同樣拿不到。
  3. 連純文字都受 64KB 限:15 頁 PDF 抽出約 40KB 尚可,25 頁以上會爆 =「轉好了卻進不去」的靜默失敗。

arcrun-rag 目前怎麼過關的(要講清楚,免得被誤會已解決) 把轉檔搬到 daemon 本機collector/convert.go 調度層+PDFium-via-wazero)—— 這是繞過(work around),不是修好。leo 的原話「用他本機來跑閃掉了」講的就是這件事。

為什麼仍要做(不擋當前工作,但別遺忘)

  • 能力分裂:現在只有「裝了 daemon 的人」有轉檔能力;純雲端用戶永遠沒有
  • 地端/雲端兩版格式支援會分岔,長期維護兩套。
  • 64KB 上限是既有限制,.md 今天就會撞到,PDF 只是讓它更快浮現。

變更範圍(提案,待 leo confirm 才動) ① host fn 加二進位/base64 通道(或 ArrayBuffer 傳遞) ② 放大或分塊化 outBuf(串流/分頁讀取,避免單次 64KB 天花板) ③ 之上才談「各格式解析零件」

影響分析

  • 不受影響:現行 active SDD portal-auth 的所有任務(不同層)。
  • 不擋arcrun-rag t73 本機轉檔層照做(已 commit 74d18ff)。
  • 牽動http_request 零件、code 零件的 host fn 契約 ⇒ 屬全人共用框架改動, 影響所有既有零件,必須 leo 拍板(跨專案結構決策)。

現在不做的理由:leo 明說「跟現在無關」+客戶在等 daemon;本條僅立案留底, 避免「本機能跑了」被後人誤讀成「這個限制已解決」。

已裁決

confirmed 2026-07-24CP2-F cypher 二~四刀拆分(leo 授權總管技術裁決)

裁決依據leo 2026-07-24 原話「不影響現在 CP 的話就排下一個,這個你是需要判斷的,不能是我,完全技術問題」。 總管裁決confirm。排程=A4 全通+t21/t24 合併重部之後(與在途不撞)。 四題:①開工時點=同上 ②刀④驗證=手寫(瘦身工程不再引依賴;兩鏈手寫+測試)③新 worker 命名=arcrun-api ④CP2-F 記載更正已由總管代辦。 開工時照 D35 ④ 先開新 SDD 搬任務再寫 code。

P-2026-07-24CP2-F 第二~四刀——執行引擎獨立成精簡 worker(cypher 瘦身收官)

提案人:總管交辦之 arcrun 偵察 subagent(唯讀分析,未動 code、未部署)。 觸發:頂層 CRITICAL-PATH.md CP2-Fw=9P3)——「免費起步」承諾不成立; leo 定調:workflow 執行引擎獨立成精簡 worker(只做調度),console/portal/credentials/webhooks 拆出去。 依 D35:現行 active SDDportal-auth,與本題不同卷,故只寫 proposal 停下等 confirm,不動 code。

0. 先更正頂層 CP2-F 的過時記載(本次實測核實)

項目 CP2-F 記載 2026-07-24 實測 出入原因
原始碼行數 15,446 行 11,050 行find src -name '*.ts' | xargs wc -l 第一刀已砍
bundle 748KB 528.1KB540,742 byteswrangler deploy --dry-run --outdir 實跑) 同上
「ingest 必爆」 隱含現在式 已穩定(第一刀驗收:連灌 10 張全過、同卡 6 連跑全過) 5a16484 已修
/health 5-7ms、9ms/節點 現在式 拆分前舊數,第一刀後未重測——本提案每刀驗法含重測 未更新

第一刀=commit 5a1648407-21):console.ts(1623行)portal-ui.ts(1390行) 搬去 console-ui/ CF Pages arcrun-console-ui.pages.dev),748→528KB-29%)。07-22 ad367e4 補 console-ui build 修復+ deploy.targets.json 具名部署目標(personal/enterprise 兩 profile,帳號+apiBase+專案名收一檔)。 → CP2-F 條目該由總管在頂層更新為「第一刀 、二~四刀待裁」,狀態從 斷改 ◐ 半通。

1. Bundle 實測解剖(528.1KBsourcemap byte 級歸因,非推測)

方法:npx wrangler deploy --dry-run --outdir=<scratch> 產 index.jsindex.js.map → 自寫 VLQ 解碼器把每個 byte 歸因到原始檔(mapped 507.5KBbundler glue 20.5KB)。

模組 KB 佔比 主要檔案(行數) 去向提議
dep: zod 130.6 24.7% 只被 lib/schemas.tslib/prompt-recipe-schema.ts import 刀④逐出引擎
dep: hono 76.9 14.6% 框架 兩邊都要,留
執行引擎核心 74.3 14.1% graph-executor(702)、component-loader(370)、wasi-shim(674)、execute/executions/resume/cypher routes 留(引擎本體)
Credentials/Auth 48.0 9.1% auth.ts(467)、credentials.ts(322)、auth-dispatcher(301)、auth-recipe-seeds(748行/21.9KB) CRUDseeds 搬;dispatcher 讀路徑留
PortalRAG 多人) 42.3 8.0% portal.ts(783)、portal-data.ts(457)、portal-auth、portal-seeds 刀②搬
Console API 31.8 6.0% console-dashboard(526)、console-auth(165)、兩 model(616) 刀②搬
dep: unenv/polyfill 29.1 5.5% nodejs_compat 代價 留(兩邊皆有)
Webhooks CRUD 25.6 4.8% webhooks-named(521)含觸發+管理混一檔 拆檔trigger/query 留、CRUD 搬
Recipes CRUD/seeds 24.1 4.6% recipes.ts(563)、api-recipe-seeds、init-seed CRUD/seeds 搬;resolveRecipe 讀路徑留
Docs/OpenAPI 12.5 2.4% openapi.ts(306) 刀③搬
KBDB proxy 8.4 1.6% kbdb-proxy.ts(272) 刀②搬
scheduled/cron 3.7 0.7% scheduled.ts、cron-* 留(觸發面)

三個關鍵事實

  • zod 一家=24.7%,卻只服務「入口驗證」兩條鏈(execute→schemas、recipe-loader→prompt-recipe-schema)。
  • 引擎真身(核心+hono+unenv)只要 ~180KB;其餘 ~350KB 全是管理/前端 API 面。
  • 耦合點:graph-executor.ts:6 import resolveRecipe from routes/recipes.ts:406—— 讀路徑長在 CRUD 路由檔裡,拆分前要先抽到 lib(刀②-0 前置小步)。

2. 拆分方案(Option A:引擎留原地,管理面搬出——推薦)

為什麼引擎留在 cypher-executor 原 worker 不搬家webhook 觸發 URL /webhooks/:token/trigger/webhooks/named/:ns/:name/trigger/q/:ns/:name 被外部 callerTelegram webhook、Routine、CLI、MCP)焊死;引擎留原地=外部零改動。 反向(引擎搬新 worker)要全網改 URL,風險大得多,不採。

佈局:既有 25 顆(22 零件+cypherkbdbmcp)→ 26 顆:新增 1 顆 arcrun-api(管理/控制面 TS worker)。 arcrun-api 是框架自身的 API 面、非業務零件,與零件須 WASM 的鐵律不衝突——cypher 本身同理。)

端點群 去向
/execute/cypher/*/validate(刀④前)、/resume/executions/*/workflows/:name/executions、webhook trigger/query/health、scheduled cron cypher-executor(引擎)留
/portal/*/portal/data/*/console/*/kbdb/*proxy)、/credentials/*/auth/* CRUD、/recipes/* CRUD、/webhooks CRUDnamed 管理(backfill/migrate/delete/list)、/init-seed/docsOpenAPI arcrun-api(新)搬

Service binding 過渡(13 顆 SVC_* 懶載現況):零風險——13 個 binding 服務的是 component-loader.ts:73-85 LOGIC_BINDING_MAP 的邏輯零件調度,全屬引擎;引擎不搬家= wrangler.toml [[services]] 原封不動。arcrun-api 完全不需要 SVC binding。 未配置時 fallback 公網 workers.dev 的既有機制(component-loader.ts:249-272)也不動。 self-hosted 的 deploy.ts 注入機制(D1 database_id 等)需對 arcrun-api 的 toml 複用同款注入——既有機制,非新開發。

與 07-22 第一刀銜接console-ui Pages 的 ARCRUN_API_BASE(build 期參數)刀②時改指 arcrun-apideploy.targets.json 兩 profile 各加一欄,部署命令不變。

刀法(分三刀,每刀獨立可回退)

  • 刀②(先抽 resolveRecipe 到 libPortalConsole APIkbdb-proxy 搬 arcrun-api。 預估 -82.5KB → 引擎 ~446KB。console-ui apiBase 同步切。
  • 刀③credentials/auth CRUDwebhooks 管理面(先把 webhooks-named.ts 拆成 trigger/管理兩檔)+ recipes CRUDinit-seed(含兩包 seeds 30KB)+docs/openapi 搬過去。預估 -90KB → 引擎 ~355KB。
  • 刀④(zod 逐出引擎)/validate 搬 arcrun-apizod 隨行);/execute 入口驗證改手寫窄驗證 graph shape 檢查 ~50 行)或換 valibot~10KB);prompt-recipe-schema 同款處理。 預估 -130KB → 引擎 ~200-225KB(對 528KB 減 ~60%

目標與誠實邊界/health <2ms 主要靠 bundle 縮(冷啟 parse+常駐面縮)可期; 但單節點 10ms 內不保證光靠瘦身達標——9ms/節點若主要來自 per-node KV put graph-executor.ts:352 每節點 kvSetNodeOutput)+JSON 序列化,則需刀④.5(備案) node output 改「僅斷點/暫停時寫 KV、其餘記憶體傳遞」。是否需要動,以刀②後的 cpuTime 實測決定,不預先動。

3. 每刀驗法(免費層 cpuTime 實測法)

每刀收工四件、缺一不算完成(守 CP 使用規則 6/7):

  1. wrangler deploy --dry-run bundle size 對照表(貼實跑輸出,驗預估)。
  2. vitest 全綠+tsc 0(現基線:cypher 169/170,唯一失敗=executor「不存在的零件」pre-existing)。
  3. 免費層 cpuTime 實測:部署後 npx wrangler tail arcrun-cypher-executor --format=jsoncpuTime,三個探針各打 10 次取 P50/health、單節點 workflowhttp_request×1)、 km_wiki_ingest6 節點)。記進 CP2-F 條目當證據。
  4. 端到端頭尾驗:console-ui 兩 profile 登入+搜尋(打 arcrun-api)、portal 登入、 acr pushacr run 走引擎、webhook trigger 原 URL 打通(外部 caller 不改的承諾)。

回退:每刀=一個 PRarcrun-api 是加法(新 worker),引擎側只刪路由掛載—— 回退=revert PR+重部引擎(arcrun-api 留著不礙事)。KV/D1 零 schema 變更,無資料遷移,無不可逆步驟。

4. 影響分析(D35 第 3 條)

  • portal-auth(現行 active:P1-P4 已完成待部署排練。刀②把 /portal/* 路由搬 arcrun-api 只搬家不改行為,其測試(portal 三套 56/56)隨檔案搬移後應原樣全綠; 但其「部署清單」要加一行(portal 部署目標從 cypher 變 arcrun-api)。不作廢任何任務
  • 第一刀遺留(5a16484「未做(第二刀)」清單)console-dashboard/portal/portal-data=本提案刀②,正式立案銷帳。
  • library-mapdraftM5 console 首頁區塊打 /kbdb/map——kbdb-proxy 刀②搬家後 console-ui apiBase 同步切,不改功能。
  • P-2026-07-21 registry proposal 的 B1(「在 cypher-executor 開 GET /search」):若兩案都 confirm /search 統一面該開在 arcrun-api 而非引擎(搜尋是管理面不是執行面)——兩案不衝突,落點修一字。
  • 不受影響22 顆零件、kbdb worker、mcp、CLIacr 打的執行端點全留原 URL)、 webhook 外部 caller、13 個 service binding、artifact-sharingconfirmed)各 Phase。
  • 新增維護面(誠實記):多一顆 worker 要部署(官方+self-hosted 各一次); deploy 腳本/文件要加 arcrun-api;兩 worker 共用 KV/D1 binding(同一批 id,讀寫面分離)。

5. 待 leo 拍板點

  1. 開工排序CP 排 P3P1=CP3-A、P1↑=A4 OAuth 在前)。本提案只求 confirm 方案,開工時點照 CP 排序走——除非 leo 要提前。
  2. 刀④驗證庫選擇:手寫窄驗證(零依賴、-130KB 全拿)vs valibot(保留 schema 風格、-120KB)——品味題。
  3. arcrun-api 命名arcrun-api?或併入既有規劃中的其他 worker?(跨 repo 佈局=總管/leo 層決策)
  4. 頂層 CP2-F 條目更正(§0 表)由總管執行——本 repo 只能在此記載,不碰頂層文件。

提案人:總管交辦之 arcrun subagent。 觸發:leo 2026-07-21 —「一旦推進一個零件,就自動進 registryrecipe、workflow、app 都應該可以 registry, 不然搜不到。一邊是寫進去,另一邊是搜到,當然要有。」 判準:「Arcrun = 讓 AI 輕易建立程式碼」「AI 要覺得 Arcrun 比 Python 還簡單,絕不可迷路」。 依 D35:本任務找不到對應的 active SDD(現行 activeportal-auth,與本題無關), 故不動 code、不自建 SDD,寫本 proposal 後停止等 leo confirm。

一句話

registry 的寫入機制存在且可用,但它唯一的自動觸發點長在 GitHub Actions 上; Actions 因防 flag 鐵律被整個刪除後(commit 037cf9b),寫入端失去觸發者、庫從此是空的。 這不是「沒有機制」,是「機制的手被砍掉、沒補上替代觸發點」。

根因(file:line 級)

事實 證據
寫入端點存在 registry/src/routes/components.ts:112 POST /components/index-onlymetadata-only 索引,冪等)
寫入實作存在 registry/src/actions/indexOnlyComponent.ts:44comp:{hash}:{ver} + idx:{canonical_id} 兩個 KV key
批次灌注腳本存在 registry/scripts/backfill-index.mjs(掃 22 個 contract.yaml → POST index-only
單顆註冊腳本存在 registry/scripts/register-component.sh(註解自稱「本地+CI 共用 SSOT」)
唯一自動觸發點已不存在 git show 037cf9b^:.github/workflows/deploy.yml 第 269-275 行有 Register component in registry step 呼叫上述 sh037cf9b 刪除整個 .github/workflows/該 step 隨之消失,無替代品
從未跑過的實證 對 leo21c 跑 REGISTRY_URL=... node scripts/backfill-index.mjs --dry-run → 22 顆待灌;線上 /components/search?q=httpcount:0

答案:是「有機制但從沒跑過」(且失去觸發者),不是「沒有寫入機制」。 → 附帶事實:registry/wrangler.toml:26[[routes]] 寫死 registry.arcrun.dev self-hostedleo21c)只能靠 workers.dev URLbackfill 腳本預設 REGISTRY_URL 也是官方域 —— 需帶環境變數才會打到自己的庫。

重要更正:leo 要的東西有一半已經存在,只是不在 registry 上

acr search <term>cli/src/commands/search.ts)已經是 leo 描述的「意圖驅動、跨類一次搜」—— 它 fan-out 四個來源(component 靜態清單 / /recipes / /auth-recipes / /webhooks/named)。 實測(2026-07-21leo21c,真實輸出見交辦回報)

  • acr search http → 命中零件 http_request(驗收劇本 1
  • acr search notify → 命中 recipe line_notify_send + auth-recipe line_notify(劇本 2 部分達成)
  • acr search github → 命中 auth-recipe github(驗收劇本 3
  • acr search telegram → 命中 recipe telegram_send + auth-recipe telegram

能力在 CLI 有、在 registry/MCP 沒有。這正是薄殼原則(rule 07)被違反的典型: 同一個「跨類搜尋」能力長在介面層(CLI)而非 API,於是另一個薄殼(MCP)享受不到。 修法的方向不是在 registry 重造一套搜尋,而是把 acr search 的 fan-out 能力下沉成 API 端點,CLI/MCP 同吃。

提案內容(四件,全部需 confirm 後才動)

A. 寫入端:補回失去的觸發點(不復活 Actions)

  • A1. acr push / acr deploy 成功後自動呼叫 POST /components/index-only(本機發起、低頻、單 repo,守 D20 讀寫界線與防 flag 鐵律)。
  • A2. acr init / acr update 部署完 22 顆零件後跑一次 backfill(讓新裝的人開箱即有索引)。
  • A3. recipe / workflow 不需要新的 registry 寫入路徑——它們本來就活在 store(KV), acr recipe push / acr push 當下就已「寫進去」。缺的只是搜尋端讀得到(見 B)。 → leo 說的「recipe、workflow、app 都應該可以 registry」,正解是統一搜尋面,不是把它們搬進 registry KV 再存一份(那會製造第二份真相源)。
  • A4. appbundle)已有 P-2026-07-19 artifact-sharing 卷涵蓋,本卷不重複立案,只在搜尋面預留類別。

B. 搜尋端:能力下沉 + 語意

  • B1. 在 cypher-executorGET /search?q=(不是 registry——因為 recipe/workflow 的真相源在 cypher 的 KV), server 端做 acr search 現有的四類 fan-out,回統一結果(含 type 欄位)。
  • B2. acr search 與 MCP 新 tool arcrun_search(或改造 arcrun_search_components)雙雙改為呼叫 B1,介面層不再自行 fan-out(回歸薄殼)。
  • B3. 語意搜尋:KBDB 那條路已驗證可用(Vectorize),把四類的 description 灌進去,讓「我要打一個 HTTP API」這種自然語言句命中 http_request。 現行 registry/src/actions/queryComponents.ts:104 明載「這是 Phase 0 的純文字比對版本,Phase 2 接入 Vectorize」——本項即補完該 Phase 2。
  • B4. 搜不到時的文案改為「導向 recipe / 既有 workflow」,移除「可以用 arcrun_publish_component 提交新零件」的建議(見 C)。

C. 斷掉「推人去寫零件」的路

  • C1. mcp/src/tools/arcrun_search_components.ts:50 搜不到時明文建議 arcrun_publish_component —— 違反 leo 既定規矩(零件走 PR、專業等級)。改為導向 recipe/workflow。
  • C2. arcrun_get_component_guide(回 TinyGo 寫 WASM 教學)與 arcrun_publish_component 對一般使用者是誤導 → 建議降級為「專業模式」才暴露(預設不掛載),或在描述首句明寫「99% 情況你不需要這個,先用 recipe」。
  • C3. 查證結果:零件相關「已拆到另一個 repo」未獲證實——registry/components/ 22 顆零件仍在本 repo, wiki 與 git 均查無拆分紀錄。leo 的印象可能來自 .github-public/ 對外鏡像(GitHub mirror 發佈模型)。此點需 leo 確認

D. 過時項

  • D1. MCP 仍要求已廢的 api_key 參數者共 15 處arcrun_introspection.ts4)、arcrun_recipe.ts6)、arcrun_workflow_crud.ts5)。 2026-07-20 已改 namespace 明碼 → 這些應改為由 server 端 namespace 推導,不再要 AI 傳。
  • D2. 1042 的真正解法已確認並已落地(本項無需修 code,只需更正記載): global_fetch_strictly_public compatibility flag,已實裝於 cypher-executor/wrangler.toml:13.component-builds/http_request/wrangler.toml:8。 leo 說的「開了一個什麼,把所有呼叫都視為外部」=這個 flag(讓 same-zone fetch 走公網前門)。 wiki 已有正確記載:system-dev/wiki/cards/decisions/same-zone-1042用flag解不用binding.mdmistakes.md:101decisions-summary.md:84。 → 「graph_neighbors 改用 recipe 繞過」的過時說法在本 repo wiki 查無此記載status.md:50-52 只寫 MCP tool PR), 該過時記載可能在頂層 InkStoneCo wiki 或 MEMORY.md,需由總管在該層更正。

影響分析(D35 第 3 條要求)

  • 現行 active SDDportal-auth:完全不受影響,本提案不碰其任務。
  • component-registry-canonstatus: paused2026-05-07 建)本題其實早有此卷, 其 §1.2 診斷的根因與今日實測完全一致(「registry 活著但 index 空的,AI 找不到零件就會繞回 Python」), 尚有 29 個未完成任務。→ 建議:不新開 SDD,改為把此卷 resume 成 active(並把 A/B/C/D 的新項增補進其 tasks), 這比另立新卷更符合 D35 第 4 條「先搬移未完成任務」的精神,也避免第二份重疊規格。 ⚠️ 但這需要先把 portal-auth 收尾或轉 paused(單一活性鐵律),此為 leo 的排序決策,不是 CC 能裁的
  • workflow-discoverypaused)/library-mapdraft:與 B1 統一搜尋面高度重疊,resume 時應一併檢視是否合併。

待 leo 拍板的四點

  1. 排序:要不要把 portal-auth 讓位、resume component-registry-canon 來做這件事?(單一活性鐵律強制二選一)
  2. C2get_component_guide / publish_component 要「預設不掛載」還是「留著但改描述」?(品味/方向)
  3. C3:零件是否真的已拆到另一個 repo?(leo 記憶待證實)
  4. B3 語意搜尋:四類描述灌進 Vectorize 會產生 embedding 呼叫成本,確認可行?(花錢)

P-2026-07-19artifact-sharing 增補「Appbundle)+實例譜系+訂閱更新+多源分享」

狀態:confirmed 2026-07-19(leo「好的可走」)。四個拍板點總管採建議值(leo 可翻案):①排序=Phase 1.5 緊接 Phase 1、在 KV 退休(#16/#17)前後皆可並行 ②訂閱預設 policy=notify ③側載標記第一波=列表標記即可 ④P6 第一波=官方源+直連一個外源,org 私區留第二波。tasks 增補見 artifact-sharing/tasks.md「Phase 1.5」段。

提案人:雲端總管(leo 2026-07-19 對話三輪收斂後令「寫」)。 目標 SDD:Leo/Arcrun system-dev/docs/3-specs/arcrun/artifact-sharing/#27+#31)。 依 D35:本檔為規格層 proposal寫入 pending-changes.md 後停下等 leo confirmconfirm 前不動 tasks、不寫 code。

一句話

workflow/recipe/template 的實體在平台(CF/KBDB),不在 YAML——YAML 是隨叫隨到的視圖(搖桿)。 因此版本控制、譜系、更新通知必須是平台內建能力,git 降級為:引擎程式碼的家+人審 diff 面+災備快照。 本提案把 #27 公庫從「單品發布/拉取」補全成「App 商店+訂閱更新+實例譜系」。

背景(為什麼現在)

  • 實證痛點:arcrun-rag(企業)與 Mira(個人)跑同族管線的兩份變體(rag_ingest v2 vs km_wiki_ingest), 「哪邊同步了沒」靠人腦;claude.ai 07-19 實測抓到的三個引擎缺口再證「修一次、兩實例都該自動受益」的通道不存在。
  • T-pack-v2「repo 即真相源」是過渡義肢:因為平台缺版本層(KV 讀不回、無版本、無譜系),才用 git 代位。 義肢照 D15 前例:平台長出器官後拆。
  • 地端版(workerd)將成第三個實例形態——在複雜度上升前把「App×實例×版本」模型立好。

提案內容(五件)

P1. bundle 第四型(App

  • public_artifact 新增 type=bundle。portable_body=成員清單: [{type: workflow|recipe|template, canonical_id, uuid(鎖版) 或 version_policy(track-latest)}] install_params_schema(安裝參數:多人開關、Gitea 端點、LLM provider…)+conformance(見 P5)。
  • 「裝一個 App」=pull 一個 bundle,成員經既有 dependency_manifest 機制解析; 個人版與企業版=同一個 bundle、不同 install params
  • arcrun-rag 為第一個 bundle(現行 install.sh 即其手寫前身,落地時翻譯成 manifest)。

P2. 訂閱與更新通知(可拒、可 pin)

  • install/pull 時建立訂閱關係:新 entry artifact_subscription subscriber namespace、canonical_id、目前安裝 uuid、policy: notify|auto|pin)。 artifact_pull_event 保持純事件帳本不改;訂閱是關係、事件是史料,分開存。)
  • 新版 submit-p 後,訂閱者「得知」的通道查詢式優先 GET /subscriptions/updates(實例/AI/console 隨時問「我有沒有落後」); 推播(notify workflow)為選配、且禁止因發布事件自動 fan-out 到多實例(D4 紅線——通知生成可以批次/排程,不掛事件觸發鏈)。
  • 更新永遠是訂閱端的顯式動作:可更、可拒、可 pin 死版本。

P3. installed_from 譜系+側載標記(隱形工作流可見化)

  • 實例內每個 materialized artifactworkflow/recipe/template)落籍記 {installed_from_uuid, installed_at, content_hash}entry metadata,不建表)。
  • 平台即可回答四態:up_to_date / behind / diverged(本地改過)/ sideloaded(無譜系,API 直建)
  • list/console/MCP 的 workflow 列表帶狀態標記。側載不禁止、只標記Android sideload 哲學); 「沒有 YAML 就不准」的 policy 不採納——對 AI 是降頻,可見性由本條提供。
  • 既有 git 外掛式 drift 稽核(guard 對 hash)為過渡措施,本條落地後退役。

P4. 更新與分岔語意

  • update=拉新版重新 materializeinstalled_from 換新 uuid)。
  • diverged 者不自動覆蓋:提示二選一——fork(submit-p 推回公庫成自己的作者版本,derived_from 記溯源)或捨棄本地改動收新版。
  • 對應 leo 模型:「Mira 和 Arcrun RAG 都 clone 了 rag app,都可以推回去存成新版本,收到更新通知但自己決定要不要更」。

P5. conformance self-check 隨 bundle(驗收矩陣自動化)

  • bundle 附驗收清單:介面×能力的機械檢查(例:portal 登入 200、MCP tools/list 含 kbdb_*graph、 keyword/semantic/graph 三模式各一題 golden question 命中)。
  • install/update 完自動跑、產報告;解「企業 GUI 驗了但企業 MCP/個人 GUI/個人 MCP 不知道、檢查到沒完沒了」—— 可用性從人肉巡邏變安裝產物。地端(workerd)實例=同一張體檢單多跑一列。

P6. registry=源(source)非地方:多源與點對點分享(leo 2026-07-19 追加)

  • 公庫端點長在 cypher-executor每個實例都內建 registry 能力;官方公開市場只是「預設源」。
  • 實例可加多個源:公開市場/org 內部源/另一個實例直連(A 做了 App,B 把 A 加為源直接拉,CF-to-CF,不經公開市場——Homebrew tap 模式)。
  • artifact 加 visibility: public | org | unlisted;外源拉取走既有 token 認證(portal-authMCP OAuth 機制,A 發「可拉取」token 給 B)。
  • P3 落籍擴充:installed_from 記「源+uuid」;P2 訂閱跨源成立(B 訂閱「A 源上的 canonical_id」)。
  • 信譽記分邊界:私下/org 內分享的 pull 事件留在該源帳本,不進公開信譽;日後同 canonical 發布公開市場,溯源保留、私史不折算。
  • 信任判斷仍在 import 端(#27 原則):來源是誰,列表標記說清楚。

P6 鐵律:拉取=落地複本,runtime 零外部依賴(leo 2026-07-19 Drive 之問定形)

  • pull/install=把 artifact(含 dependency_manifest 解析出的全部依賴,跨源亦然)materialize 進本實例 KBDB——複本式分發(npm/App Store),非引用式分享(Google Drive)。
  • 源斷線/停止分享=只失去更新,已裝的照跑;狀態標 source_lost。互相參照在安裝時全落地,runtime 永不回頭找源;只有「查更新」動作碰源。
  • 多源不亂的機制:裝完面對的是一張本地清單(每項帶源+五態標記);同 canonical_id 跨源衝突=安裝時顯式選源,不靜默合併;bundle 鎖版 uuidlockfile 對應物。

排序定調:分享先行、投稿後行(leo 2026-07-19 收斂)

  • 官方的本質=第一個策展人(leo 定調):官方源不是特權角色,就是「把很多資源收集起來分享給大家的人」;公開市場=分享機制+官方獎勵制度(信譽層)疊上去,作為分享落地後的下一件事。
  • 先做:P6 最小版(官方源+直連外源)+P1+P3 → 這就是產品自己的部署通道(leo 官方源→客戶實例拉 arcrun-rag bundle;第一組 A/Bleo 與第一個客戶、以及 Mira);再 P2 訂閱更新。
  • 後開:公開投稿+信譽榜——空市場掛榜=鬼城,等 self-hosted 用戶密度夠再開(社群玩法)。
  • 零代價保證:#31「事件是真相、統計是視圖」——pull/submission 事件 day-one append,信譽晚開也能從頭算,先分享不欠投稿任何債。

附:獎勵/信譽(確認既有設計,非新增)

  • 「貢獻 recipe 得 reputation」=#31 作者信譽經濟已設計(作者頁/聚合信譽/選版複合分/獎勵層預留、author 綁認證身份);事件 day-one append 保證信譽可事後計算。
  • 本提案只補一句:bundleApp)作者同樣累積信譽——組裝 App 與寫 recipe 同屬貢獻。

影響分析

  • 不建表:全部走 entry_typemetadata_jsonD6 鐵律);artifact_subscription/落籍 metadata 皆 template/slot 層。
  • 與 Phase 1 關係:不改既有 1.1–1.6 任務;本提案為 Phase 1.5bundle/lineage/subscription 建在單品公庫之上)。 1.5 的 recipe KV 過渡(#16)不受影響。
  • 與 D4 flag 鐵律:通知採查詢式優先、禁事件 fan-out(見 P2),無 GitHub 流量、無 Actions。
  • 與現行 installer:過渡期 install.sh 續用;第一步可先讓 installer 代寫 installed_from 落籍(義肢幫器官接生), 公庫端點好了再切換 pull 路徑——遷移平滑、無一次性大爆改。
  • 受益者:Mira 跟上企業版=「訂閱同一個 bundle 按更新」;未來 N 個客戶實例同此通道;地端版=第三個實例非第三套系統。
  • 風險:scope 擴張(#27 尚未動工就加型)——緩解:P1/P3 是最小核(bundle 形狀+落籍欄位), P2 通知與 P5 self-check 可各自獨立分批落地;全部 compute-on-read 起步,物化快照沿用 #31 判準。

待 leo 拍板點

  1. Phase 1.5 排序:在 Portal#24/#25 已收官)之後、KV 退休(#16/#17)之前或之後?
  2. 訂閱 policy 預設值:notify(通知不動手)?
  3. 側載標記的呈現強度:只列表標記,或 console 加「無譜系 workflow」提醒區塊?
  4. P6 多源第一波範圍:只做「官方源+直連一個外源」?org 私區(visibility=org)是否留第二波?

[proposal] 兩個真缺口要進 SDD2026-07-30,總管提,等 leo confirm

來源:頂層 CP critical-paths/arcrun-usable.mdleo confirm 開工)逐步查證後, 發現兩件事SDD 完全沒有,而它們是「AI 不必寫 code」的前提。

leo 的判準(2026-07-30):

「如果在這裡編任務,不就是廢掉了原本的 SDD,那到底要照 SDD 做事還是照 CP?」 ⇒ 照 SDD 做事、照 CP 排順序。CP 不得自帶任務 ⇒ 這兩件必須進 SDD 才能做。

缺口 ①:引擎缺條件邊(ON_TRUEON_FALSE)→ 建議進 arcrun-core-mvp

  • 實測if_control 的 output 是 {result: boolean, branch: "true"|"false"}cypher-executor/src 全域 grep ON_TRUE|ON_FALSE = 0(圖的邊只有 ON_SUCCESS
  • 後果AI 照規矩用 if_control 也只拿到布林值,還是得寫 code 判斷該走哪裡 ⇒ 這是「為什麼 workflow 全變成 code」的根(8 個 code 節點含 if×61
  • 佐證kbdb_upsert_block 契約自述「解 arcrun workflow 缺 IF/branch 能力的缺口 arcrun.md P1 #1)」;Gitea Arcrun#5「if_control 無法真擋分支,filter+FOREACH 才是真閘」 於 2026-07-04 就發現,至今未修
  • SDD 查證grep "ON_TRUE|ON_FALSE|條件邊|分支" 於全部 SDD → 7 命中全是別義 (「部署分支」「git 分支」),條件邊本身完全沒設計過
  • 影響面:改圖 schema graph-executor 走邊邏輯=引擎核心,風險最高 ⇒ 建議排在「查詢誠實」「節點替換」驗過之後

缺口 ②:recipe 缺 payload 與回應處理層 → 建議進 recipe-system

  • 實測recipe schema 只有 {canonical_id, endpoint, method, auth_service} (線上 GET /recipes/telegram_send 實查)
  • 後果telegram_send 的 description 明寫「body 帶 chat_id+text」但schema 存不住 body ⇒ 任何要帶 body 的 API 都只能繞過 recipe、把 URL/header/body 整包寫進 workflow ⇒ Gemini 就是這樣寫死的(ask_llm 三層全塌進節點)
  • 要補三層
    • body_templatepayload
    • response_map(回應正規化:取值路徑/思考型模型旗標/淨化規則) ——現在這段是 workflow 裡 2786 字元的 codefinalize
    • auth 加第四型 binding(免金鑰;一次打開 env.AIVECTORIZEBROWSERQUEUE
  • SDD 查證grep "body_template|response_map|payload" → 17 命中全是別的 payload
  • 不做的話LLM 換源永遠要改 workflow(而非換 recipe),違反「LLM 可換源」原則

誤標修正(誠實記錄)

總管原本在 CP 標了 5 個新缺口,逐條查 SDD 後只有上述 2 個是真的

  • success_rate 回寫 → arcrun-core-mvp/design.md:499 早就設計 success_rate = success_runs / total_runs * 100、排序規則、UI 顯示),只是沒實作
  • 8 個壞範例、意圖節點替換 → 相關設計散在既有 SDD,已改為引用

⏸ 等 leo confirm

  • confirm 後依 D35:兩份 SDD 目前皆 paused,要動需先處理單一活性 (現行 active=workflow-discovery

提案:workflow export/import 一等公民化(2026-07-31,總管代 leo 口頭定調立案)

  • 來源leo 07-31 原話(見 workflow-discovery tasks.md 3.9 引文)——分享 workflow 給同事的正路=export 檔→import,不是「用 search 湊」。
  • 變更面:① cypher GET /webhooks/named/:name/definition(已實作,staging 試點中, 零新資料模型/同 list 認證)② acr workflow export <name>acr workflow import <file> 新 CLI 命令(已寫未接線)③ 安裝器 workflows.jsonexport 檔同形狀(graph 預編,已上 prod)。
  • 不動的牆KBDB 零接觸(export 讀 WEBHOOKS KV workflow recordimport 打既有 POST /webhooks/named);「部署≠發現」(import 不驗零件存在,執行時現形); description 必填閘照舊。
  • 影響分析:新公開端點 1 個(租戶 key 認證,吐的是該租戶自己部署的 workflow 定義; 無跨租戶讀);CLI 新命令 2 個(薄殼,能力全在既有 API);無 schema migration、無新金鑰面。
  • 狀態 待 leo confirm 後 3.9b 接線。

提案:Arcrun App ↔ Portal 掛載協定 v02026-08-09Leo/Arcrun#82

  • 設計全文住在票上,本檔只留指針leo 08-09 立:設計寫在 issue 上,別讓下一個人再翻一次源碼) → Leo/Arcrun#82 的「設計提案:Arcrun App ↔ Portal 掛載協定 v0」留言。
  • 觸發:leo 08-09——「要變成是一個 Arcrun App,含前端、template、slots 的設置,任何人可以 安裝後他的 Arcrun 就跳出筆記功能」+「Mira 的那些功能萃取都要變成可安裝」+追加指示 「等你搞清楚 Mira 的功能時直接改成 App 模式,不要分兩段,不然開發好了又要一次遷移」。
  • 病根(實查)Portal 是單檔 HTML,「有哪些頁」在 console-ui/public/portal/index.html 裡寫了四遍(側欄 :253-259tab :510-516VIEWS :718allowedViews :721-729);出貨時整包 內嵌成單檔 worker(build-ui-bundle.mjs:154),安裝器只會「整顆換掉」、無任何掛載點概念。 ⇒ 加一個能力=改核心+重出 release。Leo/mira#2 那批能力若照現況搬,就是逐個焊死。
  • 變更面:① KBDB seed 一列 arcrun_app template(零新表,加進 lib/portal-seeds.ts:21/portal/sessionroutes/portal.ts:495-515)多回唯讀 apps ③ 新增泛用端點 POST /portal/apps/:id/actions/:nameserver 側代打既有 named webhook, 金鑰不外流,形狀同既有 /portal/data/upload,但泛用 ④ Portal 一次性泛用 loader(約 60 行)⑤ acr app build|install|remove|listarcrun-app.yaml 的 JSON Schemarepo 目前無「可安裝單位」schema,這是第一份)。
  • 不動的牆KBDB 零 SQL、永不加表;App 前端不進 arcrun-rag-ui bundle、不進 bundle-components.mjs(否則回到「改核心才能加能力」);App 拿不到 session token 與租戶字串,資料一律走既有 /portal/data/* 的 owner_idlibrary enforce App 自帶 workflow 必須自帶預編圖(冷實例即時編圖 25.7s > 15s timeout 的既有教訓)。
  • 影響分析:現行 active SDDworkflow-discovery,本提案不作廢它任何任務,屬新增一卷; 新公開端點 1 個(portal session 認證);新 template 1 列;無 schema migration、無新金鑰面; 既有 /portal/data/upload 可事後收編成一個 App,不必第一天做。
  • ⏸ 等 leo 裁的兩題(票上 §七):① App 前端跑 Portal originES module)還是 iframe ——短期 App 是否都由我們自己寫?② v0 只開 nav 一個掛載點夠不夠?
  • 狀態 待 confirm。沒 confirm 前照現行 SDD 走,不開新 SDD、不動功能程式碼。