# 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 2：component.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 3：workflow 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 4：CLI（arcrun，指令 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 5：README 與開源發布準備

**User Story:** As a 外部開發者, I want 看到清楚的 README，5 分鐘內能完成部署, 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 6：Standard 模式 — 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，讓貢獻者清楚知道零件的可用範圍。
