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>
This commit is contained in:
uncle6me-web
2026-06-03 15:52:38 +08:00
commit 922a57fe34
485 changed files with 89356 additions and 0 deletions
@@ -0,0 +1,180 @@
# Requirements Document
## Introduction
arcrun MVP 是從 `matrix` monorepo 中 cherry-pick 出最小可獨立運作的 AI 工作流執行引擎,目標是作為**獨立開源 repo**(`arcrun`)發布。
**背景**`matrix` 因為同時承載 InkStone 內部服務(KBDB、CLINIC_*、AICEO、MINI_ME 等)與核心執行引擎,複雜度過高,難以讓外部開發者使用或貢獻。MVP 的任務是將執行引擎從內部服務中解耦,讓任何人都能自行在 Cloudflare 上部署一套完整的 AI 工作流系統。
**護城河邏輯**
- 開源:cypher-executor(執行引擎)、WASM 零件庫(21 個)、credentials Worker、CLI
- Hosted SaaS:一行指令註冊取得 API Key,直接使用公眾零件庫,無需部署任何 Worker
- 閉源(InkStone 付費):KBDB 向量搜尋、graph 查詢、Persona SDK、MatchGPT
**不在此次範圍**:KBDB 整合、前端管理介面、向量搜尋、新增 WASM 零件。
---
## Glossary
- **cypher-executor**:原 `matrix/cypher-executor`,執行 workflow 的 Cloudflare Worker。開源版移除所有 InkStone 內部 Service Binding,只保留 KV / R2 / Workers AI。
- **component(零件)**:以 TinyGo 編譯的 `.wasm` 檔案,以 WASI preview1 / stdin-stdout JSON 為 I/O 模型。
- **component.contract.yaml**:每個零件的規格宣告,含 `canonical_id``input_schema``output_schema``gherkin_tests`,開源版補充 `credentials_required``config_example`
- **credentials Worker**`arcrun/credentials`,以 AES-GCM 加密存取 API token,部署在用戶自己的 CF 帳號。
- **WASM_BUCKET**arcrun.dev 的 R2 bucket,儲存所有公眾 `.wasm` 零件二進位,由 Arcrun 負責。
- **USER_KV**:用戶自己 CF 帳號下的 KV Namespace,同時存放 workflow YAML 與加密 credential,由用戶負責,Arcrun 不經手。
- **workflow.yaml**:用戶撰寫的工作流定義,`flow:``>>` 三元組描述,`config:` 對應各節點參數,存在用戶自己的 USER_KV。
- **CLI(套件名 arcrun,指令 acr**Node.js/TypeScript CLI 工具,管理 credentials、workflow 的上傳與執行。安裝:`npm i -g arcrun`,使用:`acr <指令>`
- **credentials_required**contract.yaml 新欄位,宣告零件需要哪個 credential 以及注入到哪個 input 欄位。
- **config_example**contract.yaml 新欄位,提供 `acr parts scaffold` 指令使用的 config 範本。
- **Standard 模式(預設)**:用戶只需在自己 CF 帳號開一個 KV(存 credential + workflow),使用 arcrun.dev 的執行引擎與公眾零件庫,無需部署任何 Worker。
- **Self-hosted 模式**:用戶自行部署全套 Worker 至自己的 Cloudflare 帳號,有完全控制權,可貢獻零件至公眾庫。
- **auth-worker**arcrun.dev 上的帳號服務 Worker,處理 `POST /register` 自動發放 API Key,不儲存用戶 credential。
- **tenant_id**:每個 API Key 對應的租戶識別碼,用於讓 cypher-executor 知道要用哪個 Cloudflare API Token 去存取用戶的 USER_KV。
- **public registry**arcrun.dev 上的公眾零件庫,所有人共用,有執行統計與 author 資訊。
- **`acr parts publish`**:CLI 指令,自架用戶將自製零件提交至公眾 registry 審核。
- **execution analytics**:每次零件執行後非同步記錄的統計資料(使用次數、成功率),公開顯示於 `acr parts`
- **visibility**contract.yaml 欄位,值為 `author_only`(沙盒通過後作者立即可用)或 `public`(人工審核後所有人可用)。
---
## Requirements
### Requirement 1:搬移 cypher-executor 至獨立 repo 並移除 InkStone bindings
**User Story:** As a 開源用戶, I want 自行部署 cypher-executor 至我的 Cloudflare 帳號, so that 我不需要依賴 InkStone 的任何服務就能執行 AI 工作流。
#### Acceptance Criteria
1. THE cypher-executor `wrangler.toml` SHALL 移除以下 Service Bindings`KBDB``REGISTRY``CLINIC_GDRIVE``CLINIC_EXCEL``CLINIC_ANALYSIS``CLINIC_RENDER``CLINIC_GSHEETS``AICEO``MINI_ME`
2. THE cypher-executor `wrangler.toml` SHALL 保留以下 bindings`EXEC_CONTEXT`KV)、`WEBHOOKS`KV)、`WASM_BUCKET`R2)、`AI`Workers AI)。
3. THE cypher-executor `wrangler.toml` SHALL 新增 `CREDENTIALS_KV`KV Namespace binding),用於 credential 解密注入。
4. THE component-loader SHALL 從 `WASM_BUCKET` R2 直接讀取 `.wasm` 檔案,不透過任何 Service Binding 或外部 HTTP 查詢。
5. WHEN cypher-executor 收到執行請求,THE cypher-executor SHALL 不依賴 `KBDB``REGISTRY` 或任何 InkStone 內部 Service Binding,只使用 KV / R2 / Workers AI 完成執行。
6. THE arcrun repo SHALL 包含以下目錄:`cypher-executor/``credentials/``builtins/``registry/components/`21 個零件)。
---
### Requirement 2component.contract.yaml 完整度補充
**User Story:** As a 零件使用者, I want 每個零件的 contract.yaml 都有 `credentials_required``config_example`, so that CLI 能自動注入 credential,用戶也能快速知道如何設定節點。
#### Acceptance Criteria
1. THE `credentials_required` 欄位 SHALL 出現在以下 4 個零件的 contract.yaml 中:`gmail``google_sheets``telegram``line_notify`
2. WHEN `credentials_required` 存在,THE 欄位 SHALL 包含以下子欄位:`key`(對應 credentials.yaml 的 key 名稱)、`type`token 類型,如 `google_oauth``telegram_bot_token`)、`description`(說明)、`inject_as`(執行時注入到 input 的哪個欄位名稱)。
3. THE `config_example` 欄位 SHALL 出現在所有 21 個零件的 contract.yaml 中。
4. WHEN `config_example` 存在,THE 欄位 SHALL 為 YAML 字串,內容為可直接貼入 workflow.yaml `config:` 區塊的範本,需有人類可讀的說明註解。
5. FOR 需要 credential 的零件,THE `config_example` SHALL 包含一行註解,說明哪個 credential key 會被自動注入到哪個欄位(如 `# access_token 由 credentials.yaml 的 gmail_token 自動注入`)。
6. THE main.go 的 `required` 欄位 SHALL 與 contract 的 `input_schema.required[]` 保持一致,不得有欄位名稱不符。
---
### Requirement 3workflow YAML 格式與執行時 credential 注入
**User Story:** As a 工作流設計者, I want 用有語意的關係詞撰寫 workflow.yaml,且 credential 自動注入, so that workflow 定義中完全不出現明文 token。
#### Acceptance Criteria
1. THE workflow.yaml `flow:` 欄位 SHALL 以 `"A >> 關係詞 >> B"` 三元組陣列描述資料流。
2. THE cypher-executor SHALL 支援以下關係詞:`完成後``失敗時``對每個``條件滿足時``ON_SUCCESS``ON_FAIL``FOREACH``IF``ON_CLICK``CALLS_SUBFLOW`
3. THE cypher-executor SHALL 拒絕使用 `PIPE` 關係詞,並回傳明確錯誤訊息。
4. WHEN cypher-executor 執行一個節點,THE cypher-executor SHALL 查詢該節點對應零件的 `credentials_required`,若存在則從 `CREDENTIALS_KV` 解密對應 credential,並注入到 input 的 `inject_as` 欄位。
5. THE credential 注入 SHALL 發生在 WASM 執行前,用戶的 workflow `config:` 中不需也不應包含 token 值。
6. IF `credentials_required` 宣告的 credential key 在 `CREDENTIALS_KV` 中不存在,THE cypher-executor SHALL 回傳結構化錯誤,包含缺少的 key 名稱與修復步驟說明。
---
### Requirement 4CLIarcrun,指令 acr)核心指令
**User Story:** As a 開發者, I want 透過 `acr` CLI 管理 workflow 與 credentials, so that 不需要直接操作 Cloudflare KV / R2 API 就能完成部署與執行。
#### Acceptance Criteria
1. THE CLI SHALL 以 Node.js/TypeScript 實作,套件名 `arcrun`bin 名 `acr`,可透過 `npm i -g arcrun` 安裝,依賴只使用 `commander``js-yaml``chalk``ora`
2. THE `acr init` 指令 SHALL 以互動式問答產生 `~/.arcrun/config.yaml`,問答內容為:CF Account ID、USER_KV namespace ID、CF API Token(用於 cypher-executor 代存取用戶 KV)、email(取得 arcrun.dev API Key);並建立空白本機 `credentials.yaml`
3. THE `acr creds push [credentials.yaml]` 指令 SHALL 讀取 credentials.yaml,逐一加密上傳至用戶自己的 USER_KV,並顯示每個 key 的上傳結果。
4. THE `acr push <workflow.yaml>` 指令 SHALL 解析 `flow:` 三元組,轉換成執行圖,連同 `config:` 存入 `WEBHOOKS KV`,並輸出 webhook URL。
5. THE `acr run <workflow_name> [--input key=value...]` 指令 SHALL 觸發 cypher-executor 執行指定 workflow,顯示各節點執行結果;失敗時顯示具體節點、原因與修復步驟。
6. THE `acr validate <workflow.yaml>` 指令 SHALL 在執行前驗證:YAML 格式、關係詞合法性(無 PIPE)、所有節點在 config 中有對應、所有零件存在於 WASM_BUCKET、所有 credentials 已上傳至 CREDENTIALS_KV。
7. THE `acr parts` 指令 SHALL 列出所有可用零件(按類型分組),顯示每個零件的必填欄位與所需 credential。
8. THE `acr parts scaffold <component>` 指令 SHALL 從 contract 的 `config_example` 輸出可直接貼入 workflow.yaml 的 config 範本,以及對應的 credentials.yaml 欄位範本。
9. THE `acr list` 指令 SHALL 列出 WEBHOOKS KV 中所有已上傳的 workflow,顯示名稱與更新時間。
10. THE `acr logs <workflow_name>` 指令 SHALL 顯示最近執行記錄,包含時間、成功/失敗狀態、執行時間,失敗時顯示失敗節點與原因。
---
### Requirement 5README 與開源發布準備
**User Story:** As a 外部開發者, I want 看到清楚的 README5 分鐘內能完成部署, so that 降低試用門檻,吸引社群貢獻。
#### Acceptance Criteria
1. THE README.md SHALL 包含以下章節:專案定位(開源核心 vs 閉源付費服務說明)、快速開始(`acr init``acr creds push``acr push``acr run` 四步驟)、零件列表(21 個零件分類說明)、workflow YAML 語法說明(三元組 + 關係詞表格)、自行部署說明(Cloudflare Workers 部署步驟)。
2. THE README.md 快速開始 SHALL 以 `newsletter_subscribe` 為範例 workflow,展示 gmail + google_sheets + telegram 的完整串接。
3. THE repo SHALL 包含 `CONTRIBUTING.md`,說明如何新增零件(TinyGo 開發環境、contract.yaml 格式、本機測試指令)。
4. THE repo SHALL 確保所有 InkStone 內部資訊(Worker URL、KV namespace ID、帳號資訊)不出現在任何已提交的檔案中。
5. WHEN cypher-executor 部署後第一次被呼叫,THE cypher-executor SHALL 能正常回應 health check`GET /health` 回傳 `{ ok: true }`),不需要任何 InkStone 服務可用。
---
### Requirement 6Standard 模式 — API Key 註冊與用戶 KV 存取
**User Story:** As a 新用戶, I want 只需開一個 CF KV 就能開始使用 Arcrun,不需要部署任何 Worker, so that 最低門檻試用整個平台,且我的 credential 永遠在我自己的環境。
#### Acceptance Criteria
1. THE auth-worker SHALL 提供 `POST /register` 端點,接受 `{ email }` 後自動生成 API Key(格式:`ak_` 前綴 + 32 字元隨機字串),無需人工審核,立即回傳 `{ api_key, tenant_id }`
2. THE auth-worker SHALL 將 `{ tenant_id, email, created_at, api_key_hash }` 存入 `ACCOUNTS_KV`,只存 hash 不存明文 API Key。arcrun.dev 不儲存任何用戶 credential 或 workflow 內容。
3. WHEN `acr init` 執行,THE CLI SHALL 互動式詢問以下資料並寫入 `~/.arcrun/config.yaml`
- CF Account ID(用戶自己的)
- USER_KV namespace ID(用戶自己開的,存 credential + workflow
- CF API Token(供 cypher-executor 用 CF API 存取用戶 KV,只需 KV Edit 權限)
- email(呼叫 `POST https://api.arcrun.dev/register` 取得 API Key
4. THE cypher-executor SHALL 在每個 request 的 header 讀取 `X-Arcrun-API-Key`,驗證後取得該 tenant 的 CF API Token,用 Cloudflare API 存取用戶自己的 USER_KV;缺少或無效的 API Key 回傳 `401 Unauthorized`
5. THE `acr creds push` 指令 SHALL 使用用戶的 CF API Token,直接呼叫 Cloudflare KV API 將加密 credential 寫入用戶自己的 USER_KV,不經過 arcrun.dev。
6. THE `acr push <workflow.yaml>` 指令 SHALL 同樣直接寫入用戶自己的 USER_KV,不經過 arcrun.dev。
7. WHEN Self-hosted 模式,THE cypher-executor SHALL 可透過環境變數 `MULTI_TENANT=false` 停用 API Key 驗證,直接使用本地 KV binding,與現有行為相容。
---
### Requirement 7:公眾零件庫執行統計與貢獻榮譽
**User Story:** As a 零件使用者, I want 在 `acr parts` 看到每個零件的真實執行統計與作者資訊, so that 我能選擇最可靠的零件;As a 零件貢獻者, I want 我的名字和統計數字公開顯示, so that 我有動機將好零件推入公眾庫而非留在私庫。
#### Acceptance Criteria
1. THE contract.yaml SHALL 新增可選欄位 `author`GitHub username,如 `@alice`),在 `acr parts` 顯示時一起展示。
2. WHEN cypher-executor 執行完一個零件節點,THE cypher-executor SHALL 非同步 POST 以下資料至 `https://registry.arcrun.dev/analytics/record`,不阻擋主流程:
```json
{ "canonical_id": "gmail", "version": "v1", "success": true, "duration_ms": 120 }
```
不含任何用戶資料或 tenant_id。
3. THE public registry SHALL 聚合每個零件的執行統計:`total_runs`(總執行次數)、`success_rate`(成功率,百分比)、`avg_duration_ms`(平均執行時間)。
4. THE `acr parts` 指令 SHALL 顯示每個零件的統計資料,格式為:
```
• gmail Gmail 發信 by @alice
★ 99.2% 成功 | 140,382 次執行 | 平均 120ms
```
5. IF 零件存在於用戶自架的私有 WASM_BUCKET 而非公眾庫,THE `acr parts` SHALL 顯示該零件但標註 `[私有]`,不顯示統計數字與 author。
6. THE public registry SHALL 在 `GET /components` 回傳的零件清單中,依 `total_runs × success_rate` 排序,讓高品質高使用量的零件排在前面。
---
### Requirement 8:零件貢獻流程與 visibility 狀態
**User Story:** As a 零件開發者, I want 提交零件後立即能自己使用,等審核通過後公開給所有人, so that 不用等待審核就能驗證自己的零件是否有用。
#### Acceptance Criteria
1. THE contract.yaml SHALL 包含 `visibility` 欄位,值為 `author_only`(沙盒通過後作者立即可用)或 `public`(人工審核通過後所有人可用)。
2. THE `acr parts publish <component>` 指令 SHALL 打包指定零件的原始碼、`component.contract.yaml`、`.wasm`POST 至 `https://registry.arcrun.dev/submit`(帶 `X-Arcrun-API-Key` header)。原始碼語言不限,但編譯產出必須為 WASM + WASI preview1。
3. WHEN 零件提交後,THE registry SHALL 依零件類型執行不同層級的沙盒驗收:
- **整合類**(需呼叫外部 API,如 gmail、telegram):體積 / syscall 掃描通過 → `author_only`
- **功能類**(純邏輯,如 string_ops、if_control):體積 / syscall 掃描 / Gherkin 測試全通過 → `author_only`
- 任一必要步驟失敗 → `rejected`(回傳具體失敗步驟與原因)
4. WHEN 零件 visibility 為 `author_only`THE registry SHALL 讓該零件只對提交者的 API Key 可見,`acr parts` 顯示時標註 `[待審核]`,其他用戶看不到。
5. WHEN 人工審核通過,THE registry SHALL 將 visibility 改為 `public`,零件立即出現在所有人的 `acr parts` 清單,並開始累積公開執行統計。
6. WHEN 審核拒絕,THE registry SHALL 回傳具體失敗原因,零件保留 `author_only` 狀態讓作者繼續修改後重新提交。
7. THE `acr parts publish` 指令 SHALL 在提交後顯示 `submission_id`、目前 visibility 狀態,以及查詢審核進度的指令提示。
8. THE `acr parts` 指令 SHALL 對 `author_only` 零件顯示「[待審核] 只有你可用」,對 `public` 零件顯示執行統計與 author,讓貢獻者清楚知道零件的可用範圍。