Leo
3892dc3a9b
docs(AGENTS): 更新 LI M2.2 + M3 新 tool / examples / skills 引用
...
對應 LI SDD M2.2 + M3.3 + M3.1 完成。
- Step 1 加 arcrun_search_examples / arcrun_list_skills 用法
- Step 3/4/5/6 改用 arcrun_* tool prefix
- 新增 Step 7:報 feedback
- §7「不確定的時候」全部更新成 arcrun_* tool 名
- 新增「過渡期 tool 命名注意」說明:arcrun_* 主用、u6u_* 舊規範保留、
u6u_deploy_workflow 壞掉建議改 arcrun_push_workflow
2026-05-16 16:41:35 +08:00
Leo
ce693b4de1
ci: deploy.yml concurrency cancel-in-progress
...
leo 2026-05-16 帳號 Actions 用爆配額被 disable。連續 push 時舊跑會被
新跑取代,省 50%+ minutes。
代價:在中段 push 後 +30 秒內再 push 第三次,第二次跑被取消(不會部署)。
LI 開發階段可接受 — 開發頻率高、最終 push 才需要真實部署。
未來若需要每次都跑(例如生產穩定期),改回 false。
2026-05-16 16:39:59 +08:00
Leo
388c193ae7
docs(registry): seed 10 examples + 5 skills (LI SDD M3.1 + M3.3)
...
對應 .agents/specs/llm-interface/ Milestone 3.1 + 3.3。
registry/examples/ — 10 個可直接 push 的 workflow 範本:
starter: webhook-to-http
common: cron-watcher, llm-classify, rag-search-answer, daily-digest
external: email-summary (gmail+claude+telegram), pdf-to-blocks,
github-issue-bot
advanced: parallel-fanout (trigger_workflow fan-out),
error-retry (try_catch+wait pattern)
每個含:workflow.yaml(可直接 push)+ description.md(解決什麼問題 /
改成你自己的 / 學到什麼)+ tags.json(搜尋用)
registry/skills/ — 5 個 AI playbook(markdown):
build_watcher_workflow — cron + filter + trigger 模式
debug_paused_workflow — claude_api callback paused 怎麼追
migrate_http_to_trigger_workflow — 從 self-fetch 換 trigger_workflow
rag_with_arcrun — KBDB + claude_api 組裝 RAG
add_new_wasm_component — TinyGo 寫 + 部署全流程
兩者差異:
examples = 可直接拿來改的 YAML
skills = 面對 X 問題該怎麼想 + 該用哪個 example
兩者後續:CI 自動同步進 KBDB(type=workflow-example / type=agent-skill),
MCP arcrun_search_examples / arcrun_list_skills 走 KBDB semantic search。
(CI sync 是 M3.4 工作)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 16:33:54 +08:00
Leo
989fbeb9ac
feat(cypher-executor): /executions/* introspection (LI SDD M2.1)
...
對應 .agents/specs/llm-interface/ Milestone 2.1。給 AI debug 用的執行
狀態檢視端點。3 個新路由:
GET /executions/paused
- 列當前 api_key 下所有 paused workflow(等 callback resume)
- 走 EXEC_CONTEXT KV `paused_run:*` prefix scan,過濾 state.api_key
- 回 [{task_id, run_id, paused_node_id, workflow_name, expires_at}]
- 限 limit 100,避免 KV N+1 爆
GET /executions/:task_id
- 看單一 paused state 細節(trace_so_far / paused_context / pending_result)
- 隔離租戶(state.api_key !== 用戶 ak → 回 not_found 不洩漏存在性)
- 回完整 state JSON
GET /workflows/:name/executions
- 列某 workflow 最近 N 次執行 verdict(走 ANALYTICS_KV stats:{name}:* prefix)
- 先驗 workflow 屬該 api_key
- 按 timestamp 後綴 desc sort
統一 error contract(LI SDD §1.3 / §1.4 規範):
- ok: bool
- error_code: enum (auth_missing / not_found / internal_error)
- human_message: 描述
- next_actions: 陣列,給 AI 看的下一步
- hints: 成功時的 next-step 建議
不影響既有路由 contract。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 15:58:35 +08:00
Leo
04ed722591
chore: gitignore .swarm/ + ruvector.db (Claude Code local artifacts)
...
之前 M1.2 telemetry commit 不小心把 cypher-executor/src/.swarm/ 跟 ruvector.db
commit 進去。這些是 Claude Code 自己的本地工具產物,不該入庫。
- 加 .gitignore 樣式:.swarm/ / ruvector.db / **/.swarm/ / **/ruvector.db
- 撤回上次 commit 進去的 5 個檔案
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 15:35:55 +08:00
Leo
d04e34ea35
feat(cypher-executor): implicit telemetry (LI SDD M1.2)
...
對應 .agents/specs/llm-interface/ Milestone 1.2。
新增 lib/telemetry.ts:
- hashApiKey(): SHA-256 截 16 hex 字元(不可逆,可聚合)
- recordTelemetry(): fetch fire-and-forget 寫 KBDB type=agent-telemetry block
- 設計:不阻擋主流程,錯誤 console.warn 不 throw
- 用 ctx.waitUntil 確保即使主 request 已回,背景仍會跑完
寫入點 3 處:
1. routes/webhooks-named.ts POST /webhooks/named (deploy) → deploy_success
2. routes/webhooks-named.ts POST /webhooks/named/:name/trigger →
executeWebhookGraph 帶 ctx + userAgent,內部記 run_success / run_fail
3. routes/validate.ts POST /validate → validation_error (含 schema_failed / edge_node_missing)
executeWebhookGraph 簽名擴張:可選 ctx + userAgent,舊 caller (scheduled /
trigger_workflow / anonymous webhook) 不傳也 OK(telemetry 仍寫但無 ctx 加持)。
paused (workflow 因 claude_api 等等 callback resume) 算 run_success,
不污染 fail metric。
types.ts: 加 PLATFORM_API_KEY env (可選) + re-export ExecutionContext
不違反「業務邏輯走 WASM」鐵律:telemetry 是 orchestrator 觀測自身的能力,
跟 trigger_workflow / scheduled() 同類。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 15:33:35 +08:00
Leo
56973558e2
docs(arcrun): AGENTS.md v1 — AI onboarding (LI SDD M1.1)
...
對應 SDD .agents/specs/llm-interface/ M1.1。
LI (LLM Interface) 第一份文件:任何 AI agent 載入這份就能用 arcrun,
不用讀 SDD 內部架構、不用 grep codebase、不用問人。
包含:
- 30 秒「what is arcrun」
- MCP 連線配置(Claude Desktop / Cursor / 自製 agent 通用)
- 5 個核心概念(Component / Cypher binding / FOREACH / Paused-resume / api_key)
- 你的第一個 workflow(list → validate → push → run → trace 5 步)
- URL 慣例 + CF self-fetch 死鎖警示
- 常見錯誤 + error_code → 下一步 mapping
- 「不確定的時候」標準流程
- report_feedback 規範(**必做**)
- KBDB 速覽 + cron watcher 範例
- meta-規範:寫 workflow 的 AI 自己的習慣
901 words / 263 lines(控制在 5-8K tokens 內),純繁體中文。
CI 自動同步 KBDB block (type=agent-onboarding) 之後再做(M1.1 另一個 subtask)。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 15:28:05 +08:00
Leo
180cef26c7
docs: rename SDD folders u6u-* → arcrun-* + update cross-refs
...
對應 SDD arcrun/.agents/specs/llm-interface/ M5.6(之前列為 backlog 連動)。
leo 2026-05-16 拍板 u6u 整體退場後,順手把兩個 SDD 也改名。
- .agents/specs/u6u-core-mvp/ → arcrun-core-mvp/
- .agents/specs/u6u-platform-evolution/ → arcrun-platform-evolution/
- CLAUDE.md / .claude/rules/00-sdd-protocol.md / 04-current-progress.md /
llm-interface SDD 內所有跨 SDD 引用同步更新
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 15:24:22 +08:00
Leo
5d99302681
docs(llm-interface): apply leo's decisions — drop u6u + finally.click
...
leo 2026-05-16 拍板(除 dual-hostname 外照原設計):
1. MCP URL: 單一 mcp.arcrun.dev,mcp.finally.click 直接退場(不並存)
- 理由:finally.click 是還沒申請新網址的暫用,那是一個服務,arcrun 是底層
2. u6u branding 整體退場:
- u6u-mcp repo → arcrun-mcp
- u6u-gui repo → arcrun-gui
- u6u_* tool prefix → arcrun_*
- 一次切換,不留 alias,不留 deprecation 期
- 理由:u6u 不存在了
SDD 三件套同步更新:
- requirements.md: 開放問題章節改決策紀錄;移除「保留 15 tool deprecation」自相矛盾
- design.md: §1.1 命名 + §6 migration plan + §8 決策表全部改成「單一切換」
- tasks.md: M5 重組成 6 個 sub-step(準備 / repo rename / tool rename / 舊 URL 退場 / 文件 / 連動 SDD 追蹤)
連動但不在本 SDD 範圍:
- matrix/arcrun/.agents/specs/u6u-core-mvp/ 改名
- matrix/arcrun/.agents/specs/u6u-platform-evolution/ 改名
(M5.6 列出,另起 task 追蹤)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 15:09:48 +08:00
Leo
c2a2f82ade
docs(arcrun): SDD llm-interface — AI 操盤手使用體驗 first-class
...
設計動機:3 天 mira dogfood 累積 14 個痛點,7 個純粹是 LI 缺失。
arcrun 過去設計集中在「人」(u6u-gui / docs),AI 對 arcrun 的可用性
沒被當第一公民。
SDD 三件套(matrix/arcrun/.agents/specs/llm-interface/):
requirements.md
- personas(Claude Code 主力 / 用戶私人 agent / SDK 使用者)
- 範圍涵蓋 5 系統(cypher-executor / registry / u6u-mcp / u6u-gui / kbdb)
- 10 個 FR:onboarding / CRUD 對等 / dry-run / 結構化 trace /
可程式化 error / feedback tool / implicit telemetry /
skill blocks / examples / weekly closed loop
- 5 個 NFR:相容 / 多 transport / error contract 穩定 /
feedback exportable / coverage 量化
design.md
- 5 層 LI 模型:AGENTS.md / arcrun-mcp / Skills / Examples / Telemetry
- 25 個 MCP tool 完整清單分 5 類
- error_code enum v1
- coverage matrix(GUI 動作 vs MCP / 31 cypher-executor 路由 vs LI)
- 完整 AGENTS.md 模板
- u6u-mcp → arcrun-mcp migration plan(90 天 deprecation)
- weekly_review workflow YAML 範本
tasks.md
- 5 個 milestone(M1 收 data / M2 gap-fill / M3 skill+examples /
M4 closed loop / M5 rename)
- 估算 23 個工作日 (~5 週)
- M1 是硬前置(不收 data 改了也不知道對沒)
Audit 基準(用 4 個並行 Explore agent 整理):
- cypher-executor: 31 HTTP 路由,9 個 AI-essential
- u6u-mcp: 15 tool,缺 update/delete/history/validate/feedback
- u6u-gui: 8 個人類動作可對等 LI / 3 個視覺類不需
- kbdb: 50 路由 13 group,LI 走 abstracted tool 不直接 expose
同步更新 .claude/rules/04-current-progress.md SDD 索引。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 14:58:21 +08:00
Leo
521624261d
fix(cypher-executor): trigger_workflow paused 不算失敗
...
watcher 實測 8/8 raw 跑通後發現 wait=true 把 wiki_synthesis paused
(claude_api 等 callback resume 的正常狀態)回報成 success:false,造成
watcher 看起來「5/8 失敗」實際是「正在背景跑」。
改成:
- isPaused 偵測「workflow paused at node X」error 字串
- isPaused → success:true, status:'paused_awaiting_resume'
- 完整完成 → status:'completed'
- 真失敗 → status:'failed'
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 14:04:12 +08:00
Leo
b8ecef0b41
feat(cypher-executor): trigger_workflow 內建零件 — 繞 CF self-fetch
...
mira_feed_watcher 之前用 http_request 自打 cypher.arcrun.dev / 自身 workers.dev URL
都被 CF self-fetch 防護擋(Worker→自身的 subrequest 攔截)。
新增 `trigger_workflow` 內建 orchestration 零件:
- 在 createComponentLoader 最前面攔截 component_id === 'trigger_workflow'
- 從 WEBHOOKS KV 撈 `{api_key}:wf:{name}` 拿 graph
- 動態 import 避循環依賴
- in-process 呼叫 executeWebhookGraph,沒有任何外部 HTTP
- 預設 wait=true(claude_api paused 仍視為 success 回傳)
不違反「業務邏輯走 WASM」鐵律:trigger_workflow 是 orchestrator 自己的 routing
能力(像既有的 CALLS_SUBFLOW),不是業務邏輯。
對應 mira_feed_watcher.yaml 同步改用此零件(在 polaris/mira/ repo)。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 13:54:26 +08:00
Leo
1084e0102a
fix(mira): wikilink autocomplete 5s cache + 開下拉時 refetch
...
leo 反饋:30s TTL 太久,wiki_synthesis 後台跑出新 entity,autocomplete 撈不到。
- TTL 30s → 5s
- WikilinkAutocomplete 在 matchInfo 從 null → 有值時主動 invalidate refetch
- 順手把 yaml-parser 對 FOREACH iterator relation 命名變體(「對每個 X」/「FOREACH X」)放行,graph-builder 早就支援,validate 卻擋掉
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-16 13:37:03 +08:00
Leo
7da1eb6d65
feat(mira): [[entity]] wikilink — 顯式建檔 + autocomplete + render link
...
對應 tasks.md backlog #12 / design.md §3.6.2。leo 反饋:要像 Logseq 那樣
寫 [[X]] 立刻建檔,下次 [[X 自動補完,render 變連結。
helpers:
- parseWikilinks(text) → 抽 [[X]] entity list
- fetchAllEntityNames(apiKey) → 合 index-entry + wiki-page entity 名稱
- getEntityNamesCached → 30s session cache for autocomplete
- ensureEntitiesExist → 新 entity 立刻建 wiki-page placeholder
- tags 含 entity-type:book/url/concept(guessEntityType 推測:《》→ book / http → url)
- source: leo-explicit
- expandWikilinks(text) → render 時把 [[X]] 轉 markdown link to /mira/wiki/wiki-X
UI:
- <WikilinkAutocomplete>:textarea cursor 在 `[[query` 未閉合時,下拉顯示既存
entity(substring filter)+「⊕ 建立 [[query]]」option,↑↓選 / Enter 確認 /
Esc 取消。fixed-position below textarea bottom(cursor tracking 留下輪)
- PostComposer compact + popup 兩個 textarea 都掛 autocomplete
- EditingArea(PostEditor / BlockEditor / ReplyLine / PageReplyComposer 共用)
加 apiKey prop,內部 textarea + popup 都掛 autocomplete
submit hook:
- PostComposer.submit:postBlockId 建好後 ensureEntitiesExist(wikilinks)
- BlockEditor.submitReply / ReplyLine.submitReply 同樣建檔
- 在 wiki_synthesis trigger 前先建,避免 race
render:
- markdown.tsx expandWikilinks 取代 stripLogseqMeta 前處理(兩階段)
- 內部 wiki link(/mira/wiki/...)不開 _target=_blank(不離開頁面)
留下輪:metadata 補完 (作者/出版社) / cursor tracking / PostEditor.save 也建檔
2026-05-16 12:08:28 +08:00
Leo
d6bff9d551
fix(mira): reply @mira indicator + RAG match 寬鬆化
...
leo 試用反饋:
bug:reply 中 @mira 「看起來無效」
- 真正 root cause: trigger 確實 fire,但 thinking indicator 沒亮起 → leo 沒看到回應
以為失敗(其實 mira 後台跑 30s+ 才回)
- 修:MiraTriggerContext 把 thinking trigger 抽成 context callback
PostComposer / PostEditor / BlockEditor / ReplyLine 五個 @mira 觸發點
都呼叫 triggerThinking?.(docPageName) 啟動 5s polling
bug:RAG 抓不到 entity(leo 寫《李飛飛的視界之旅》沒被識別)
- 之前只看 type=index-entry,且嚴格 substring。新建 wiki 還沒 index-entry
時就漏;entity 名稱跟貼文文字稍微不同也漏
- 修 fetchRelevantWikiContext:
- 平行撈 index-entry + wiki-page 兩種,合併 entity set
- 雙向匹配:entity 完整 substring postContent(嚴格) OR
entity 內 3+ 字片段在 postContent 出現(寬鬆,中文友善)
- top 5(從 3 增加),給 mira 更多上下文
2026-05-16 11:43:28 +08:00
Leo
94368ec981
fix(mira): 4 bug — popup 在 edit / 思考 indicator 條件 / RAG / edit @mira
...
leo 試用 P0 後反饋的 4 個問題:
bug #1 : popup 編輯時沒有,更擠
- EditingArea 元件加 ⇱ 放大 button + popup overlay(共用 PostComposer 的 popup pattern)
- 影響:所有 edit / reply 模式現在都有放大編輯
bug #2 : Mira 思考中很久(即使沒 @mira)
- root cause: onAiTriggered(pageName) 在 PostComposer 永遠 fire,會在每篇貼文觸發
thinking indicator UI
- 修:移到 if (hasMiraMention) 分支內。沒 @mira → 不顯示 thinking
- wiki_synthesis 仍每篇都跑(背景靜默)但不顯示 thinking,避免 leo 誤會
bug #3 : Mira reply 不知道有 wiki,無狀態
- 加 fetchRelevantWikiContext: 撈所有 type=index-entry blocks,用 entity 名稱
keyword match against post content,取 top 3 整篇 markdown 餵進 prompt
- prompt 加規則「如果 leo 提到的 entity 你已有 wiki 知識,請主動引用」
- 對應 leo「應該以擁有知識庫的專人來回覆」
bug #4 : edit 時 @mira 沒反應
- PostEditor.save / BlockEditor.saveEdit / ReplyLine.save 三處都加 hasMiraMention 偵測
- 條件:新內容含 @mira 且舊版沒有 → 觸發(避免重複編輯重複 trigger)
placeholder 加 hint「@mira 呼叫 Mira 回覆」。
2026-05-16 11:07:34 +08:00
Leo
8d4c3a3464
feat(mira): P0 河道完善 3 task — Mira 頭像 / @mira 選擇性回覆 / 編輯器 popup
...
對應 tasks.md backlog #5a / #5b / #5c(leo 2026-05-16 P0),design.md §3.6.5。
#5a Mira 發文獨立頭像
- 新 MiraAvatar 元件(紫色漸層圓 + 🤖 emoji)
- isMiraSource() 判斷 post 來源是 leo(km-writer-direct/logseq/mobile/web/tg/rss)
還是 mira(ai-* / mira-* / 其他 test sources)
- PostCard header:showMira ? Mira 頭像 + 名「Mira」 : leo 頭像 + leo 名
#5b @mira 選擇性回覆(撤回每篇 auto-reply)
- 新 hasMiraMention() regex:偵測文字含 @mira(前後可有標點)
- PostComposer / BlockEditor / ReplyLine 三處 submit:只有 @mira 時 triggerAiReply
- triggerAiReply prompt 加 topic 抽取(@mira 後第一段到標點)+ scope hint
- wiki_synthesis trigger 跟 @mira 無關,每篇都跑(KB 副本同步)
- 不擋手動筆記(leo 隨手寫不需要 mira 每篇都回)
#5c 編輯器 popup 放大
- composer 加 ⇱ 放大按鈕 → 切到 fullscreen overlay popup
- popup 含大 textarea + 同 markdown toolbar + 同 submit 邏輯
- ⌘+Enter 發布、Esc 收起、外點 backdrop 收起
- 對應 leo「寫長文 textarea 太小」需求
CSS 加 .mira-avatar-mira / .mira-composer-popup-* 系列。
TS check pass。
2026-05-16 10:35:32 +08:00
Leo
0f2a00e0d5
ci(landing): auto-deploy to CF Pages on push to main
...
接好 leo 反饋的「Pages auto-deploy 沒接」坑。新增 .github/workflows/deploy-landing.yml:
- push 到 main 且 landing/ 有變動 → build + 部署
- workflow_dispatch 也可手動觸發
- 用既有的 CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID secrets
- 用 cloudflare/wrangler-action@v3 標準 action
下次 leo 推 landing 改動就會自動 deploy,不用 wrangler pages deploy 手動跑。
2026-05-16 09:29:57 +08:00
Leo
3689f30409
fix(mira): [pageName] h1 顯示 entity 名 + listing dedupe by entity
...
兩個 leo 反饋的 UI bug:
1. wiki/[pageName] 對 index-entry 渲染時,h1 用 block.content(整篇 markdown)
會把整個內容塞進 h1。改:wiki-page 用 content 當 entity 名;其他類型
(index-entry/schema/log)用 page_name 剝 `wiki-` / `index-` prefix。
2. listing「Wiki Pages (21)」累積式設計造成同 entity 多版顯示為多張卡,雜亂。
改:用 useMemo dedupe by entity(content)— 每 entity 一張卡顯示最新版,
標題顯示「N 版累積」當 N>1。原始 21 筆 → 現在約 6-7 個 unique entity。
2026-05-16 09:03:45 +08:00
Leo
64193f2aa5
feat(mira): wiki listing 加 Index Entries section(CC navigation 入口)
...
leo 反饋:原本只看到 wiki-page 列表沒看到 per-entity index-entry,
不知道 CC 從哪入口。新增 section 列出所有 type=index-entry blocks,
標題用 entity 名稱(剝 `index-` prefix),點進去看完整 markdown 摘要。
對應 design.md §3.5.12.4.2 雙層 outliner(v1.6):
- 概覽層:index-entry markdown(含「段落 outline」/「涵蓋面向」等)
- 完整 outliner:wiki page 自身(7B.3g 已實現的樹狀渲染)
部署:arcrun-landing.pages.dev(手動 wrangler pages deploy)。
2026-05-14 18:01:55 +08:00
Leo
bc6360ccfc
feat(arcrun): http_request body_json + error heuristic; mira feed fire-and-forget
...
http_request 零件擴展(registry/components/http_request):
- 加 body_json 物件欄位(內部 JSON.stringify),yaml 端不用手組 JSON 字串
- 新增 JSON 回應的 error 欄位偵測 → 若 body 含 `{"error":"..."}` 則零件回 success=false
解 cascade bug:mira_feed_watcher 用 http_request trigger wiki_synthesis,
原本 4xx response 也被當 success,ON_SUCCESS 鏈會誤觸發
根因架構債:host fn 沒回 HTTP status code(arcrun.md 列為 P1 follow-up)
landing 河道 feed (landing/app/mira/feed/page.tsx):
- 加回 triggerWikiSynthesis fire-and-forget 對 cypher.arcrun.dev/webhooks/named/
wiki_synthesis/trigger 公開觸發 endpoint(arcrun-native,非 mira-specific route)
- 不走 watcher 是因為 cypher-executor 自己 fetch 自己 workers.dev URL = CF 1042
self-fetch 擋
watcher 仍存在當 cron backup,但目前因 self-fetch 1042 不會真正觸發下游
wiki_synthesis(arcrun.md 列為 P1 follow-up)。
2026-05-14 16:06:46 +08:00
Leo
8ab6f8a66b
fix(cypher): interpolateString single-ref array/object pass-through (P0 #11 )
...
mira_feed_watcher 第一輪 cron tick 跑 264ms 完成但 0 raw 處理 — 挖到 root cause:
interpolateString 看到模板就 string.replace,非 string 值(如 kbdb_get 回的
blocks 陣列)一律 JSON.stringify。所以 `items: "{{list_raws.blocks}}"` 把
陣列轉成字串給 filter 零件,filter 收到字串 != array → items 被忽略 →
FOREACH 跑 0 次 → watcher 看似成功實則空跑。
修:interpolateString 加 single-ref pass-through —— 若整個值是純單一 `{{x}}`
引用,回 raw value(保留 array / object 型別)。多 ref / 混合文字仍 stringify。
對應 SDD: arcrun.md 三-A P0 #11。
下一輪 cron tick 應該真正處理 raws,加 wiki-processed tag。
2026-05-14 14:54:26 +08:00
Leo
711af5dbf2
feat(arcrun): kbdb_get 加 type/source/user_id filter
...
之前只支援 block_id / page_name,撈「source=km-writer-direct 的 note」這類
跨 page 查詢做不到。Wiki UI 7B.3g 跟 mira_feed_watcher 都要用 client-side
filter 繞,違反「邊用 arcrun 邊修」原則。
擴 contract:保留既有 block_id (mode A) + page_name (mode B),新增純 filter
mode C:type / source / user_id 任意組合。同時 page_name + filter 也允許組合。
驗證:source=km-writer-direct&type=note&limit=5 撈到 leo 5 筆未處理河道貼文。
對應 SDD: arcrun.md 三-B 新零件 checklist + tasks.md 7B.3h(mira_feed_watcher
正在組)。
2026-05-14 14:18:43 +08:00
Leo
9560485937
feat(cypher): add scheduled() handler — arcrun-native cron 排程基建
...
對應 arcrun.md 三-A P1 #3。
緣由:cron 零件存在但只做 expression validation,沒有真正的排程跑。leo 指出
「邊用 arcrun 邊修,不要 workaround」— 撤回前一輪的 /mira/wiki-from-raw
mira-specific route(違反 mira CLAUDE.md §1.5 一律 arcrun-native),改補
真正的 cron infra。
加入:
- src/lib/cron-match.ts — 5 欄位 cron matcher(* / N / */N / a-b / a,b 組合)
- src/scheduled.ts — handler:掃 KV cron-idx: prefix,比對 controller.scheduledTime
→ executeWebhookGraph 背景跑
- routes/webhooks-named.ts — acr push 時偵測首節點 cron → 存 cron_expr 到 record
+ 額外寫 cron-idx:{api_key}:{name} 輕量索引;DELETE 一併清理
- src/index.ts — export default 改 { fetch, scheduled }
- wrangler.toml — [triggers] crons = ["* * * * *"](每分鐘 tick)
- wrangler.toml — workers_dev = true 供 self-fetch self-trigger 用
- tests/arcrun-test/cron_heartbeat.yaml — 健康監控 workflow(每分鐘 fire + set 節點)
撤回:
- 刪 src/routes/mira.ts(mira-specific workaround)
- types.ts 拿掉 MIRA_CONFIG
- index.ts 拿掉 miraRouter wire
- landing/app/mira/feed/page.tsx 拿掉 triggerWikiSynthesis 呼叫
下一輪:mira_feed_watcher.yaml(mira side),可能要先補 kbdb_get filter +
CALLS_SUBFLOW wire(arcrun.md 列為跟進)。
2026-05-14 14:04:57 +08:00
Leo
660b32eafd
feat(mira): 河道 → wiki 自動化(fire-and-forget 觸發 wiki_synthesis)
...
對應 polaris/mira/.agents/specs/mira-app/tasks.md 7B.3h(簡化版)。
原計畫用 arcrun cron 零件 → cypher-executor scheduled() handler,但發現
cron 零件只是 validator,cypher-executor 還沒實作 scheduled()。為了不擋
「河道書寫 → 自動產 wiki」這條 UX,先做 fire-and-forget 版本:
- 新 cypher-executor route POST /mira/wiki-from-raw
- body: { raw_block_id }
- server 端從 MIRA_CONFIG secret 補 partner key / mira_token / 三個 block IDs
- waitUntil 背景跑 executeWebhookGraph,立刻回 202
- landing 河道 post composer 成功寫 raw 後 fire-and-forget triggerWikiSynthesis()
跟既有 triggerAiReply() 同範式
- types.ts 加 MIRA_CONFIG?: string
部署後需手動:
echo '{"service_api_key":"ak_...","data_api_key":"ak_...","schema_block_id":"...","skill_block_id":"...","entities_block_id":"...","mira_token":"..."}' \
| wrangler secret put MIRA_CONFIG
UX:河道貼一則 → AI reply 30s 內 → wiki 60-90s 內出現在 /mira/wiki。
arcrun.md 記 P1 #3:cypher-executor 加 scheduled() handler,那是真正的
cron 路線,封測前不擋。
2026-05-14 13:50:13 +08:00
Leo
933ae6cb13
feat(mira): 7B.3g wiki UI 樹狀渲染 + 跨 wiki 連結
...
對應 polaris/mira/.agents/specs/mira-app/design.md §5.2 + §3.5.12。
`/mira/wiki/[pageName]`:
- 抓 wiki-page 後平行撈所有 wiki-paragraph / triplet / wiki-page,client-side 用 parent_id filter
(KBDB 沒 parent_id server filter,且 tag filter 還有 KI-3 bug)
- 按 facet 分區渲染:facet 標題 + paragraph markdown + 該段的 triplets
- facet 預設展開(看一篇要看內容)/ triplets 預設折疊(leo Logseq outliner 習慣)
- **triplet A/B 拆字串 「A >> 關係 >> B」**,若 A 或 B 對得上既有 wiki entity → render 成 <Link>
跨 wiki 跳轉,是 Wikipedia-like 體驗的關鍵
- fallback:非 wiki-page block(schema/index/log 等)直接 render content
`/mira/wiki`:列表用 wiki-page 的 content (= entity 名稱) 當標題,不是 page_name slug。
mira.css 加 `.mira-wiki-detail` 不破版 + h2 底線,避免長 cypher 字串撐爆右邊界。
TS check pass。
2026-05-14 13:35:54 +08:00
Leo
d6d2cecfb5
fix(cypher): resumeFromPaused 漏 node-id namespace 導致下游模板找不到 paused 結果
...
mira 7B.3f PATCH 測試踩到:classify 跟 compose 都是 claude_api(兩次 paused/resumed),
upsert_index_entry config 寫 `{{compose_index_entry.data.text}}`,但 PATCH 跑出的
block content 是字面 `{{compose_index_entry.data.text}}` —— 模板沒被替換。
根因:resumeFromPaused 把 callback_result spread 到 top-level,但漏了
`[paused_node_id]: callback_result` 的 namespace 包裝。同步路徑的 propagateCtx
有做這件事,resume 路徑沒做,行為不一致。
修:mergedContext 加 [paused_node_id]: callback_result 一行,跟 propagateCtx 對齊。
arcrun.md 同步補三-B「新零件 checklist」+ 三-C「workers_dev=true 全 component
自動化」收尾紀錄。
2026-05-14 12:06:59 +08:00
Leo
c830897988
fix(cypher): register kbdb_upsert_block + workers_dev=true on all 32 components
...
兩件事一起補:
1. cypher-executor 的 WASM_HTTP_RUNNER_IDS 白名單漏加 kbdb_upsert_block。
mira 7B.3f 端對端 debug 才發現 upsert 節點直接拋「找不到零件」。
建零件時要記得同步註冊到 loader。
2. .component-builds/*/wrangler.toml (×32) 全部加 workers_dev = true。
解決每次新部署 component 都要去 CF Dashboard 手動啟用 workers.dev URL
的痛點(leo 今天踩這個踩了好幾次)。zero-touch deploy + free tier 友好,
符合 arcrun 「fork 後 self-host 用 free tier 跑得起來」的核心目標。
對 mira 端:wiki_synthesis.yaml 還原回完整鏈
(lookup → compose → upsert + 平行的 FOREACH paragraphs/triplets)。
2026-05-14 11:37:28 +08:00
Leo
6f6e31dbee
fix(cypher): deploy P0 #9/#10/#10衍生 fixes (workers.dev URL + nested FOREACH + propagateCtx)
...
arcrun.md 一直標 ✅ 已解決但 fix 在 working tree 沒推。今天 mira 7B.3f 端對端
跑不通才發現 production 還是舊版(fetch *.arcrun.dev 同 zone 自循環 → 522)。
涵蓋:
- P0 #9 : wasmWorkerUrl() 從 *.arcrun.dev 改 arcrun-{kebab}.{WORKER_SUBDOMAIN}.workers.dev
+ types.ts/wrangler.toml 加 WORKER_SUBDOMAIN binding (uncle6-me)
+ auth-dispatcher.ts 用新 signature
- P0 #10A: interpolateData() 拆 interpolateString + interpolateValue 遞迴 nested
- P0 #10B: propagateCtx() helper 把上游 output spread + 用 node id namespace 存
讓下游能 {{node_id.data.text}} 永不被覆蓋。5 個 edge type 全用此 helper
- P0 #10C: FOREACH 找 iterable 先看 result 沒有再看 ctx + 掃 nested object 一層
解雙重 FOREACH(paragraph→triplets)內層跑 0 次
rules/01-tech-stack.md + rules/03-component-architecture.md 同步補 workers.dev 慣例說明。
未推 5 個 worker 改動,今晚才發現實際沒部署過。
2026-05-14 11:02:44 +08:00
Leo
4e746986b4
feat(arcrun): add kbdb_upsert_block component for idempotent block writes
...
對應 mira 7B.3f:per-entity index-entry 維護需要「找有則 PATCH 沒找到 POST」,
arcrun workflow 沒 IF/branch 能力(已知限制 #1 + 新 P1 #1),用 kbdb_upsert_block
零件把分支邏輯封進零件內:GET /blocks?page_name=X → user_id filter → 找到 PATCH 沒找到 POST。
page_name 當 idempotency key,未來其他「找有則改沒則建」場景共用。
SDD:polaris/mira/.agents/specs/mira-app/design.md §3.5.12.4.1
matrix/arcrun/.agents/specs/arcrun/arcrun.md 三-A P1 #1 + 三-B 新零件加入紀錄
2026-05-14 10:18:21 +08:00
Leo
519423cb0d
feat(arcrun): mira wiki page with tag filter + accumulated WIP
...
- landing/app/mira/wiki: tag=mira-wiki list now shows all wiki paragraphs
(depends on KBDB tag filter exposed in matrix/kbdb commit, separate repo)
- landing: app/mira hub + feed split + various WIP from prior sessions
- registry/components: claude_api / kbdb_create_block / kbdb_get / km_writer /
platform_crypto / auth_oauth2 contracts + main.go (accumulated)
- .component-builds: pkg-lock updates + index.ts adjustments (WIP)
- .agents/specs/arcrun/frontend-redesign: design notes
- docs/test_credentials, docs/user_requirements/arcrun-landing-page: WIP docs
- cypher-executor: auth-dispatcher / wasi-shim adjustments (WIP)
Includes accumulated work from prior sessions plus the wiki UI tag-filter
update that surfaces the AI-generated wiki paragraphs at /mira/wiki.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-07 16:52:01 +08:00
Leo
e8fca33f80
feat(cypher): 3-node wiki workflow end-to-end (FOREACH + nested interp + unified parsing)
...
Three platform-level improvements that together enable the full
"草稿 → LLM 整理 → KBDB" wiki ingest workflow via cypher binding:
## 1. Nested interpolation in node.data
Previously {{var}} only supported top-level keys, so {{item.content}}
literal-passed through. Now supports dot-path:
{{paragraph.content}} → ctx.paragraph.content
{{paragraphs.0.entity}} → ctx.paragraphs[0].entity
Non-string values (object/array) JSON.stringify automatically.
## 2. 對每個 X cypher binding syntax
'A >> 對每個 paragraph >> B' parses into FOREACH edge with
iterator='paragraph'. graph-builder.ts strips the iterator from label
before edge type resolution. Backwards compatible: bare '對每個' still
defaults to item.
## 3. FOREACH preserves outer context
itemContext was previously {...result, [iter]: item}, dropping
top-level api_key etc. Now {...outerCtx, ...result, [iter]: item} so
{{api_key}} interpolation works in foreach body.
## 4. Unified recipe output parsing (sync + resume)
Extracted parseRecipeOutput() helper used by both sync claude_api
result + workflow resume callback. Strips ```json fence, parses,
spreads parsed top-level fields into result so downstream FOREACH
finds 'paragraphs' (not buried in data.paragraphs).
paused state now stores recipe_output_format + required_fields so
resume route can apply same parsing as sync path.
End-to-end verified:
- input(草稿+api_key) → synth(claude_api+recipe) → 對每個 paragraph → write_wiki(kbdb_create_block)
- Real Claude synthesis on Mira daemon: 3 triplets + 2 paragraphs
- Both paragraphs written to KBDB as wiki-page blocks (verified GET)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-07 16:23:02 +08:00
Leo
497f92a268
feat(arcrun): recipe system + resumable workflow + component registry canon
...
Three new platform capabilities + one component (kbdb_get) to enable
real AI workflow execution through cypher binding YAML.
## Recipe System (容器 + Recipe 模式)
SDD: .agents/specs/recipe-system/
- prompt_recipe schema (Zod): fragments + inputs + assembly + output
- recipe-expander.ts: expand recipe ref → real prompt by fetching KBDB blocks
+ pulling context fields with transforms (pluck_content / extract_field / etc)
- 7 transform whitelist: json_array / to_string / join / markdown_list /
extract_field / first / pluck_content
- graph-executor hooks: detect node.data.recipe → expand → inject into ctx
- output JSON parser (with markdown fence stripping for Claude-wrapped JSON)
- Stored in RECIPES KV under prompt_recipe:{name}
## Resumable Workflow (webhook callback resume)
SDD: .agents/specs/resumable-workflow/
- WorkflowPaused class + paused-runs.ts (persist/load/consume in EXEC_CONTEXT KV, 24h TTL)
- graph-executor: detect {pending:true, task_id} → persist state → throw WorkflowPaused
- cypher-handlers: catch → return {success:true, paused:true, task_id, run_id}
- POST /workflows/resume route: consume KV state → resumeFromPaused()
- Auto-inject callback_url for claude_api nodes (PUBLIC_BASE_URL or default cypher.arcrun.dev)
- claude_api/main.go: forward callback_url to Mira daemon, default timeout 25s→120s
- Idempotent (consume = load+delete)
## Component Registry Canon
SDD: .agents/specs/component-registry-canon/
- Add POST /components/index-only endpoint (metadata-only, no wasm/sandbox)
- Backfill script (mjs): scan registry/components/*/contract.yaml → submit to KV
- register-component.sh: SSOT for local + CI hook (deploy.yml change in next commit)
- Drop R2 dead storage from submitComponent + types + wrangler
- Schema relaxed: category enum + auth/ai/platform; cold_start 50→500ms; size 2→8MB
## kbdb_get component
- registry/components/kbdb_get/: TinyGo WASM, two modes (block_id / page_name list)
- .component-builds/kbdb_get/: WASI shim worker (kbdb-get.arcrun.dev)
End-to-end validation: AI uses MCP execute_workflow with recipe ref →
cypher-executor expands prompt from KBDB schema/skill blocks + drafts →
claude_api calls Mira daemon → daemon callback fires resume route →
workflow continues. Verified with real 2KB+ Karpathy LLM Wiki draft.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-07 15:52:19 +08:00
Leo
e2221161a8
fix(wasi-shim): re-read memory.buffer after await in all host functions
...
WebAssembly memory can grow (and return a new ArrayBuffer) during an
async host function call. Reading memory.buffer before await and using
it after the await causes host functions (kv_get / crypto_decrypt /
crypto_sign_rs256 / http_request) to write into a detached buffer,
so the WASM side reads zero bytes → empty string → JSON parse failure.
Fix: read inputs before await using the current buffer snapshot,
then call memory.buffer again after the await to write the result.
For crypto_sign_rs256 and http_request, input arrays are copied
before await so the snapshot can be released.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-24 17:13:03 +08:00
Leo
83a01fe028
feat(auth_static_key): auto-encode Basic Auth; seed gemini/trello/mailgun recipes
...
- auth_static_key WASM: 偵測 Authorization header "Basic <x>:<y>" (含冒號
的 user:pass 原文), 自動 base64 編碼; 無冒號則維持原樣 (向後相容
已 base64 過的值).
這涵蓋 twilio / jira / mailgun 三個 Basic Auth recipe, 用戶 recipe
只需寫 'Basic {{secret.user}}:{{secret.key}}' 直覺語法.
- 新增 3 個 recipe (auth-recipe-seeds.ts):
• gemini — static_key / header x-goog-api-key (單 secret)
• trello — static_key / QUERY key+token (雙 secret, 第一個 query
injection 測試覆蓋)
• mailgun — static_key / HEADER Basic api:<key> (雙 secret Basic Auth)
- hook fix (pre-write-guard.sh): 放行 auth-recipe-seeds.ts 的 {{secret.X}}
字面值. 該檔是 RECIPES KV 的 seed 資料, 不是 TS 展開邏輯;
真正展開仍在 WASM 完成.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-22 08:29:02 +08:00
Leo
258ef38f7a
fix(ci): regenerate tier2 pnpm-lock.yaml after adding wrangler
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 21:21:18 +08:00
Leo
200a8e14dc
fix(ci): add wrangler to tier2 devDependencies
...
tier2 deploy failed with ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL
because cypher-executor / registry / builtins package.json
didn't list wrangler; local dev worked via global install only.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 21:05:55 +08:00
Leo
2bfe16ba61
ci(deploy): drop setup-node pnpm cache (fails on legacy Workers)
...
setup-node's cache: 'pnpm' requires the cache-dependency-path to
resolve, but several legacy .component-builds/* Workers only ship
package-lock.json (historical mixed state — see rule
05-deploy-convention.md). With pnpm-lock.yaml missing, setup-node
fails fast with "Some specified paths were not resolved" before
the install step's fallback logic even gets a chance to run.
Since each Worker deploy takes ~30s on its own runner, skipping
the per-job cache costs nothing in practice.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 20:52:39 +08:00
Leo
38b42a2662
ci(deploy): fetch full history + fallback when base sha unreachable
...
fetch-depth: 2 is too shallow — a batch push of 10 commits (like
Phase 1-6 commit chain) leaves github.event.before outside the
fetched range, so git diff returns empty and nothing deploys.
- Set fetch-depth: 0 (full history) so diff always has a reachable
base.
- Added git cat-file -e check: even with full history, force-pushes
or orphan base SHAs trigger a "deploy all" fallback instead of
silently skipping.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 20:39:54 +08:00
Leo
4516cdee4b
feat: add landing page + builtins Worker + BETA_TEST guide + README
...
- landing/: Next.js 15 app for arcrun.dev (dashboard, integrations,
API docs, login). Deploys via Cloudflare Pages — CI scan skips
this via pages_build_output_dir marker.
- builtins/: minimal Hono Worker at arcrun-builtins (/init for
one-shot component registry seeding). initComponents logic is
flagged stale in src/index.ts for future rewrite.
- BETA_TEST.md: pre-launch validation playbook.
- README.md: updated to match current arcrun.dev / acr CLI flow.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:52:41 +08:00
Leo
13b01328c1
docs: add SDD specs + user requirements + tests
...
- .agents/specs/: spec-driven-dev docs for arcrun MVP, auth-recipe,
credential-primitives-wasm (active refactor), landing-page,
sdk-and-website, u6u-core-mvp, u6u-platform-evolution.
- .agents/steerings/tech.md: detailed tech stack rationale.
- docs/user_requirements/: long-form requirements incl. credential
primitives, pages spec, py strategy analysis.
- tests/: end-to-end harness scaffolding.
These are the durable context backing CLAUDE.md's SDD protocol.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:48:24 +08:00
Leo
cadcaef3b0
ci: generic scan-based deploy workflow for all Workers
...
Rewrites deploy.yml to auto-discover every wrangler.toml in the repo
(excluding node_modules and Pages projects) rather than hardcoding
each Worker. Adding a new Worker only requires the new directory —
no workflow changes.
- Two-tier fanout: tier1 = .component-builds/* (WASM rebuild +
deploy in parallel), tier2 = orchestration Workers (cypher-executor,
registry, builtins) that depend on tier1 via service bindings.
- Diff-aware on push: only changed Worker dirs deploy; changes under
registry/components/{name}/ cascade to .component-builds/{name}/.
- workflow_dispatch inputs: force_all (deploy everything) and only
(comma-separated allow-list).
- TinyGo 0.40.1 rebuilds WASM from registry/components/{name}/main.go
so deployed binaries always match source.
- max-parallel: 5 to stay under Workers API rate limit.
Adds .claude/rules/05-deploy-convention.md documenting the
"new Worker = new dir + wrangler.toml" invariant.
Per .agents/specs/arcrun/credential-primitives-wasm Phase 6.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:42:14 +08:00
Leo
066652f6e8
feat(cli): add recipe / auth-recipe commands + update push/creds/init
...
- New: acr recipe (push/list/get a user recipe to RECIPES KV)
- New: acr auth-recipe (inspect platform-seeded auth recipes)
- push/creds/init/parts/config updated to match the new cypher-executor
routing (/auth, /credentials, webhooks-named).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:40:57 +08:00
Leo
500d796573
feat: 15 logic component Workers + cypher-executor auth/credentials routing
...
Component Workers:
- Deploys if_control, switch, filter, merge, try_catch, wait, set,
array_ops, string_ops, number_ops, date_ops, validate_json,
ai_transform_compile, ai_transform_run, foreach_control as
independent Workers, backing cypher-executor's SVC_* service
bindings (fast internal RPC for logic components).
cypher-executor routing:
- New routes: /auth (recipe resolution), /credentials (CRUD),
/webhooks/named (user-friendly alias for cmp_/rec_ hashes).
- auth-recipe-seeds.ts: 20 pre-built platform auth recipes
(Google Sheets, Gmail, Telegram, etc.) seeded into RECIPES KV.
- graph-executor + cypher-handlers + search-nodes updated for
the new resolution chain.
- scripts/seed-auth-recipes.ts: one-shot tool to push seeds to KV.
- wrangler.toml: 15 SVC_* bindings wired to the new logic Workers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:40:02 +08:00
Leo
6a3219e51b
feat(components): move 6 API components to independent WASM Workers
...
Deploys gmail, telegram, line_notify, google_sheets, http_request, cron
as independent Cloudflare Workers at {name-kebab}.arcrun.dev. Each
wraps the TinyGo WASM from registry/components/{name}/main.go via
wasi-shim cross-import (Method A).
component-loader no longer carries BUILTIN_API_RECIPES — those
hardcoded gmail.googleapis.com / api.telegram.org / sheets / line-notify
endpoints all lived in TS, violating "all business logic in WASM".
Resolution chain now routes the 6 canonical IDs straight to their
{name}.arcrun.dev Worker URLs via WASM_HTTP_RUNNER_IDS.
Per .agents/specs/arcrun/credential-primitives-wasm Phase 3.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:36:06 +08:00
Leo
8c14562a2f
feat(auth): auth_service_account WASM primitive + remove TS JWT signer
...
- registry/components/auth_service_account: TinyGo impl for Google
Service Account (JWT-bearer → token exchange) and base structure
for AWS SigV4.
- .component-builds/auth_service_account: independent Worker at
auth-service-account.arcrun.dev, extends wasi-shim with an
http_request host function for the token exchange step.
- Delete cypher-executor/src/lib/wasm-executor.ts (legacy, replaced
by component-loader WASM HTTP runner path).
- credential-injector.ts service_account branch now throws — all
service_account recipes must route through auth-dispatcher.
Per .agents/specs/arcrun/credential-primitives-wasm Phase 2.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 17:34:42 +08:00
Leo
18f04448ce
feat(auth): auth_static_key WASM primitive + host functions
...
- wasi-shim gains kv_get / crypto_decrypt / crypto_sign_rs256 host
functions with strict boundary (ENCRYPTION_KEY never exits Worker).
- registry/components/auth_static_key: TinyGo impl for API-key /
Bearer / Basic Auth recipes (80% of supported services).
- .component-builds/auth_static_key: independent Worker at
auth-static-key.arcrun.dev, imports wasi-shim cross-directory.
- cypher-executor/auth-dispatcher routes static_key recipes to the
new Worker instead of credential-injector TS.
Replaces TS credential injection per
.agents/specs/arcrun/credential-primitives-wasm Phase 1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 16:54:18 +08:00
Leo
6ee6fee8b9
chore: remove duplicate credentials/ dir + add CLAUDE.md + .claude rules
...
credentials/ was a leftover duplicate — all credential routes already live
in cypher-executor/src/routes/credentials.ts. Adds the SDD protocol,
tech-stack, forbidden-list, component-architecture, and progress rules
that guide Phase 1-6 refactors.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 16:53:26 +08:00
Leo
40df4025a6
chore: gitignore .DS_Store
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-20 16:52:52 +08:00
Leo
7b18387113
feat: config field in /cypher/execute — node-level component override
...
- /cypher/execute now accepts separate `config` field:
{node_name: {component: "cmp_19e62efd", ...staticParams}}
- graph-builder reads config[node].component to override componentId
(supports cmp_ hash, rec_ hash, or canonical_id)
- config[node] other fields become node.data (static params merged at runtime)
- acr run now sends workflow.config as separate `config` (not flattened into context)
- context is now only --input dynamic params
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 18:42:26 +08:00