# Implementation Plan: arcrun MVP ## Overview 依照 Design 的七個 Phase 實作。原則:最小異動,不重寫現有邏輯,只 cherry-pick + carve-out + supplement。 所有 Phase 1–3 工作在 `matrix` repo 對應目錄驗證後再搬到新 repo。 **PR #2(claude/review-mvp-specs-8Bvdu)狀態:** 初始實作已提交,已修復以下問題後準備 merge: - CF API Token 傳至 arcrun.dev 安全問題(已修復) - 加密 fallback 格式不相容(已修復) - submitComponent KBDB 依賴(已修復,改用 SUBMISSIONS_KV) - Webhook 路由缺 analytics(已修復) - `require()` 在 ES module 中(已修復) - api 類零件 `no_network_syscall: true` 錯誤(已修復) --- ## Phase 1:搬移與清理 - [x] 1. 建立 `arcrun` 獨立 repo 並初始化 - [x] 1.1 在 GitHub 建立新的 public repo(使用 matrix monorepo 的 `arcrun/` 子目錄代替,PR #2) - [x] 1.2 設定 `.gitignore`(排除 `node_modules/`、`.wrangler/`、`credentials.yaml`、`~/.arcrun/`) - [x] 1.3 從 `matrix` cherry-pick 四個目錄: - `matrix/cypher-executor/` → `arcrun/cypher-executor/` - `matrix/u6u-core/credentials/` → `arcrun/credentials/` - `matrix/u6u-core/registry/components/` → `arcrun/registry/components/` - _Requirements: 1.6_ - [x] 2. 清理 `cypher-executor/wrangler.toml` - [x] 2.1 移除 9 個 InkStone Service Bindings(KBDB、REGISTRY、CLINIC_*、AICEO、MINI_ME) - [x] 2.2 確認保留:`EXEC_CONTEXT`、`WEBHOOKS`、`WASM_BUCKET`、`AI` - [x] 2.3 新增 `CREDENTIALS_KV` 與 `ANALYTICS_KV` KV namespace binding - [x] 2.4 更新 `name` 為 `arcrun-cypher-executor` - _Requirements: 1.1, 1.2, 1.3_ - [x] 3. 改寫 `cypher-executor/src/lib/component-loader.ts` - [x] 3.1 移除對 MINI_ME、KBDB、InkStone bindings 的 hardcode - [x] 3.2 實作三層邏輯:builtin Map → WASM_BUCKET R2 直讀 → 結構化錯誤 - _Requirements: 1.4, 1.5_ - [x] 4. 移除對 InkStone bindings 的依賴程式碼 - [x] 4.1 刪除 `autoPublishMissing.ts`(依賴 REGISTRY binding) - [x] 4.2 移除所有 `env.KBDB`、`env.REGISTRY`、`env.MINI_ME`、`env.AICEO`、`env.CLINIC_*` 引用 - _Requirements: 1.1, 1.5_ - [ ] 5. 本機驗證 - [ ] 5.1 `cd arcrun/cypher-executor && wrangler dev` 能啟動(無 binding 錯誤) - [ ] 5.2 `GET /health` 回傳 `{ ok: true }` - [ ] 5.3 上傳 `validate_json.wasm` 到 WASM_BUCKET,執行 `POST /execute` 能正常回傳結果 - _Requirements: 1.5, 5.5_ --- ## Phase 2:零件完整度補充 - [x] 6. api 類零件 `no_network_syscall` 修正 - [x] 6.1 gmail、telegram、google_sheets、line_notify、http_request 改為 `no_network_syscall: false` - _Requirements: 2.1_ - [ ] 7. 審查 21 個零件 contract.yaml 並補充 `credentials_required` - [ ] 7.1 確認 gmail、google_sheets、telegram、line_notify 有 `credentials_required`(PR #2 已加入,需驗證格式正確) - [ ] 7.2 確認所有 21 個零件有 `config_example` 欄位 - [ ] 7.3 驗證 `main.go` required 欄位與 `contract.yaml` input_schema.required[] 一致 - _Requirements: 2.1, 2.2, 2.3_ --- ## Phase 3:Credential 注入整合 - [x] 10. `credential-injector.ts` 已實作(`arcrun/cypher-executor/src/actions/credential-injector.ts`) - [x] 10.1 讀取 contract.yaml from R2,解析 `credentials_required` - [x] 10.2 從 `CREDENTIALS_KV` 讀取 AES-GCM 加密 token,注入到 input 對應欄位(inject_as) - [x] 10.3 credential 不存在時拋出結構化錯誤(含 key 名稱與修復步驟) - _Requirements: 3.4, 3.5, 3.6_ - [ ] 11. 驗證 credential 注入整合進 graph-executor - [ ] 11.1 確認 `graph-executor.ts` 在節點執行前正確呼叫 `injectCredentials` - [ ] 11.2 確認注入只影響 WASM input,不修改 WEBHOOKS KV 中儲存的 workflow 定義 - _Requirements: 3.4, 3.5_ - [ ] 12. 端對端測試(手動) - [ ] 12.1 建立 `credentials.yaml`,加入測試 token - [ ] 12.2 執行 `acr creds push`,確認寫入 CREDENTIALS_KV 格式為 `{ encrypted, iv }`(無 `mode: 'base64'`) - [ ] 12.3 執行含 credential 的 workflow,確認 inject_as 欄位正確注入 - _Requirements: 3.4, 3.5_ --- ## Phase 4:CLI 開發 - [x] 13. CLI 專案骨架已建立(`arcrun/cli/`) - [x] 13.1 `package.json`(name: `arcrun`,bin: `acr`) - [x] 13.2 `tsconfig.json`(module: NodeNext) - [x] 13.3 所有 10 個指令已實作骨架 - _Requirements: 4.1_ - [x] 14. `acr init` 已實作,修正項: - [x] 14.1 Standard 模式不再傳送 `cf_api_token` 至 arcrun.dev(只傳 `email`) - [x] 14.2 `require()` 改用 `await import()` 修正 ES module 相容 - [ ] 14.3 **待補**:`acr init` 需詢問 `ARCRUN_ENCRYPTION_KEY` 並寫入 config(目前加密 key 需手動設定) - _Requirements: 4.2, 6.3_ - [x] 15. `acr creds push` 已實作 - [x] 15.1 讀取 `credentials.yaml`,AES-GCM 加密後寫入用戶 CF KV(`cred:{name}`) - [x] 15.2 加密 fallback(base64)已移除,key 不足時直接拋錯提示生成指令 - _Requirements: 4.3, 6.5_ - [x] 16. `acr push` 已實作 - _Requirements: 4.4_ - [x] 17. `acr run` 已實作 - _Requirements: 4.5_ - [ ] 18. `acr validate` credential 檢測邏輯有誤,需修復 - [ ] 18.1 `extractCredentialRefs()` 目前掃描 `{{creds.xxx}}` 語法,但 injection 使用 `inject_as` key - [ ] 18.2 改為讀取 contract.yaml 的 `credentials_required[].key`,與 `cred:{key}` KV 存在性比對 - _Requirements: 4.6_ - [x] 19. `acr parts`、`acr parts scaffold`、`acr parts publish` 已實作 - [ ] 19.1 `acr parts` 中 YAML 解析改用 `js-yaml`(目前用 regex,可能解析失敗) - _Requirements: 4.7, 4.8_ - [x] 20. `acr list` 與 `acr logs` 已實作 - _Requirements: 4.9, 4.10_ --- ## Phase 5:開源發布準備 - [x] 21. README.md 已撰寫(`arcrun/README.md`) - [x] 22. CONTRIBUTING.md 已撰寫(`arcrun/CONTRIBUTING.md`) - [ ] 23. 安全審查(PR merge 前執行) - [ ] 23.1 搜尋 `.workers.dev` InkStone 網域 - [ ] 23.2 確認 wrangler.toml 所有 KV id 欄位留空 - [ ] 23.3 確認 `credentials.yaml` 在 `.gitignore` 中 - _Requirements: 5.4_ - [ ] 24. 發布(安全審查後) - [ ] 24.1 `npm publish`(CLI package `arcrun`) - _Requirements: 5.1_ --- ## Phase 6:Standard 模式 — auth-worker 與用戶 KV 代存取 - [ ] 25. 建立 `auth-worker`(新 Worker,部署至 `api.arcrun.dev`) - [ ] 25.1 建立 `auth-worker/` 目錄,初始化 Hono + wrangler.toml - [ ] 25.2 實作 `POST /register`:接收 `{ email, account_id, kv_namespace_id }` + CF API Token 透過 header 傳入 - **不在 request body 中接收 CF API Token**(Token 透過 header `CF-Api-Token` 傳入,減少 TLS 以外的洩漏面) - 生成 `tenant_id` 與 `api_key`,存入 `ACCOUNTS_KV` - [ ] 25.3 Bindings:`ACCOUNTS_KV` - _Requirements: 6.1, 6.2_ - [ ] 26. 改造 `cypher-executor` 支援 multi-tenant 用戶 KV 代存取 - [ ] 26.1 讀取 `MULTI_TENANT` env var(目前已宣告但未讀取),實作 tenant middleware - [ ] 26.2 `X-Arcrun-API-Key` → 查 `ACCOUNTS_KV` → 取得用戶 cf_api_token + kv_namespace_id → 建立 `CfKvClient` - [ ] 26.3 `CfKvClient` 已實作(`arcrun/cli/src/lib/cf-api.ts`),需移植到 `cypher-executor/src/lib/` - [ ] 26.4 `credential-injector.ts` 改用 userKv 取得加密 credential - [ ] 26.5 webhook 路由注入 userKv - _Requirements: 6.4, 6.5, 6.6_ - [ ] 27. 端對端測試(用戶 KV 隔離) - _Requirements: 6.4, 6.5_ --- ## Phase 7:公眾零件統計與貢獻審核 - [x] 28. Analytics 基礎設施已建立 - [x] 28.1 `execution-logger.ts` 建立,`writeExecutionVerdict` 寫入 `ANALYTICS_KV`(fire-and-forget) - [x] 28.2 `/execute` 路由已整合 `waitUntil(writeExecutionVerdict(...))` - [x] 28.3 `/webhooks/:token/trigger` 路由已補上 `waitUntil(writeExecutionVerdict(...))` - _Requirements: 7.2_ - [ ] 29. registry Worker analytics 端點 - [ ] 29.1 新增 `POST /analytics/record` 路由,原子更新 `ANALYTICS_KV` - [ ] 29.2 `GET /components` 回傳加入 `total_runs`、`success_rate`、`avg_duration_ms` - _Requirements: 7.3, 7.6_ - [x] 30. `author` 欄位已加入 contract.yaml 規格 - _Requirements: 7.1_ - [x] 31. 零件提交審核流程已實作(`arcrun/registry/src/actions/submitComponent.ts`) - [x] 31.1 沙盒驗收流程(sandboxAcceptance.ts):size_check + syscall_scan 已實作;cold_start + gherkin_tests 為 Phase 0 mock - [x] 31.2 `SUBMISSIONS_KV` 儲存元數據,預設 `visibility: author_only` - [ ] 31.3 `PATCH /submit/:id/approve` → 將 visibility 改為 `public`(待實作) - [ ] 31.4 Gherkin 測試執行(取代 mock) - _Requirements: 8.2, 8.3, 8.4, 8.5_ --- ## 待辦(無相依順序,可平行處理) - [ ] A. `builtins/` 清理:`initComponents.ts` 仍用舊的 HTTP endpoint 模式上架零件(`buildComponentDefs` 含 URL),應改為呼叫 `POST /submit` 送 WASM binary + contract,或直接移除 builtins(功能已整合到 registry) - [ ] B. `validate` 指令 credential 檢測邏輯修復(見 Phase 4 Task 18) - [ ] C. `acr init` 加入 `ARCRUN_ENCRYPTION_KEY` 設定步驟 - [ ] D. `acr parts` YAML 解析改用 `js-yaml` --- ## Notes - 標記 `*` 的子任務為選填,可跳過以加速 MVP 交付 - Gherkin 測試執行(sandbox 步驟 d)為 Phase 0 mock,Phase 7 補充 - cold-start 測量(sandbox 步驟 b)為 Phase 0 mock,Phase 2 補充 - CF API Token 永遠不離開用戶本機,arcrun.dev 只收 email + account_id + kv_namespace_id