uncle6me-web
|
525faaf5d0
|
fix(cypher-executor): /cypher/search 不再誤報執行期原生零件 not_found(Arcrun#88)
病因:/cypher/search 只查 component registry(SUBMISSIONS_KV,經 submitComponent/
index-only 才有記錄);而 component-loader.ts 能直接解析、從不查 registry 的一整類
零件(trigger_workflow/BUILTIN_COMPONENTS/LOGIC_BINDING_MAP/WASM_HTTP_RUNNER_IDS,
如 if_control/http_request/switch)從未被 submit 過。leo21c 實例實測:
GET /components/catalog 回 404「零件 catalog 不存在」,search 因此對這些零件誠實地
回「兩庫都查過沒有」——但它們其實跑得動(leo 08-11 探測工作流已證)。
修法:從 component-loader.ts 匯出 RUNTIME_NATIVE_COMPONENT_IDS(既有三份執行期
解析白名單的聯集,非新清單),search-nodes.ts 在查 registry 之前先比對,
不受 registry 是否可達/是否已 backfill 影響。真正不存在的零件仍誠實回
not_found/unknown,not_found 的分型建議與相似候選機制不變。
刻意不做:不掃描 registry/components/* 目錄當清單來源——那含已標記待刪的死碼
(km_writer/kbdb_upsert_block),07-30 曾把這類死碼誤灌進 registry;也不投資
SUBMISSIONS_KV 的 backfill 腳本——decisions-summary.md D29 已定調 SUBMISSIONS_KV
併入「KV 退休戰」,不宜再加投資。
測試:cypher-executor/tests/search-nodes-runtime-native.test.ts 7 case 全綠,
複現 registry unreachable/registry 可達但目錄空(leo21c 實例的真實症狀)兩種情境。
全 suite 迴歸:357 pass(較修前 350 pass 多 7 個新測試),既有 14 個失敗與修前
數量、內容完全相同(pre-existing,與本次改動無關)。
|
2026-08-11 21:51:21 +08:00 |
|
uncle6me-web
|
7ba78552a4
|
D38:credential 目錄改走 KBDB API(零原生 SQL)+舊表退場;測試刻意留紅燈
存取層:credentials.ts / auth-dispatcher.ts / portal.ts 全改走 kbdbBase()+fetch
到 /entries(照 execution-logger.ts 既有慣例),.prepare/.exec/.batch 命中 0。
資料層:0005 seed credential template;0006 把舊表資料搬進 entries 後拆表;
0002 標退役、deploy.ts 不再套用(加 kbdb-sql-ok 留痕,純歷史對照)。
總管親驗四項(不聽 agent 自評):
1 三個檔 .prepare/.exec/.batch 命中 0;六個檔全部通過 kbdb-api-wall-guard
2 0006 的 INSERT 欄位(id/entry_type/owner_id/page_name/metadata_json/
created_at/updated_at)與 0001_base 的 entries 表逐一對得上
3 不可逆風險查官方:D1 batch 是 transaction、任一句失敗整批 rollback;
exec 出錯則「執行停止、後續不執行」=> 兩種語意下 INSERT 失敗都不會跑到
DROP TABLE,用戶 credential 目錄不會遺失
4 0006 搬在拆之前、冪等(NOT EXISTS 防重複)、豁免標記有留痕且理由正當
(拆表是牆內施工,API 不提供也不該提供拆表)
🔴 抓到一個假綠並修正:agent 中途被中斷,把 111 行的 credentials.test.ts
砍成一行「// placeholder — see edit below」,那個 edit 從來沒發生,
且 setup.ts 被刪。vitest 對這種檔案回報「Tests: no tests」,
很容易被讀成「沒失敗=通過」——正是 CP 記過的
「這條 route 曾整條消失過沒人發現」同型。
處置:還原 setup.ts/vitest.config.ts,credentials.test.ts 改成
**刻意會失敗的紅燈**並在檔頭列出要補的五項。空檔會被誤認為綠,紅燈不會。
未部署。本批要先上 stage 驗過才進 prod(leo 08-07 定)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 17:27:18 +08:00 |
|
uncle6me-web
|
60688c3108
|
fix(kv-quota): workflow 執行紀錄搬離 KV,改走 KBDB template 機制(A1/A2/A7)
事故:cypher-executor/src/actions/execution-logger.ts 舊版每跑完一次 workflow 就
ANALYTICS_KV.put() 一筆新 key(註解寫「避免覆蓋」)= 只增不減,封測者 Evan 處理約 690 個
檔案就把 KV 免費層 1,000 write/日打爆(實測 1,070 write),整個實例 429。
A1 少記:workflow 執行紀錄改走 KBDB template 機制(entries 表 entry_type='execution_log',
kbdb/migrations/0004_execution_log_template.sql 只 seed 一列 template 定義,零建表/改表)。
儲存精神比照既有 recipe_stat(kbdb/src/actions/recipe-stat.ts):template 只負責文件化,
實際一筆執行是 entries 表一列(1 次執行=1 次 D1 寫入,不走 entry_values 全展開)。欄位收斂:
時間/workflow/verdict/duration/錯誤訊息/(可得的)目標;成功記最少,失敗多記(訊息截斷長度
不對稱:200 vs 2000 字)。target 只認 trigger context 的 page_name/path,不整包存 input。
A2 自我降級:D1 額度仍與知識卡共用同一顆 100,000 rows/日,本模組自設 20% 軟上限(可用
EXECUTION_LOG_DAILY_WRITE_LIMIT 覆寫),超過 80% 降成只記失敗、超過 100% 完全停止記錄,
但 workflow 執行永遠照跑(cypher-executor 端 fire-and-forget 永不 throw)。
A7 讀取端:/workflows/:name/executions、/portal/data/workflows 的 last_execution、MCP
list_recent_executions 全部改打 KBDB HTTP API(GET /execution-log、/execution-log/latest),
取代原本的 ANALYTICS_KV list/get(免費層 list 也是 1,000/日)。
架構鐵律修正(本次施工中兩度被抓到走偏,過程留痕於 commit 訊息供後續參考):
- KBDB 三張表打天下(entries/templates/entry_values),永遠不加新 table——新資料類型
一律用 template + entries,不建表、不 ALTER TABLE。
- KBDB = API-as-Wall,零 SQL:cypher-executor 端一律走 KBDB 的 HTTP API(連法比照既有
recordRecipeStats/kbdbFetch 慣例),不直連任何 D1、不對 arcrun-kbdb 下任何原生 SQL。
順帶修復:kbdb/src/actions/entry-crud.ts listEntries 的 ORDER BY 補 `, rowid DESC` 二級
排序——entries.created_at 是 unixepoch() 秒級解析度,高頻寫入(execution_log 一秒內多筆)
常同秒,單靠 created_at DESC 不保證「最新一筆」正確,此為本次測試(latestExecutionLog)
發現的既有潛在缺陷,順手補上決定性排序,不改變任何既有查詢在 created_at 不同時的行為。
隔離:portal-data.ts INTERNAL_ENTRY_TYPES 加入 execution_log/execution_log_usage(與既有
value/workflow 同層級排除),避免用戶知識搜尋混進執行 log;本模組從不設 metadata_json.embed,
故永不進 Vectorize 語意搜尋索引。
不動:registry/src/actions/recordAnalytics.ts(零件市場統計,獨立 Worker、獨立 KV 命名空間、
不同資料模型,非本次事故根因所指範圍);cypher-executor/{wrangler.toml,kbdb/wrangler.toml}
未變動(repo 層級 deny 規則保護這兩個生產設定檔不被 AI 編輯)——ANALYTICS_KV binding
因此仍留在 wrangler.toml 宣告中但程式碼零讀寫點(見 PR 說明的完整 grep 佐證)。
KV 裡既有的 stats:* 舊資料不搬移(是統計不是真相源,維持原樣任其依 90 天 TTL 自然過期)。
測試:kbdb/tests/execution-log.test.ts(13 個,含零建表證明/少記/A2 降級/route)、
cypher-executor/tests/execution-logger.test.ts(payload 正確性/永不 throw)、
cypher-executor/tests/executions-route.test.ts(讀取端轉發)、portal-data.test.ts 對應區塊
改寫。kbdb 全測試 104/104 通過;cypher-executor 320 個測試中 9 個失敗為 main 既有(與本次
改動無關,改動前後 stash 對照確認)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 16:13:00 +08:00 |
|
uncle6me-web
|
eefbed98b6
|
合流 batch:步驟 3/4/5/6 併成一版出貨(同一顆 cypher worker,bundle 是 worker 粒度)
鐵律(08-01 血淚):CP 可分步驗收,但 bundle 是 worker 粒度——凡改同一顆 worker 的多步,
出貨前必先合流成一版再重生 bundle,否則 stage 只拿到一步(三條分支各自建 bundle 的坑)。
base=feat/step3-missing-guidance(最前緣,已含 step4+step6+t158-t162 prod 修)
merge=feat/step5-conditional-edges(引擎條件邊+recipe 三層+教材世代修)
|
2026-07-31 16:56:09 +08:00 |
|
uncle6me-web
|
a9a47b7c37
|
🔴 步驟5 補斷點:教材說「引擎不支援條件分支」+意圖語法收不到分支標籤
備考 haiku 真考時自查發現的兩個斷點——**若不補,考試必掛,且掛的是我自己的教材**。
形狀=步驟1 那個「世代脫節」的翻版:能力做好了,但教 AI 的地方還停在舊世代。
斷點①:三處教材主動說「沒有條件分支」,還教了正好造成腹語術的替代法
- mcp/src/mcp-handler.ts:44「**沒有** ON_TRUE/ON_FALSE——引擎目前不支援條件分支」
- registry/skills/write_intent_workflow.md:39「不要寫 ON_TRUE/ON_FALSE…
需要判斷時**寫成一個獨立節點**再接 ON_SUCCESS」← 這正是「判斷退回 code」的入口
- registry/skills/INDEX.md:44「已知的坑:引擎沒有條件分支」
⇒ 三處全部更新成現況(三顆零件都輸出 data.branch、引擎依標籤選路、
查零件回應附 branch_hint 照著接即可),並保留「不要寫 ON_FAILURE」(那個真的沒有)。
斷點②(更隱蔽,靜默失效):`graph-builder` 只認得 `對每個 X` 的參數化 label,
`ON_BRANCH(branch_active)` 帶括號會落到 toEdgeType 預設值 **PIPE**
⇒ 我在 skill 教的寫法,編圖收不到,而且**不報錯**——AI 以為分支了、實際全走同一條。
「教了語法但引擎不收」比沒做更糟,故與文件同批補上:比照 FOREACH 抽 iterator 的作法
抽 branch 標籤(半形/全形括號都收),寫進 edge.branch。
新增 tests/intent-branch-syntax.test.ts(7 項綠):守「文件教的寫法,編圖真的收得到」
——ON_TRUE/ON_FALSE 不退化成 PIPE、中文「成立時/否則」、ON_BRANCH(標籤) 抽得出 branch、
全形括號、try/catch 標籤;零變化:ON_SUCCESS 仍是 ON_SUCCESS、對每個 X 的 iterator 不受干擾。
全套 234 passed(前 227 +7),失敗數維持既有 9 筆;tsc 綠。
SDD: workflow-discovery 3.11|CP: arcrun-usable 步驟 5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 16:51:19 +08:00 |
|
uncle6me-web
|
5f5c0a89e2
|
步驟5 缺口②:recipe 補 payload/回應正規化/binding 三層(leo 三層模型的第③層)
問題:舊 recipe schema 只有 {canonical_id, endpoint, method, auth_service}(body 有但淺)
⇒ ①帶 body 的 API 只能繞過 recipe 把整包寫進 workflow code
②回應解析綁死單一供應商(rag_chat 的 finalize 2786 字元全在對付 Gemini 形狀)
③Cloudflare binding(env.AI/VECTORIZE/BROWSER/QUEUE)整類被「只認 HTTP+金鑰」的抽象排除
⇒ 換 LLM 供應商=改 workflow,而非換 recipe,違背「外部 API 只有一條一致的路」。
新增 lib/recipe-payload.ts(純函式,好測):
- renderBodyTemplate:遞迴插值,單一 {{x}} 保留原型別、混合文字拼字串、
支援 dot path、取不到保留原樣(不靜默吞掉,看得見才好 debug)。
語義刻意與 graph-executor 的 interpolateData 一致,不新造第二種插值行為。
- applyResponseMap:text_path 取值/thinking_model 剔除 thought=true 取最後一個非 thought/
answer_marker 用 lastIndexOf(自檢清單內文也會提到標記)/strip_prefixes 循環剝殼
(實撞三型「Draft: 【答】」「* 【答】」「Answer: * 【答】」,單趟剝不乾淨)。
RecipeDefinition 加四個**全選填**欄位:body_template/response_map/auth/binding_name。
- component-loader:body_template 優先於 body,兩者皆無才沿用 ctx 當 body(既有行為)
- response_map 有設才附 text 欄,未設原樣回傳 ⇒ 既有 recipe 行為完全不變
- 新增 makeBindingRecipeRunner+pickRecipeRunner:auth='binding' 走平台 binding(免金鑰、
開機即可用),其餘一律走既有 HTTP 路徑。binding 缺綁定/無 run() 時回可操作錯誤,不假綠。
這型不是為 Workers AI 開特例——一次打開 env.AI/VECTORIZE/BROWSER/QUEUE 整排。
payload 用法要「查得到」(同 branch_hint 動機,leo 08-01 的 n8n 式逐顆查):
buildPayloadHint() 讓 recipe 的查詢回應說得出「payload 怎麼填、回應怎麼取值、
認證誰負責」,wire 進 discover 混搜/legacy 逐顆/target=recipe 三條路徑。
金鑰鐵律 D36:hint 只說「走 auth recipe X,金鑰由系統注入、你不必也不該填」,不吐值。
測試:tests/recipe-payload-response.test.ts 14 項全綠(含三家形狀 Gemini/Claude/Workers AI
用不同 path 都取得出文字=換源=換 recipe 的實證;未設 response_map 原樣回傳的相容性)。
全套 209 passed(前 179 +30 新),失敗數維持既有 9 筆未變;tsc --noEmit 綠。
SDD: workflow-discovery task 3.12|CP: arcrun-usable 步驟 5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 16:31:58 +08:00 |
|
uncle6me-web
|
323ccc8475
|
步驟5 缺口①:引擎通用具名分支邊(ON_TRUE/ON_FALSE/ON_BRANCH)=Arcrun#5 根治
問題(「全變成 code」的根):if_control 回 {result, branch} 卻沒有邊讀得懂它,
圖的邊只有 ON_SUCCESS/IF/FOREACH ⇒ 就算照規矩用零件,仍得寫 code 判斷走哪條。
leo 08-01 追問「你改了 if,有改 switch 嗎?switch 更嚴重」——確認 switch(N 路)
與 try_catch(try/catch) 同病,故一次做成通用機制,不留「為 switch 再改一次」的債。
設計:三顆流程控制零件的 output_schema 本來就都收斂到同一形狀 data.branch: string
(if_control→true/false;switch→case 名或 default_branch;try_catch→try/catch)
⇒ 引擎只需「依標籤選邊」一個機制 ON_BRANCH;ON_TRUE/ON_FALSE 是布林路的語法糖,
底層同一條路(測試已證等價)。讀不出分支=不走(誠實,不亂挑一條)。
- types/schemas/constants:新增三邊型(純新增,既有列舉不動)+ GraphEdge.branch
- graph-executor:readBranch() 依 data.branch → branch → data.result → result 四層相容
- 中文語意詞:成立時/為真時=ON_TRUE,不成立時/為假時/否則=ON_FALSE,BRANCH=ON_BRANCH
分支用法要「查得到」(leo 08-01:AI 可能像 n8n 那樣逐顆查、自己組圖):
新增 lib/branch-hints.ts,讓 if_control/switch/try_catch 的查詢回應自帶 branch_hint
(branch_field/branches/edge_types/usage/example)——只看這一顆的回應就知道怎麼接下一步,
不必回頭讀 skill。四條回應路徑全wire:catalog found/legacy 逐顆/步驟4 substitution/
target=component 名字搜尋(=n8n 式那條)。不分岔的零件不加此欄,避免噪音。
測試(先寫測試再改引擎,紅線要求):tests/conditional-edges.test.ts 16 項全綠
——if 兩路/switch 多路+default/try_catch 成功與失敗路/語法糖等價/
context 傳遞/同分支 fan-out/無匹配不走/混合邊時 PIPE 不受影響/schema 放行。
零變化保證:195 passed(前 179 +16 新),失敗數維持既有 9 筆未變(console/portal
HTML 資產未建置+executor 斷言字串漂移,皆與本次無關);tsc --noEmit 綠。
現存 workflow/example 用到新邊型=0 筆(grep 實查)⇒ 既有行為不可能被改動。
SDD: workflow-discovery task 3.11|CP: arcrun-usable 步驟 5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 16:26:26 +08:00 |
|
uncle6me-web
|
832f270f52
|
Merge branch 'feat/step6-success-rate' into feat/step3-missing-guidance
|
2026-07-31 14:54:25 +08:00 |
|
uncle6me-web
|
d48f83ae6f
|
t159 步驟4 意圖節點→真實零件/recipe 替換+/cypher/search 加 target 指定搜尋對象
CP arcrun-usable 步驟 4(目的:AI 只要填 payload——系統把「傳到 telegram」
翻成 http_request+recipe telegram_send)+leo 07-31 追加:
「難道我不能指定要搜尋工作流或節點或 recipe 嗎?」
替換(只動 discover,t158「部署≠發現」邊界不碰):
- 兩庫 exact 落空後,在 t158 一次抓好的清單記憶體內媒合,零新增 round-trip
- 規則 A 服務詞→recipe:名字全部服務詞命中同一 recipe 且唯一才換
(google_slides_create 不被 google_sheets 誤吃)
- 規則 B 強欄位斷詞→零件:canonical/display/aliases 強命中×10+弱命中,
需至少一強命中且分數唯一最高(aes_encrypt 無強命中不換)
- 換到=status resolved+substitution{from,componentId,recipe,reason},
cypher 圖節點直接帶真實 componentId;換不到照舊 not_found+3.7 指路
target 參數(各走既有機制,不新造第二套搜尋):
- triplets+target=component|recipe=只查該庫
- query+target=名字搜尋:component→registry /components/search(=MCP
arcrun_search_components 同路);recipe→私庫 RECIPES KV(回應註明公庫走
arcrun_recipe_search);workflow→新抽 lib/workflow-search.ts,
GET /workflows/search 與 target=workflow 共用(=arcrun_search_workflows 同路)
- 防呆:compile+target 400/target=workflow 吃 query 不吃 triplets/非法 target 400
驗(本地 wrangler dev,registry 種 20 合約+init/seed 10 recipe):
- 「判斷有沒有新資料 >> ON_SUCCESS >> 傳到 telegram」→ if_control(resolved)
+telegram_send(substitution.componentId=http_request)=feature 06 驗法過
- 機械考 27/27 全綠(01 組×5+03 組×4 迴歸+06 組×8+target×8+compile 迴歸×2)
- 冷啟第一發 94ms、熱 8–13ms(t158 病史對照:舊 25.7s);compile 39ms unchecked 照舊
- tsc 全綠;vitest 9 failed/179 passed=t158 基線完全相同
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 13:49:09 +08:00 |
|
uncle6me-web
|
ea1c0571c1
|
步驟6 執行統計回寫:每顆零件跑完回寫 success_rate(task 29,design.md「執行統計設計」)
- registry 新增 POST /analytics/record:ANALYTICS_KV 計數器(stats:{hash_id}:{version})
為唯一真相源,衍生值(success_rate/avg_duration_ms/call_count)回填 comp: 記錄
——查詢讀取端讀哪就寫哪,不開第二真相源。KV 無 CAS,誠實標註非原子。
- cypher-executor execution-evaluator 從 stub 改真實作:執行收尾(/cypher/execute
成功與 ExecutionError 路徑+webhook 路徑)對 trace 裡每顆 Component 節點
fire-and-forget 回寫,waitUntil 包、不增加執行同步延遲(仿 recordRecipeStats 慣例)。
成敗判定=trace error 或 output.success===false(makeHttpRunner 非 2xx 不 throw)。
- registry 位置沿 search-nodes 慣例:REGISTRY_BASE_URL 覆蓋,未設走 wasmWorkerUrl。
- 新增單測 13 個全綠;本地雙 wrangler dev 端到端實測:http_request 跑 5 次
(3 成功+2 失敗)→ success_rate 1→0.6、call_count 0→5,/cypher/search 同步可見。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 13:45:05 +08:00 |
|
uncle6me-web
|
7e631a890a
|
t158 迴歸修復「部署≠發現」:複製路徑回毫秒級純編圖,誠實化只留在 discover
leo 07-31 定調:「這裡只是複製一些工作流的 data 過去,沒有要在這裡驗證,難怪這麼慢。
就算是我自己寫了錯的工作流,也可以跑跑看,如果錯誤就修改,
沒有說有錯誤還要一個個驗證這回事。」
定性=迴歸非新設計:部署路徑純複製是既有設計(arcrun-rag installer/src/index.js:13
「workflows.json 是既有 workflows/*.local.yaml 的搬運(打包期抽 flow/config)」+
arcrun-rag wiki「workflow 打包期預編成 workflows.json(worker 免帶 parser)」)。
5cadc60 起誠實化漏進 /cypher/search ⇒ 複製路徑也逐節點跑兩庫查詢+相似搜尋
(每 missing 節點 1+9 次 HTTP+recipe KV 掃)⇒ 冷實例 8 節點實測 25.7s、
安裝器 15s timeout 必炸(leo stage 實走 rag_takedown_direct aborted)。
改動:
- /cypher/search 加 mode:compile=純編圖零查詢(安裝器/acr push 複製路徑);
discover=誠實查詢預設(AI 問「有沒有」的既有契約,not_found+分型指路全保留)
- /cypher/execute 一律 compile(存在性由 component-loader 執行時決定=原權威)
- compile 的節點 status 標 unchecked(誠實「沒查」,不回假 found)
- discover 批次化:registry 新增 GET /components/catalog(一次回全目錄含
input_schema,補 CP2-B「沒有列表端點」缺口)+recipe 清單一次抓,
存在判定與相似度全記憶體比對;舊 registry 無 catalog 端點 → 退回逐顆(相容);
registry 整個查不通 → unknown 照舊(不誤判 not_found)
- cli push 帶 mode:compile+拔 missing 擋(push 不看 missing;要問有沒有走 validate)
驗(本地 wrangler dev 誠實環境,registry 種 20 合約):
- compile 編圖:graph_neighbors 39ms/rag_chat(11節點) 3ms/rag_ingest_card 2ms/
rag_takedown_direct(8節點) 3ms——回迴歸前毫秒級
- 安裝器 pushWorkflowTo(mode:compile)4/4 ok(44/7/7/5ms)
- 故意引用不存在零件的 workflow:部署 ok=true,trigger 執行時誠實報
「找不到零件…」+可用零件清單(部署≠發現實證)
- discover 契約:邏輯名 missing=2+not_found+suggestion(21ms);
頂層 verify.sh 01 組 5/5+03 組 4/4 全綠
- cypher+registry tsc 全綠;vitest 9 failed/179 passed=5cadc60 基線完全相同
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 13:31:33 +08:00 |
|
uncle6me-web
|
1794072179
|
3.6/3.7 查詢誠實化:兩庫都查、缺件回 not_found+分型指路 suggestion
📋 SDD:workflow-discovery task 3.6/3.7(leo 07-31 步驟 3 考題)
契約以頂層 arcrun-usable/verify.sh 01+03 組為準。
- 3.6 recipe 納入 /cypher/search:零件 registry 落空後查 RECIPES KV
(resolveRecipe,執行鏈同一套解析);recipe found 附 source/description/endpoint
- 3.7 缺件分型指路:status 契約定 not_found(verify grep),suggestion 欄——
名字含服務詞(google/telegram/…)=外部 API 樣貌 → 指 skill write_recipe;
含計算詞(encrypt/hash/…)=計算原語樣貌 → 指 skill add_new_wasm_component 投稿 PR;
判不出型誠實說判不出、兩條路都給。規則簡單可解釋(不接 LLM),判準在 code 註解
- 相近候選:not_found 附 similar_components/similar_recipes——全名搜不中就斷詞
(ASCII 詞+中日韓 2-gram)打 registry /components/search,
「判斷有沒有新資料」媒合到 if_control(leo:AI 不用知道零件存在)
- 修頭節點假 found:resolveNodeRole 把無入邊頭節點判 Input,searchNodes 對 Input
無條件 found ⇒ 「aes_encrypt >> … >> code」的頭被掩蓋。改為只有字面
input/trigger/…/output 名才短路(isVirtualIoName),真名字照查兩庫
- registry 查詢層補 input_schema/output_schema 透傳:KV 一直有存
(indexOnlyComponent),toComponentRecord 丟掉 ⇒ /cypher/search 給不出
「怎麼填 payload」。順手補 REGISTRY_BASE_URL 可選覆蓋(比照 KBDB_GRAPH_URL 慣例,
本地 dev/self-hosted registry 掛別處時用)
驗:cypher-executor+registry tsc 全綠;vitest 9 failed/179 passed=與 5cadc60
基線完全相同(既有債非本次造成);本地 wrangler dev(cypher 指本地 registry,
KV 用 index-only 種入 20 份 repo 合約)跑頂層 verify.sh 01+03 組 9/9 全綠,
含 telegram_send 種入後 recipe found 路徑實測。部署到實例後需對真環境重驗。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-31 11:56:15 +08:00 |
|
Leo
|
5cadc60e36
|
feat(workflow-discovery): /cypher/search 改為真查 registry——修「查詢回假信號」
📋 SDD:workflow-discovery(本 commit 同時執行 D35 交接:portal-auth 26/26 完成 → closed
superseded_by workflow-discovery;workflow-discovery paused → active。單一活性已驗=1 份)
🎯 對應 task:3.x 搜尋端誠實化(CP2-B)
病灶(leo 2026-07-30 定性「腹語術」):
search-nodes.ts 無條件回 status:'found'、missingNodes 永遠 []——
型別宣告了 'missing' 但程式碼從不使用。實測「完全不存在的東西xyz」也回 found。
⇒ AI 拿到假信號 → 以為零件存在 → 部署才發現沒有 → 改寫 code
⇒ 正式 workflow 只用 2 個零件、8 個 code 節點含 if×61。
修法:
- 查 registry 判真實存在(走 HTTP,守 D28 禁新增 service binding;
URL 用既有 wasmWorkerUrl() 慣例組,不自創)
- found 時附 input_schema/success_rate/stability
⇒ AI 才填得出 payload、才看得到「測過幾次」(leo:AI 只要填 payload)
- 查不通回 'unknown' 而非 'missing'——**誠實限制**:
不能因查詢失敗就宣告零件不存在(那會讓 AI 誤判而重寫 code)
- missing 真的回傳出去(原本寫死 [])
⚠️ 實測發現 registry **沒有列表端點**(GET /components → 404,只有 /components/<id>)
⇒ 改為逐個查(節點數通常 <10、5s timeout)。補列表端點後可改抓一次=CP2-B 待辦。
驗:tsc 零錯誤;vitest 9 failed/179 passed=**與改動前 stash 對帳完全相同**(既有債非本次造成)。
⏳ 待部署到實例後跑 arcrun-usable/verify.sh 驗 01 那組轉綠。
|
2026-07-30 20:41:53 +08:00 |
|
Leo
|
20c7610371
|
refactor: 移除已廢棄的自管加密金鑰機制(credential 全面託管 CF Workers Secrets)
leo 2026-07-20 明令:「已經改用 cf 自己的 secrets,不要再說它了」
「我希望以後再也看不到這個詞再出現」
背景:credential 早已遷移至 CF Workers per-script Secrets + D1 目錄,
舊的自管金鑰(client 端 AES-GCM + KV 密文 + crypto_decrypt)是遷移期遺留。
本次連根移除,含一併作廢的死 SaaS 碼。
移除:
- 舊 KV 密文解密路徑(credential-injector.ts 整檔、dual-read fallback)
前置驗證:leo21c / youlin 兩帳號 CREDENTIALS_KV 實測 *:cred:* 皆 0 筆
- migrate-to-workers-secrets 搬家端點(回填已完成,無可回填)
- /register 路由與 generateApiKey(HMAC 產 ak_ key 是 SaaS 遺物;
self-hosted 走 namespace 明碼 D21,已無人使用)
- platform_crypto component(三帳號實測 404 已退役,無 workflow 引用)
保留(附理由):
- crypto_decrypt 保留為永遠回失敗的 stub——現役三個 auth .wasm 仍宣告該
import,缺項會讓 WASM instantiate 直接失敗。待零件重編後可真正刪除。
順帶修復(原不在範圍,但會實際壞事):
- /auth/callback 有 `if (!key) redirect(server_error)` 閘,未設該 secret 的
實例會登入直接失敗 → 已移除
- OAuth 兩處把 provider token 寫進舊加密 KV(租戶鍵與實際 api_key 在 rotate
後必然分歧,已失效)→ 改導向 Workers Secrets,包 try/catch 不影響登入
- acr init Standard 模式呼叫已刪除的 /register → 改引導 OAuth 取 key
- .claude/rules 與 system-dev/docs 是同一規範的兩份鏡像,先前只改 rules
導致鏡像仍在教舊做法 → 已同步(此類雙檔同步應納入檢查)
新用戶安裝從此零 secret 前置。
測試 187/188(唯一 fail 為 pre-existing,stash 驗證與本次無關);
cypher-executor 與 cli typecheck 全綠。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-21 01:32:48 +08:00 |
|
uncle6me-web
|
ed2e42e007
|
feat(credentials): T6 讀取/注入接新家 + T7 雙讀 fallback (credential-store-migration 方案 A)
D19「擁有目錄不擁有內容物」遷移的讀取斷點。密文住 cypher per-script secrets、
D1 只存 secret_ref、auth worker 讀不到 cypher 的 secrets → cypher 先取值塞 payload。
WASM 端(T7 fallback 骨架,零行為改變可獨立部署驗):
- auth_static_key/main.go + auth_service_account/main.go:Input 加 resolved_secrets,
解密處改「有 resolved 就用、沒有才 fallback 舊 kv_get+crypto_decrypt」。default 等於舊碼。
- tinygo build 兩支通過,copy 到 .component-builds/*/component.wasm。
TS 端(T6 主路徑):
- auth-dispatcher.ts 新增 resolveSecretsFromNewHome:查 D1 拿 secret_ref →
secret_get(env[ref], T4) 取明文 → 組 map(取不到的 name 缺席,不放空字串) →
更新 last_used_at。tryAuthDispatch + resolveCredentialRefs 都塞 resolved_secrets。
- rule 02 §2.2 對齊:只查 ref/取值/塞字串,不解密不展開模板不組 JWT。
驗證:cypher-executor + cli tsc exit 0;vitest 41/42(新增 auth-dispatcher.test.ts 6 案例全過,
剩 1 pre-existing 無關失敗)。待 leo21c 部署驗 WASM 端到端(不由本任務部署,acr update
硬綁 GitHub codeload=mistakes #23)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-05 13:44:26 +08:00 |
|
uncle6me-web
|
da84425d25
|
feat(credential-injection): {{credential.X}} 用戶面語法(credential-primitives §8)
壓測 401 根因:{{credential.X}} 系統沒實裝,三條 template 展開路徑都不認
credential. namespace → 注入空值 → 目標 API 401(test_arcrun/5 Haiku 實證)。
修法(design §8,richblack 確認方向 B「讓 {{credential.X}} 真的能用」):
- auth_static_key 加 resolve_credentials action:給 names → WASM 內 kv_get +
crypto_decrypt → 回明文 map(不查 recipe、缺則誠實報錯)
- auth-dispatcher 加 resolveCredentialRefs:遞迴偵測 {{credential.X}} → 交 WASM
解密 → 回填(無 ref 則零開銷不打 WASM)
- graph-executor 在 node.data interpolate 後呼叫,不碰 ENCRYPTION_KEY(rule 02 §2.2)
解密全程在 WASM,TS 只偵測+回填。tinygo build OK + tsc 0 + §2.2 自檢綠。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-10 13:55:31 +08:00 |
|
uncle6me-web
|
6a75117ba3
|
feat(kbdb): recipe 公庫/私庫雙向機制 + UUID 身份 + KBDB Base + 市場數據
kbdb-base SDD §7.5(公庫/私庫雙向機制,richblack 2026-06-07 拍板)。
## KBDB Base worker(新)
- kbdb/:D1-only 核心三表(entries/templates/entry_values)+ CRUD + LIKE search
+ recipe-stats 端點(市場數據)+ 0001_base.sql migration(含 recipe_stat seed)
## Phase 2.3:init 建 D1 + 套 migration
- cli cf-api.ts 加 listD1Databases/ensureD1Database;init 建 arcrun-kbdb D1
- deploy.ts 部署後對 D1 套 0001_base.sql(CF /d1/query API,idempotent)+ 注入 database_id
## Phase 5.1:recipe 成功記錄(市場數據來源)
- GraphExecutor 收集本次用到的 recipe uuid(usedRecipeKeys)
- executeWebhookGraph 執行結束一次性記 per-uuid 成功/失敗到 KBDB(fire-and-forget)
## Phase 7.5:recipe UUID 身份 + app-store 模型
- recipe 領 uuid=唯一身份;canonical_id/author/公私=屬性(§7.5.5)
- recipe:{uuid} + idx:canonical/installed/hash;resolveRecipe 向後相容不破執行鏈
- POST /recipes/submit=領新 uuid 新增作者版本(非覆蓋,app-store)
- GET /public-recipes 搜尋(多作者+per-uuid 市場星數)/ :id pull(選市場最佳)
- 落空→found:false 創作引導(§7.5.6 閉環)
- POST /recipes/migrate-uuid 一次性轉舊 key(增量寫不刪舊、冪等)
- init-seed 用 UUID(author=system)
## 薄殼(rule 07 §5:CLI + MCP 覆蓋同組能力)
- CLI: acr recipe search/pull/submit-p(config 加 DEFAULT_PUBLIC_LIBRARY_URL)
- MCP: arcrun_recipe_search/pull/submit_p/push/list/delete(補齊漂移)
## 壓測修正
- api-recipe-seeds: google_sheets_append PUT→POST(:append 正確動詞,階段12)
四 worker tsc 全綠(cypher/cli/kbdb/mcp)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-07 16:18:10 +08:00 |
|
uncle6me-web
|
95a1462b65
|
fix(cypher): 改用 global_fetch_strictly_public flag 解 same-zone 1042(revert service binding)
richblack 拍板:service binding(前一 commit)靜態、加/改要重 deploy cypher,廢。
改用 global_fetch_strictly_public compatibility flag——cypher wrangler.toml 加一行,
讓 fetch() 走公網前門,self-hosted 的 same-zone fetch(cypher 與 auth 同在
{sub}.workers.dev zone)也能通。
- wrangler.toml:compatibility_flags 加 global_fetch_strictly_public(移除 SVC_AUTH_*)
- auth-dispatcher.ts / types.ts:還原到 service binding 之前(單純 fetch workers.dev)
- 安全(官方 docs):唯一副作用 self-loop 僅在 fetch 自己 hostname;cypher 不 self-loop
- 官方/self-host 共用同一份 toml:官方本就跨 zone 行為不變,self-host 被修好
- 規範還原:rule 02/03/CLAUDE.md/pre-bash-guard 的 service binding 禁令維持原狀
SDD: credential-primitives-wasm Phase 7(A→廢→B)。tsc exit 0。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-06 21:44:13 +08:00 |
|
uncle6me-web
|
d2048e26a7
|
fix(cypher): auth primitive 改走 service binding(解 self-hosted CF 1042)
壓測階段 11:self-hosted 帳號 cypher 用 fetch(workers.dev) 打同帳號
auth worker 被 CF 子請求限制回 1042,service account token 換不到 →
表單寫不進 Google Sheets。token/解密鏈本身正常(直打 auth worker 回真 ya29)。
架構演化(richblack 2026-06-06 拍板):用戶產生的是 recipe(KV 資料,不 deploy),
primitive 是平台固定基礎設施、用戶不新增 → 解除「auth primitive 禁 service binding」
舊禁令。service binding 是 CF 內部 RPC,繞開同 zone 522 + 同帳號 workers.dev 1042。
- wrangler.toml:加 SVC_AUTH_STATIC_KEY/SERVICE_ACCOUNT/OAUTH2(已部署者;mtls 未部署留註解)
- auth-dispatcher.ts:binding 優先 svc.fetch(),無 binding fallback fetch(workers.dev)
- types.ts:4 個 optional SVC_AUTH_*
- deploy.ts 無需改:stripOfficialOnlyBindings 不碰 services,tier1 auth 先於 tier2 cypher
- 已驗證 self-hosted(leo21c)13 邏輯零件 binding 實綁成功,auth binding 走同路
規範同步:rule 02 / 03 / CLAUDE.md / pre-bash-guard 例外。SDD: Phase 7。tsc exit 0。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-06 21:09:49 +08:00 |
|
uncle6me-web
|
922a57fe34
|
arcrun — AI workflow execution engine (clean history)
Self-hosted 開源:WASM 零件 + recipe + cypher-executor,跑在你自己的 Cloudflare。
此為重建的乾淨歷史起點(移除曾誤 commit 的 GCP SA 金鑰,舊歷史保留在
richblack/arcrun 與本地 backup 分支)。含:
- acr init --self-hosted installer(建 KV/R2 + codeload 拉預編譯 wasm + wrangler deploy + seed recipe)
- recipe push 把關(資料外流提醒 + 打通檢查)
- 19 個正當零件預編譯 wasm(claude_api/km_writer/kbdb_upsert_block 排除:違反 DECISIONS §1)
- CLI / cypher-executor / registry / 完整 SDD
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-03 15:52:38 +08:00 |
|