Files
Arcrun/system-dev/docs/3-specs/workflow-discovery/tasks.md
uncle6me-web 5783420fcf 併 feat/harness-content-refresh:install-harness 升現世代+世代閘
leo 2026-08-05:「Arcrun 是它的父層,這裏的問題也影響 Arcrun RAG」。

main 的 cli/harness/ 停在 06-15,分支是 07-31 的升級(676 行實質改動):
· cli/scripts/check-harness-generation.mjs(130 行)=**世代閘**——
  與今天救回的 build-bundles 落後閘同族,都是防「發舊版給用戶」
· cli/scripts/build-harness-skill.mjs(64 行)
· CLAUDE.block.md/commands/arcrun.md/hooks/arcrun-guard.sh 交付內容升級

自動合併零衝突。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 13:35:56 +08:00

22 KiB
Raw Permalink Blame History

workflow-discovery — Tasks

狀態:方向待確認,尚未實作(全部 [ ])。確認後才動 code。 對應 design.mdtasks.md 是唯一進度來源,每完成一個立刻標 [x],不批次。 建立:2026-06-27issue #8


Phase 0:方向確認(前置,擋住所有實作)

  • 0.1 SDD 三件式回報到 issue #8 comment,列關鍵決策(方案 C 雙寫 / YAML description 為準 / 提示式回填)
  • 0.2 等總管/richblack 點頭;拍板 design §9 的 4 個待決點 — leo 2026-06-27 全拍定,Q2 翻案(CC 據實生成 vs 介面層不生成)已吸收進 design §3.2
  • 0.3 實作前核實 /entries/search 是否支援 entry_type filter — 總管查證:不支援(只有 q/owner_id/source/mode),schema 有欄位+索引,要改 4 處(route/searchEntries/semanticSearch/kbdb-proxy),做 base 通用 filter

Phase 1:強制 descriptionR1,Q2 定案:CC 據實生成、用戶可改)

  • 1.1 cypher POST /webhooks/nameddescription 改必填,trim 後空 → 400 + 可操作錯誤訊息(定位:要求操盤 CC 據實寫一句「能做什麼」,非逼用戶手填、非介面層機械塞)— webhooks-named.ts 加驗證,tsc 綠
  • [⏸] 1.2/1.3 MCP deploy 改走 /webhooks/named(方向①,leo 拍定)— 卡在 ①-a/b/c 子決策design §3.1b/c):實作期發現 /webhooks/named 吃 graph 非 YAMLYAML→graph 編排現在寫在 CLI push.ts 介面層;MCP 複製=違 rule 07。等總管定 ①-a(複製)/①-b(編排下沉新 /workflows/deploy 吃 YAMLCLI 也改用)/①-c(先 a 通、b 另開 issue)。:無論哪個,MCP 最終打 /webhooks/named(已強制 description1.1 完成)→ description 強制目標三選項都達成。
  • 1.3b(方向①前置,三選項共需)GET /webhooks/named 補回 description/created_at/cron_expr 欄位,讓 MCP list 改讀本端點時欄位齊 — webhooks-named.tstsc 綠
  • 1.4 驗證:兩條路徑各跑一次「無 description 部署」→ 都被擋(端到端,非只 tsc)— CLI 路徑已可驗,MCP 待 ①-a/b/c 收

Phase 2:可搜 entry 雙寫(R2 資料層)

  • 2.1 cypher 部署 handlerrecord 寫完後雙寫一個 entry_type=workflow entrycontent=description、metadata_json.embed:true、owner_id=apiKey),waitUntil 非阻塞 — webhooks-named.ts 加 writeWorkflowSearchEntry helper(注意:KBDB 用 metadata_json 字串非 metadata 物件)。tsc 綠
  • 2.2 補 KBDB /entries/searchentry_type filterbase 通用,不寫死 workflow)— 改 4 處:searchEntries(entry-crud.ts) + semanticSearch(embed.tsentry_type 已 index) + route(entries.ts) + cypher kbdb-proxy /kbdb/search 透傳。kbdb+cypher tsc 綠
  • 2.3 驗證:部署一個帶 description 的 workflow → KBDB 查得到對應 entryowner_id 正確)

