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,521 @@
# u6u-core 獨立開源 Repo 需求規格 v3
## 背景與定位
### 為什麼開源
u6u-core 是 AI 工作流執行引擎,開源的護城河邏輯如下:
```
開源(u6u-core 閉源(InkStone 付費服務)
──────────────────────── ──────────────────────────────
cypher-executor(執行引擎) KBDB 向量搜尋
WASM 零件庫(Gmail / GSheets…) KBDB graph 查詢
credentials Worker Persona SDK / Mini-me
CLI MatchGPT
→ 需要訂閱,不需要 YAML / KV
```
用戶自架版:YAML + CF KV,完全免費。
升級版:不需要 YAML,直接用自然語言查 KBDB 圖譜組 workflow,這是差異化。
### 目前 matrix repo 狀況
```
matrix/
├── cypher-executor/ ← 要搬進 u6u-core
├── u6u-core/
│ ├── builtins/
│ ├── credentials/
│ └── registry/
│ └── components/21 個 WASM 零件)
└── ...(其他 InkStone 內部服務,不搬)
```
---
## 任務一:搬移 cypher-executor 進 u6u-core
### 目標結構
```
u6u-core/(新獨立 repo,開源)
├── README.md
├── cypher-executor/ ← 從 matrix/cypher-executor 搬入
│ ├── src/
│ ├── wrangler.toml ← 需要清理(移除 InkStone 內部 bindings
│ └── ...
├── credentials/ ← 從 matrix/u6u-core/credentials 搬入
├── builtins/ ← 從 matrix/u6u-core/builtins 搬入
└── registry/
└── components/ ← 從 matrix/u6u-core/registry/components 搬入
```
### wrangler.toml 清理(重要)
現有 `cypher-executor/wrangler.toml` 有大量 InkStone 內部 Service Bindings,開源版要移除:
**移除(InkStone 專屬,不公開):**
```toml
# 移除這些 services bindings
KBDB inkstone-kbdb-api
REGISTRY inkstone-component-registry
CLINIC_GDRIVE clinic-gdrive
CLINIC_EXCEL clinic-excel
CLINIC_ANALYSIS
CLINIC_RENDER
CLINIC_GSHEETS
AICEO inkstone-aiceo-bot
MINI_ME inkstone-mini-me
```
**保留(用戶自己部署需要的):**
```toml
[[kv_namespaces]]
binding = "EXEC_CONTEXT" # 執行上下文暫存
[[kv_namespaces]]
binding = "WEBHOOKS" # workflow YAML 儲存
[[r2_buckets]]
binding = "WASM_BUCKET" # WASM 零件二進位
[ai]
binding = "AI" # Workers AIauto-publish 用)
```
**新增(開源版用戶需要的):**
```toml
[[kv_namespaces]]
binding = "CREDENTIALS_KV" # credential 加密存儲
```
### 清理後的 component-loader
現有 component-loader 可能有 InkStone 內部查詢邏輯(KBDB HTTP fetch),
開源版改為:**直接從 WASM_BUCKET R2 讀取 `.wasm` 檔案**,不依賴任何外部服務。
---
## 任務二:零件完成度審查與補充
### 完成度標準
每個零件的 `component.contract.yaml` 必須包含:
```yaml
# 已有(現狀)
canonical_id: "gmail"
input_schema: ...
output_schema: ...
gherkin_tests: ...
# 需要補充
credentials_required: # 需要 token 的零件才需要此欄位
- key: gmail_token # 對應 credentials.yaml 的 key 名稱慣例
type: google_oauth # token 類型
description: "Google OAuth access tokengmail.send scope"
inject_as: access_token # 執行時自動注入到 input 的哪個欄位
config_example: | # scaffold 指令產出的範本,帶說明註解
send_email: # 節點名稱(可自訂)
to: "" # 收件人 Email(必填)
subject: "" # 主旨(必填)
body: "" # 內文(必填)
# access_token 由 credentials.yaml 的 gmail_token 自動注入
```
### 需要 credentials_required 的零件
| 零件 | 需要的 token | inject_as |
|------|-------------|-----------|
| gmail | google_oauth | access_token |
| google_sheets | google_oauth | access_token |
| telegram | telegram_bot_token | bot_token |
| line_notify | line_token | token |
| http_request | 不固定(用戶自訂) | 不適用 |
### 不需要 credentials_required 的零件
set, filter, merge, switch, wait, if_control, foreach_control,
try_catch, validate_json, string_ops, number_ops, array_ops,
date_ops, cron, ai_transform_compile, ai_transform_run
### 審查任務(給 CC
對 21 個零件逐一檢查,**只回報,不修改**:
```
路徑:u6u-core/registry/components/
檢查四項:
1. contract.yaml 存在?
2. 有 credentials_required?(需要 token 的才需要)
3. 有 config_example
4. main.go required 欄位與 contract input_schema required[] 一致?
回報格式:表格(✓ / ✗ / N/A)+ 每個零件缺少什麼
不修改任何檔案。
```
審查完成後,再逐一補充缺少的欄位。
---
## 任務三:workflow YAML 格式定義
### 格式設計原則
- `flow:``>>` 三元組描述資料流,人類直接看懂
- 關係詞使用有語意的詞,**不使用 PIPE**(PIPE 等於什麼都沒說)
- `config:` 用零件名稱對應參數,欄位從 contract 的 config_example 來
- credential 全部集中在 `credentials.yaml`workflow 只寫 `{{creds.KEY}}`
### 可用關係詞
| 關係詞 | 語意 | 使用時機 |
|--------|------|---------|
| `完成後` | 前一個成功後執行 | 最常用的串接 |
| `失敗時` | 前一個失敗後執行 | 錯誤處理 |
| `對每個` | 對陣列每個元素執行 | 迭代 |
| `條件滿足時` | 條件分支 | 判斷 |
| `ON_SUCCESS` | 同「完成後」 | 英文版 |
| `ON_FAIL` | 同「失敗時」 | 英文版 |
| `FOREACH` | 同「對每個」 | 英文版 |
| `IF` | 同「條件滿足時」 | 英文版 |
| `ON_CLICK` | 前端按鈕觸發 | UI 互動 |
| `CALLS_SUBFLOW` | 呼叫子工作流 | 模組化 |
**禁止使用 PIPE** — 任何串接都應該用有語意的關係詞。
### workflow.yaml 範例
```yaml
name: newsletter_subscribe
description: 訂閱電子報,發感謝信並記錄到 GSheets
flow:
- "input >> 完成後 >> send_thanks"
- "input >> 完成後 >> save_to_sheet"
- "send_thanks >> 完成後 >> output"
- "send_thanks >> 失敗時 >> notify_error"
- "save_to_sheet >> 完成後 >> output"
config:
send_thanks: # componentId: gmail(由 cypher-executor 語意搜尋對應)
to: "{{input.email}}"
subject: "感謝訂閱!"
body: "歡迎加入!"
# access_token 由 credentials.yaml 的 gmail_token 自動注入
save_to_sheet: # componentId: google_sheets
action: write
spreadsheet_id: "{{creds.sheet_id}}"
range: "訂閱者!A:B"
values: [["{{input.email}}", "{{input.timestamp}}"]]
# access_token 由 credentials.yaml 的 google_oauth 自動注入
notify_error: # componentId: telegram
chat_id: "{{creds.telegram_chat_id}}"
text: "發信失敗:{{input.email}}"
# bot_token 由 credentials.yaml 的 telegram_bot_token 自動注入
```
### credentials.yaml 範例
```yaml
# credentials.yaml — 類似 .env,加入 .gitignore,不進 git
# u6u creds push 時逐一加密上傳到 CREDENTIALS_KV
gmail_token: "ya29.a0AfB_..."
google_oauth: "ya29.a0AfB_..."
sheet_id: "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms"
telegram_bot_token: "123456:ABC-..."
telegram_chat_id: "987654321"
```
### 執行時 credential 注入流程
```
u6u run newsletter_subscribe
cypher-executor 讀 workflow YAML
遇到節點 send_thanks → 查 contractcredentials_required.inject_as = access_token
去 CREDENTIALS_KV 讀 gmail_token → 解密
注入到 WASM input{ to, subject, body, access_token: "ya29..." }
WASM 執行,用戶的 config 裡完全不出現 token
```
---
## 任務四:CLI 開發
### 技術選型
- **語言**Node.jsTypeScript
- **安裝**`npm i -g u6u`
- **依賴**`commander``js-yaml``chalk``ora`
### 指令規格
#### `u6u init`
互動式初始化,產生 `~/.u6u/config.yaml` 和本機 `credentials.yaml`
```
$ u6u init
? Cloudflare Account ID: abc123
? KV Namespace ID (WEBHOOKS): xyz789
? KV Namespace ID (CREDENTIALS_KV): abc456
? R2 Bucket name (WASM_BUCKET): u6u-wasm
? Cypher Executor Worker URL: https://cypher-executor.xxx.workers.dev
? Credentials Worker URL: https://u6u-credentials.xxx.workers.dev
? Cloudflare API Token: ***
✓ 設定完成 → ~/.u6u/config.yaml
✓ 建立 credentials.yaml(已加入 .gitignore
```
---
#### `u6u creds push [credentials.yaml]`
讀取 credentials.yaml,逐一加密上傳到 CREDENTIALS_KV。
```
$ u6u creds push
讀取 ./credentials.yaml...
✓ gmail_token → 已加密上傳
✓ google_oauth → 已加密上傳
✓ sheet_id → 已上傳
✓ telegram_bot_token → 已加密上傳
✓ telegram_chat_id → 已上傳
共上傳 5 個 credentials
```
---
#### `u6u push <workflow.yaml>`
解析 `flow:` 三元組,轉換成 triplets 陣列,上傳到 WEBHOOKS KV。
```
$ u6u push newsletter_subscribe.yaml
✓ 已上傳 newsletter_subscribe → WEBHOOKS KV
Webhook: https://cypher-executor.xxx.workers.dev/webhook/abc123
```
轉換邏輯(CLI 負責):
```
flow[] 三元組
POST /cypher/search(取得 ExecutionGraph
連同 config 存入 WEBHOOKS KV
```
---
#### `u6u run <workflow_name> [--input key=value...]`
觸發執行,顯示結果。
```
$ u6u run newsletter_subscribe --input email=test@example.com
⏳ 執行中...
✓ 完成(2.3s
結果:
send_thanks: { success: true, data: { message_id: "xxx" } }
save_to_sheet: { success: true, data: { range: "訂閱者!A2" } }
```
錯誤時給出具體修復步驟:
```
✗ 執行失敗:節點 send_thanks
原因: access_token 無效(401 Unauthorized
修復方式:
1. 更新 credentials.yaml 的 gmail_token
2. 執行 u6u creds push
3. 重新執行 u6u run newsletter_subscribe
取得 Google OAuth token
→ https://developers.google.com/oauthplayground
```
---
#### `u6u validate <workflow.yaml>`
執行前完整驗證,提前發現問題。
```
$ u6u validate newsletter_subscribe.yaml
✓ YAML 格式正確
✓ flow 三元組語法正確
✓ 所有關係詞有效(無 PIPE
✓ 所有節點名稱在 config 有對應
✓ 所有零件存在於 WASM_BUCKET
✓ credentials 對應:
gmail_token ✓ 已上傳
google_oauth ✓ 已上傳
sheet_id ✓ 已上傳
telegram_bot_token ✗ 缺少
⚠ 缺少 1 個 credential
telegram_bot_token → 請加入 credentials.yaml 並執行 u6u creds push
```
---
#### `u6u parts`
列出可用零件。
```
$ u6u parts
可用零件(21):
[整合]
• gmail Gmail 發信
需要: to, subject, body
credential: gmail_tokengoogle_oauth
• google_sheets 讀寫 Google 試算表
需要: spreadsheet_id, range, action
credential: google_oauth
• telegram Telegram Bot 發訊息
需要: chat_id, text
credential: telegram_bot_token
• line_notify LINE Notify
需要: message
credential: line_token
• http_request 任意 HTTP 請求
需要: url
[控制]
• if_control 條件分支
• foreach_control 迭代執行
• try_catch 錯誤處理
• switch 多路路由
• wait 等待 N 毫秒
[資料]
• set / filter / merge / string_ops / number_ops / array_ops / date_ops
[AI]
• ai_transform_compile 自然語言 → JS 轉換函式
• ai_transform_run 執行已編譯的轉換
```
---
#### `u6u parts scaffold <component>`
從 contract 的 config_example 產出可直接貼入 workflow 的 config 範本。
```
$ u6u parts scaffold gmail
貼入 workflow.yaml 的 config 區塊:
send_email: # 節點名稱(可自訂)
to: "" # 收件人 Email(必填)
subject: "" # 主旨(必填)
body: "" # 內文(必填)
# access_token 由 credentials.yaml 的 gmail_token 自動注入
貼入 credentials.yaml
gmail_token: "" # Google OAuth token
# 取得方式:https://developers.google.com/oauthplayground
```
---
#### `u6u list`
列出 WEBHOOKS KV 中所有 workflow。
```
$ u6u list
• newsletter_subscribe (更新: 2026-04-16)
• daily_summary (更新: 2026-04-15)
```
---
#### `u6u logs <workflow_name>`
查看最近執行記錄。
```
$ u6u logs newsletter_subscribe
2026-04-16 14:30 ✓ 成功 2.1s
2026-04-16 09:00 ✗ 失敗 send_thanks: 401 Unauthorized
2026-04-15 09:00 ✓ 成功 1.8s
```
---
## 開發順序
### Phase 1:搬移與清理(先做)
```
1. 建立新的獨立 repou6u-core
2. 從 matrix 搬入:
- cypher-executor/
- u6u-core/credentials/
- u6u-core/builtins/
- u6u-core/registry/
3. 清理 cypher-executor/wrangler.toml(移除 InkStone 內部 bindings
4. 確認 component-loader 只依賴 WASM_BUCKET,不依賴 KBDB / REGISTRY
5. 本機部署測試
```
### Phase 2:零件完成度(搬移後)
```
6. 審查 21 個零件的 contract.yaml
7. 補充 credentials_requiredgmail, google_sheets, telegram, line_notify
8. 補充 config_example(全部 21 個)
9. 驗證 main.go required 欄位與 contract 一致
```
### Phase 3CLI(完成度補充後)
```
10. u6u init
11. u6u creds push
12. u6u push
13. u6u run(含 credential 自動注入)
14. u6u parts / u6u parts scaffold
15. u6u validate
16. u6u list / u6u logs
```
### Phase 4:開源發布
```
17. 撰寫 README.md(快速開始、零件列表、workflow 語法說明)
18. 撰寫 CONTRIBUTING.md(如何新增零件)
19. 發布到 GitHub
20. npm publishu6u CLI
```
---
## 不在此次範圍
- KBDB 整合(未來付費服務)
- 向量搜尋 / graph 查詢
- 前端管理介面
- Webhook trigger 設定(用戶自行設定 CF Cron)
- 新增 WASM 零件(現有 21 個先做完整,之後再擴充)