Phase 3search_workflow 工具(R2 介面層)

  • 3.1 cypher 新增 GET /workflows/search?q=&mode=:轉發 KBDB /entries/search(限 entry_type=workflow + 本租戶 owner_id,預設 mode=semantic 自動降級)— webhooks-named.ts。tsc 綠
  • 3.2 MCP 新增 u6u_search_workflows(query):呼叫 3.1,格式化結果,透傳 capability_hint(AI 看到可主動問用戶開 Vectorize)— 新檔 + registry 註冊。tsc 綠
  • 3.3 驗證 mode=keywordVectorize 未開):LIKE 命中 + 回 capability_hint「叫 CC 幫你開語義查詢」
  • 3.4 驗證 mode=semanticVectorize 開,需 self-hosted leo21c):語意命中,限本租戶
  • 3.5 租戶隔離驗證:A 租戶搜不到 B 租戶的 workflowcount=0

Phase 4:既有工作流回填(R3

  • 4.1 cypher POST /workflows/backfill-search-entries(限本租戶):有 description 的 record → 補寫 entry;無 description 的 → 列出回報,不自動編造 — webhooks-named.tstsc 綠
  • 4.2 backfill 經 CLI/MCP 暴露為主動指令(非 cron,守 C2)
  • 4.3 驗證:對既有 workflow 跑 backfill → 有 desc 的可搜、無 desc 的被正確列出待補

Phase 5:薄殼對稱補(R2.5,次階段,可獨立驗收)

  • 5.1 CLI acr workflow search <query>:對等 MCP 工具(同一 cypher 端點)
  • 5.2 驗證:CLI/MCP 同 query 回同一組結果(底層同端點,差異只來自介面慣例)

Phase 6:收尾

  • 6.1 tsc 全綠(cypher / mcp / cli / kbdb 受影響者)
  • 6.2 部署 + 端到端實證(leo21c 帳號跑強制填 + 搜尋 + 回填,收客觀證據非自報)
  • 6.3 issue #8 comment 回報端到端綠燈證據;由實證決定結案時機(待端到端綠才 close)
  • 6.4 同步更新 design.md(若實作中發現偏差)+ wiki status

3.x 追加(2026-07-31,頂層總管交棒;出處=leo 定義步驟 3 考題)

leo:「你要找的 Google Slides API 我沒有,你可以自己做。有 2 種: 一種是要一個零件(如 Crypto)但沒有→用 PR 產生; 另一種是要一個 recipe(如 Google Slides)但沒有→自己寫 recipe。」 機械考題已在頂層 arcrun-usable/verify.sh 03 組(aes_encryptgoogle_slides_create 兩題, 現對實例跑全紅=正確標記)。行為綠過才准佔用 arm 部署(頂層 mistakes 07-31 條)。

  • 3.6 recipe 納入 /cypher/search 存在性查詢(現只查零件 registry ⇒ 說不出「某 recipe 沒有」) — 2026-07-31 search-nodes.tsregistry 落空後查 RECIPES KVresolveRecipe), recipe found 附 source:'recipe'+description+endpoint;本地實測 telegram_send found ✓
  • 3.7 缺件回應分型指路:suggestion 欄——計算原語型→「投稿零件 PR」;外部 API 型→「自己寫 recipe」 (欄位契約定案時同步頂層 verify.sh 03 組的 grep 且每筆要帶「去哪裡看」leo 07-31 三次定調):component 路→skill add_new_wasm_component (已存在、安裝器現會 seed 進新實例);recipe 路→skill write_recipe不存在,見 3.8 — 2026-07-31 完成:status 契約定 not_found(同 verify.sh 01/03 grep);分型=服務詞/計算詞 簡單規則(不接 LLM,規則在 code 註解);附 similar_components/similar_recipes 相近候選 (自然語言「判斷有沒有新資料」媒合到 if_control)。順手修二病灶:①頭節點被 resolveNodeRole 判 Input 而免查(aes_encrypt >> … >> code 假 found)→ 只有字面 input/output 名才短路; ② registry 查詢層把 KV 裡的 input_schema 丟掉 → 補透傳。本地 wrangler dev 跑頂層 verify.sh 0103 組 9/9 全綠(部署後要對真實例重驗)
  • 3.8 寫 write_recipe skillregistry/skills/)——「怎麼寫 recipe」的 playbook 目前是空地, 3.7 的 recipe 指路沒有目的地;寫完納入安裝器 seed 清單(compile-skills.mjs 自動收) — 2026-07-31 完成:內容從真 code 反推(RecipeDefinition schemaapi-recipe-seeds 的 telegram_send+gmail_send 真範例/auth-recipes 必填欄位/acr recipe push 打通檢查), 比照 write_intent_workflow 風格;INDEX.mdwrite_intent_workflow.md 同步指路 not_found
  • 設計基調(leo 07-31 二次定調):回覆的重點是「缺哪些」不是「有哪些」—— 有的照常編圖不必報告;缺的要兩庫(零件+recipe)都搜過後點名+給正確指示。 驗收兩層:機械(verify 01/03)綠 → haiku 真考(只讀回覆就能說出缺什麼、該做什麼)。

3.9 追加(2026-07-31 深夜,t158 後續;leo 定調 export/import 原語)

leo:「你要做的就是一個叫 export,另一個是 import,打包好的幾個工作流準備好直接 import 就好了。現在如果我要把我做的工作流分享給同事,我要怎麼 export?他要如何 import?是缺了功能用 search 來湊嗎?在從前就是寫成幾個 yaml 丟過去讓新的送進 KBDB 不是嗎?」+「絕對不能違背原來的堅持(不能違規)」。

  • 3.9a GET /webhooks/named/:name/definitionexport 引擎端):吐 workflow record 原樣(graphconfigdescription)——與既有 list 同認證(X-Arcrun-API-Key)、 同租戶 key 前綴,零新資料模型。062757f 已入 staging bundle 試點。 KBDB 牆自證:讀的是 WEBHOOKS KVworkflow 記錄),不碰 KBDB。

  • 3.9b acr workflow export/import CLI 接線(命令已寫 cli/commands/workflow.ts 未接進 index.ts——D35 ③:新命令面屬規格層,已走 pending-changes 提案, confirm 後才接)。importgraph 直 POST /webhooks/named(既有部署端點, 零編圖零 search);手寫 yaml 指去 acr push。

  • 3.9c 安裝器同一條路驗證:workflows.json 打包期預編 graph+純上傳(rag-installer 5a6539d 已上 prod)——安裝器不走私有路徑的機械檢查(copy-contract 級)留此收。

  • 3.10 意圖節點→真實零件/recipe 替換(CP arcrun-usable 步驟 4;頂層交棒 t159 — 2026-07-31 search-nodes.ts trySubstitutiondiscover 混搜兩庫 exact 落空後, 在 t158「一次抓好的兩庫清單」記憶體內媒合(零新增 round-trip)。兩條保守規則 (不接 LLM,規則在 code 註解):A 服務詞→recipe(名字裡全部服務詞命中同一 recipe 且唯一才換;「google_slides_create」不會被 google_sheets 誤吃);B 強欄位斷詞→零件 canonical/display/aliases 強命中×10description/tags 弱命中,需至少一強命中且 分數唯一最高;「aes_encrypt」無強命中不換)。換到=status resolvedsubstitution 欄(from/componentId/recipe/reason),cypher 圖節點直接帶真實 componentId、不列 missing;換不到照舊 not_found3.7 指路+候選。只動 discover——compile(部署/ 推送複製路徑)零替換零查詢(t158 邊界不動)。 驗(本地 wrangler devregistry 種 20 合約+/init/seed 10 recipe): 「判斷有沒有新資料 >> ON_SUCCESS >> 傳到 telegram」→ if_controlresolved)+ telegram_sendresolvedsubstitution.componentId=http_request)=feature 06 驗法過; 機械考 27/27 全綠(01 組 503 組 4 迴歸+06 組 8target 8compile 迴歸 2); 冷啟第一發 94ms、熱 8–13mst158 病史對照:舊 25.7s

  • 3.10 /cypher/searchtarget 指定搜尋對象(leo 07-31:「難道我不能指定要搜尋 工作流或節點或 recipe 嗎?」)— componentrecipeworkflow tripletstarget=component|recipe=只查該庫;querytarget=名字搜尋,各走既有 機制不新造(component→registry /components/searchMCP arcrun_search_components 同一條路;recipe→私庫 RECIPES KV 同 discover 第二庫讀法,回應註明公庫走 arcrun_recipe_searchworkflow→新抽 lib/workflow-search.tsGET /workflows/search 與 target=workflow 共用同一 KBDB 轉發=MCP arcrun_search_workflows 同一條路)。 防呆:mode=compiletarget → 400target=workflow 吃 query 不吃 triplets400 指路); 非法 target → 400。已知缺口如實透傳:workflow 無 description 搜不到(capability_hint 照舊),補救仍走 /workflows/backfill-search-entries。 MCP 三分型工具盤點:search_componentssearch_workflowsrecipe_search 均註冊活著; 前兩者與 target 走同一條路;recipe_search 搜公庫 vs target=recipe 搜私庫=語料不同 是設計(installed vs marketplace),回應互相指路,非行為漂移

  • 3.11 acr install-harness 交付內容升級到現世代(CP arcrun-usable 步驟 1 最後一筆; 頂層交棒)— 管道本來就好的,過時的是內容cli/harness/skills/arcrun-mindset/SKILL.md 4066Bgrep「意圖」「>>」=0 命中,只講世界觀/別寫 Python, 新裝封測者拿不到步驟 1 的核心教材(>> 意圖語法)。 - 單一真相源harness skill 改為建置期由 registry/skills/write_intent_workflow.md 複製cli/scripts/build-harness-skill.mjsheadregistry 正文+tail 三段拼接)。 選建置期複製而非 symlink/npm 引用:npm files 只收 harness/registry 不進套件; symlink 在 npm pack 與 Windows 不可靠。產物 commit 進 reponpm 裝的是產物,不跑 build)。 head/tail 為 harness 專屬(CLI 語境入口/acr 指令表/暴露同意/誠實鐵律), install-harnesscopyTree 跳過 .head.tail 不鋪給用戶。 - 其餘三件同步升級CLAUDE.block.md(補 >> 意圖語法+not_found 兩條路+ 零件 vs recipe 分型+腹語術紅線+金鑰只拿名字);commands/arcrun.md(步驟改成 「先寫意圖→丟去查→再寫 YAML」,補 acr searchacr validate); hooks/arcrun-guard.sh正路提示改為指向 arcrun-mindset Skill +意圖語法 呼應「hook 沒提 skill 反而把 AI 導向 repo 文件」的教訓;新增 code 節點腹語術提醒, settings.fragment 補 Write|Edit|MultiEdit matcher)。 - 世代閘(防再度脫節):cli/scripts/check-harness-generation.mjs 檢查四件交付物的 現世代指紋(>>ON_SUCCESS對每個not_found/腹語術/arcrun-mindset), 缺指紋 exit 1;掛進 npm run build(故 prepublishOnly 也擋)。 反向驗證:把 skillCLAUDE.block 換回上一代 → 兩者都被擋下並逐條點名缺哪個指紋。 - 驗收(考生 haiku/受測物=環境):乾淨臨時目錄跑 acr install-harness → 四件鋪好、重跑冪等(全檔 md5 不變、CLAUDE.md 66 行不變、hooks 條目 2 不變、 arcrun 區塊仍 1 個);haiku 只讀該目錄的 CLAUDE.mdSKILL.md(明令禁讀 ~/.claude、 禁上網;兩份教材 md5 與大小均不同可證非考本機那支)答十題 → grade-step1.sh 10 / 10 通過(判分器同時反向驗證仍會抓 ON_TRUE/ON_FAILURE 第一節點非 input


3.y 追加(2026-08-01leo confirm 兩缺口進 SDD;服務 CP arcrun-usable 步驟 5

D35 處置(鐵律④ 判斷結果:不開新 SDD、不換 active、不搬移 paused 任務)

leo 2026-08-01 confirm 頂層 pending-changes.md 07-30 兩段(缺口①引擎條件邊/ 缺口② recipe payload 與回應處理層)。處置理由逐條:

  1. 不開新 SDD——鐵律②「CC 在任何情況下不得主動建新 SDD」。confirm 的是 「規格層 proposal」,鐵律④只規定「開新 SDD 時」的搬移程序,並未要求每個 confirm 都必開新 SDD。本案能落進現行 active 就不該增生第三本。
  2. 不把 active 交給 arcrun-core-mvprecipe-system——兩本 paused 的未完成任務 core-mvp 14 筆=credential 注入/auth-workermulti-tenant KVanalytics recipe-system 10 筆=prompt_recipe 的 MCP tool 與 mira wiki 端到端) 與本次兩缺口零交集。升任一本為 active 就得先收掉 workflow-discovery16 筆 未完成、正在服務 CP 步驟 3/4),等於為了掛兩筆新任務把進行中的鏈打斷。
  3. 落在 workflow-discovery=任務層變更(鐵律②第二類)——CP arcrun-usable 步驟 3→4→5 是同一條有序鏈,步驟 3(誠實查詢)、步驟 4(節點替換)的任務 本來就掛在本 SDD 的 3.x;步驟 5 是同鏈的下一步,且改的是同一顆 worker cypher-executor)。掛同一本=與既有 3.6–3.10 同源,不是新方向。
  4. 兩本 paused 維持 paused、未完成任務原地不動——沒有被取代、沒有被繼承, 故不填 superseded_by、不移入 archive/。pending-changes 原提案標的 (缺口①→arcrun-core-mvp、缺口②→recipe-system)僅為「議題歸屬」描述, 非活性歸屬;實作歸屬依鐵律①走現行 active。

作廢任務清單:無(本次不作廢任何既有任務)。 搬移任務清單:無(不換 active,故無跨 SDD 搬移;新增下列 3.11–3.13)。

  • 3.11 缺口①:引擎通用具名分支邊(=Arcrun#5 根治;CP 步驟 5 交付物之一) 08-01 本地綠(commit 323ccc8):ON_TRUEON_FALSEON_BRANCH 三邊型+ readBranch() 四層相容讀法(data.branch → branch → data.result → result)。 做成通用具名分支,非布林特例leo 08-01「你改了 if,有改 switch 嗎?switch 更嚴重」)—— 三顆流程控制零件的 output_schema 本來就都收斂到 data.branch: string if_control→true/falseswitch→case 名/default_branchtry_catch→try/catch ⇒ 引擎只需一個機制,不留「做完 if 還要為 switch 再改一次」的債。 ON_TRUE/ON_FALSE=布林路語法糖,測試已證與 ON_BRANCH branch="true" 等價。 分支用法查得到leo 08-01 n8n 式逐顆查):新增 lib/branch-hints.ts 三顆零件的查詢回應自帶 branch_hintbranch_field/branches/edge_types/usage/example), 四條回應路徑全 wirecatalog foundlegacy 逐顆/步驟4 substitutiontarget=component)。 測試 tests/conditional-edges.test.ts 16 項全綠;零變化:現存 workflow 用到新邊型=0 筆。 〔原始描述〕 現況:if_control 只回 {result, branch}cypher-executor/src grep ON_TRUE|ON_FALSE0,圖的邊只有 ON_SUCCESSIFFOREACH ⇒ AI 照規矩用 if_control 也還是得寫 code 判斷該走哪條路 ⇒「全變成 code」的根。 要做:EdgeTypeON_TRUEON_FALSEgraph-executor 走邊邏輯依上游 branch 選路。引擎核心、風險最高:先寫測試再改;既有 4 支官方 workflow 行為必須零變化(跑一次證明)。
  • 3.12 缺口②:recipe payload 與回應處理層CP 步驟 5 交付物之二、之三) 08-01 本地綠(commit 5f5c0a8):新增 lib/recipe-payload.ts renderBodyTemplate 遞迴插值+保留型別+dot path;applyResponseMap 取值路徑/ thinking_model 剔除 thoughtanswer_marker 用 lastIndexOfstrip_prefixes 循環剝殼), RecipeDefinition 加四個全選填欄位 body_templateresponse_mapauthbinding_name component-loadermakeBindingRecipeRunnerpickRecipeRunnerauth='binding' 走平台 binding=免金鑰、開機即可用;一次打開 env.AI/VECTORIZE/BROWSER/QUEUE 整排)。 payload 用法查得到buildPayloadHint() wire 進三條 recipe 回應路徑 (守 D36:只說「金鑰由系統注入、你不必也不該填」,不吐值)。 測試 tests/recipe-payload-response.test.ts 14 項全綠(含 Gemini/Claude/Workers AI 三家形狀各用不同 path 都取得出文字=換源=換 recipe 的實證)。 相容:未設新欄位的既有 recipe 行為完全不變(有測試守)。 〔原始描述〕 現況 schema 只有 {canonical_id, endpoint, method, auth_service, headers, body} ⇒ 帶 body 的 API 只能繞過 recipe 把整包寫進 workflow code;回應解析 finalize 2786 字元)綁死 Gemini 格式。 要補三層:body_templatepayload 模板+變數插值)/response_map(回應正規化: 取值路徑・思考型模型旗標・淨化規則)/auth 第四型 binding(免金鑰, 一次打開 env.AIVECTORIZEBROWSERQUEUE)。 相容硬要求:既有 recipe(無新欄位)行為完全不變。
  • [◐] 3.13 驗收=CP 步驟 5 考試(features/07 ◐ 08-03t1523.13「真正的改寫」那半落地):rag_chatask_llm 從 「整包 Gemini 細節寫在 workflow 節點」改成 component: workers_ai_chat(一個 recipe 名 一個 prompt), finalize2786 字元縮到 12 行(回應解讀搬進 recipe 的 response_map)。 本 repo 側配套:api-recipe-seeds.ts 新增 workers_ai_chat 種子(auth: binding, 3.12 第四型認證的第一個真實案例)+修掉 /init/seed 列舉式重建吃掉 3.12 四個欄位的洞 (種子帶了 body_template/response_map/auth 卻進不了 KV,且哪裡都不會紅——與 08-02 syncManifest 吃掉 manifest.daemon 同型)。回歸閘 tests/init-seed-recipe-fields.test.ts 3 項,拿掉修復會紅、補回會綠(實測過會擋)。 實例端到端(1.4.4 youlin 帳號,零 API 金鑰):問答鏈全綠、有答案有出處。 選型實測見種子檔註解(llama-4-scout 2.2s vs Gemini gemma-4-31b 16.87s)。 ⚠️ 仍 ◐ 未 :haiku 場景(缺件時只寫 recipe 就補全、零 JS)=features/09 stage 端到端未驗。 ◐ 08-01:本地驗收綠(tests/step5-acceptance.test.ts 3 項),實跑輸出= 舊寫法 1201 字元 / if×8 → 新寫法 350 字元 / if×0(下降 71% 且分流工作流 success=true、零 code 節點。 ⚠️ 誠實標記:線上那顆 assemble5509 字元、if×23)住在 arcrun-rag 實例, 本 repo 無其定義 ⇒ 本次是把它的判斷骨架以新能力重建成等價工作流證明 「判斷不必寫在 JS 裡」,不是直接改寫線上節點。 真正的改寫與 haiku 場景(逐顆查、只寫 recipe 補全、零 JS)=stage 端到端 features/09),未驗前不得標 。 〔原始描述〕:拿現行 assemble 節點 (5509 字元、if×23)用新能力重寫 → code 大幅下降且仍 verdict=success; 貼改寫前後字元數與實跑輸出。另附 haiku 場景:缺件時只寫 recipe 就補全、零 JS。

跨任務鐵律提醒

  • 強制填 / 搜尋 / 回填全是能力 → 落 APICLI/MCP 只暴露(rule 07)。
  • 不假綠:未開 Vectorize 就老實降級 + hint,不假裝語義(mindset §7)。
  • 不自動編造 description:強制是逼真的描述,自動填 = 假裝有(誠實)。
  • flag 紅線search/backfill 都是主動 pull,無 cron/輪詢/fan-outC2)。
  • 框架級改動 → 端到端實證(leo21c)才算完成,不是 tsc 綠就宣布。