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>
This commit is contained in:
2026-04-20 17:48:24 +08:00
parent cadcaef3b0
commit 13b01328c1
36 changed files with 7499 additions and 0 deletions
@@ -0,0 +1,340 @@
# arcrun.dev Pages 規格
> **讀者**CC(可直接照做)
> **部署**Cloudflare Pages + Workers
> **語言**:英文為主,中文切換
> **技術棧**Astro(靜態生成)+ Cloudflare Pages + D1(使用統計)
---
## 0. 這個 Pages 的三個角色
1. **門面**:第一次看到 arcrun 的人,30 秒內要懂「這是什麼、對我有什麼用」
2. **轉換漏斗**:工程師 → 試用 lib → 申請 API Key;小白 → 看榮譽牆 → 問 AI 能不能用
3. **社群磁鐵**:榮譽牆讓工程師有動機貢獻 recipe,貢獻越多服務越多,用戶越多
---
## 1. 網站結構(五個頁面)
```
arcrun.dev/
├── / 首頁(門面 + 轉換)
├── /docs 用法文件
├── /integrations 榮譽牆(服務目錄)
├── /api Swagger UI(原始 API
└── /changelog 版本記錄
```
---
## 2. 首頁(/
### 2.1 Hero Section
**英文**
```
Stop fighting OAuth.
One API key. Every service. Works anywhere.
arcrun handles Google, Notion, GitHub, Slack authentication
so your Python / JS code doesn't have to.
[Get API Key — Free] [View on GitHub]
```
**中文切換後**
```
不要再跟 OAuth 搏鬥了。
一個 API Key,接通所有服務,在哪跑都行。
[免費取得 API Key] [查看 GitHub]
```
語言切換按鈕放右上角,用 `?lang=zh` query paramCloudflare Worker 記住偏好存 cookie。
### 2.2 三行說清楚(Why arcrun
```
┌────────────────────┬────────────────────┬────────────────────┐
│ Before │ │ After │
│ │ │ │
│ 40 行 OAuth 程式 │ →→→ │ 1 行 │
│ GCP Console 設定 │ │ arcrun.auth.bind │
│ debug 兩天 │ │ ("google_drive") │
└────────────────────┴────────────────────┴────────────────────┘
```
### 2.3 Code Demo(互動式 tab
三個 tab 切換:Python / JavaScript / HTTP(給 n8n 小白)
**Python tab**
```python
pip install arcrun-auth
from arcrun import auth
# 就這樣,Google Drive 認證完成
drive = auth.bind("google_drive")
resp = drive.get("/files")
```
**JavaScript tab**
```javascript
npm install arcrun-auth
import { auth } from 'arcrun-auth'
const drive = await auth.bind('google_drive')
const resp = await drive.get('/files')
```
**HTTP tab(給 n8n 用戶)**
```
POST https://api.arcrun.dev/v1/auth/bind
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"service": "google_drive",
"secret": "{{ $env.GOOGLE_SA_JSON }}"
}
```
下方加一行小字:「n8n 用戶:用 HTTP Request 節點貼上這段,不需要安裝任何東西」
### 2.4 數字牆(social proof
```
127 個認證服務 1,247,832 次呼叫 89 位貢獻者
```
這三個數字從 D1 即時讀,每小時更新一次(Cloudflare KV cache)。
### 2.5 CTA
```
[免費取得 API Key]
註冊後立即可用,不需要信用卡
```
---
## 3. 榮譽牆(/integrations)★ 核心頁面
### 3.1 頁面頂部
```
127 個已驗證的認證服務
由社群工程師貢獻並測試,每個 recipe 都有真實使用數據
[搜尋服務...] [全部] [AI] [Google] [社群媒體] [生產力] [台灣]
```
### 3.2 服務卡片
每個 recipe 一張卡:
```
┌──────────────────────────────────────────┐
│ [圖示] Google Drive ★ 官方 │
│ │
│ 認證方式:Service Account │
│ 貢獻者:@richblack ──→ GitHub profile │
│ 驗證日期:2026-03-15 │
│ │
│ 使用次數:██████████ 12,847 次 │
│ │
│ [查看 Recipe] [複製 Python 範例] │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ [圖示] OpenRouter │
│ │
│ 認證方式:API Key (Header) │
│ 貢獻者:@some_engineer ──→ GitHub │
│ 驗證日期:2026-04-01 │
│ │
│ 使用次數:██░░░░░░░░ 89 次 │
│ │
│ [查看 Recipe] [複製 Python 範例] │
└──────────────────────────────────────────┘
```
badge 規則:
- `★ 官方`arcrun 團隊維護
- `✓ 社群驗證`:100+ 次使用 + 30 天無錯誤回報
- `🆕 新加入`30 天內合併的 PR
### 3.3 貢獻者排行(頁面底部)
```
Top Contributors
🥇 @some_engineer 23 個 recipe 89,234 次呼叫
🥈 @another_dev 15 個 recipe 45,123 次呼叫
🥉 @third_person 8 個 recipe 12,456 次呼叫
...
[我也要貢獻 →] (連到 CONTRIBUTING.md
```
### 3.4 「我要貢獻」的 CTA
```
找不到你要的服務?
大部分 API Key 類的服務,填一份 YAML 就能加進來。
把 API 文件丟給 AI,五分鐘生成,開 PR 送出。
[查看 Recipe 格式] [開始貢獻]
```
---
## 4. 用法文件(/docs
### 結構
```
快速開始
├── 取得 API Key
├── Python 安裝與第一個範例
├── JavaScript 安裝與第一個範例
└── 直接用 HTTP(n8n / 任何工具)
認證方式
├── API Key 類服務
├── OAuth2 類服務
├── Google Service Account
└── mTLS
進階用法
├── 多帳號(multi-instance
├── 只取 tokenescape hatch
└── 錯誤處理
貢獻 Recipe
├── Recipe YAML 格式說明
├── 讓 AI 幫你寫 Recipe
└── 提交流程
```
### 「讓 AI 幫你寫 Recipe」這一節特別重要
```markdown
## 讓 AI 幫你寫 Recipe
把下面這段丟給 Claude / ChatGPT
再把目標服務的 API 文件一起貼進去:
---
請根據以下 API 文件,
生成一份符合 arcrun recipe schema 的 YAML。
Schema 文件:https://arcrun.dev/docs/recipe-schema
目標服務:[貼上 API 文件]
---
AI 生成後,你只需要:
1. 把 YAML 存成 recipes/community/服務名.yaml
2.`acr recipe test 服務名.yaml`
3. 開 PR
通常整個過程不超過十分鐘。
```
這一節讓「貢獻門檻」從「工程師才能做」變成「任何人叫 AI 做」。
---
## 5. API 文件(/api
直接嵌入 Swagger UI,連到 `https://api.arcrun.dev/swagger.json`
頁面頂部加一行說明:
```
這是 arcrun 的原始 API。
Python / JS lib 是它的包裝,
任何能發 HTTP request 的工具都能直接用。
```
這一句話讓 n8n 用戶、Make 用戶、甚至 Excel 用戶都知道「我也能用」。
---
## 6. 技術實作
### 6.1 技術選型
**Astro**(靜態生成)是首選,原因:
- 頁面大部分是靜態內容(docs / recipe 卡片),Astro 的 SSG 完美對應
- 動態數字(使用次數、貢獻者排行)用 Astro 的 `client:load` island 局部更新
- 部署到 Cloudflare Pages 零配置
**不用 Next.js**,因為你已在 Cloudflare 生態,Next.js 的 SSR 在 CF Pages 有摩擦。Astro + CF Pages 是更自然的組合。
### 6.2 資料來源
| 資料 | 來源 | 更新頻率 |
|---|---|---|
| Recipe 清單、metadata | GitHub repo `recipes/` 目錄 | CI merge 時觸發 rebuild |
| 使用次數 | Cloudflare D1API call log | 每小時從 D1 聚合 → KV cache |
| 貢獻者排行 | 同上 | 每小時 |
| 總呼叫次數 | 同上 | 每小時 |
### 6.3 多語言
用 Astro 的 i18n routing
- `/` → 英文
- `/zh/` → 中文
語言切換按鈕寫入 cookie `arcrun_lang`CF Worker 在 edge 讀 cookie 做 redirect。
不用 JS framework 的 i18n library,保持輕量。
### 6.4 部署流程
```
GitHub push to main
→ GitHub Actions 跑 astro build
→ 產出 dist/
→ 自動部署到 Cloudflare Pages
→ Pages 掛 arcrun.dev domain
```
recipe YAML 有變動時(PR merge)額外觸發一次 rebuild。
---
## 7. CC 的實作任務
### Phase 1:靜態骨架(3-5 天)
- [ ] Astro 專案初始化,設定 CF Pages 部署
- [ ] 首頁 Hero + Code Demo tab(靜態版,數字先寫死)
- [ ] `/integrations` 靜態版(先手動列 5-10 個服務)
- [ ] `/docs` 基本結構(快速開始 + Python 範例)
- [ ] `/api` 嵌入 Swagger UI
- [ ] 中英切換機制
### Phase 2:動態資料(3-5 天)
- [ ] D1 schema`recipe_calls(recipe_id, count, last_updated)`
- [ ] CF WorkerAPI call 時寫入 D1
- [ ] 每小時聚合 WorkerD1 → KV cache(總數 / per recipe / per contributor
- [ ] 首頁數字牆:從 KV 讀即時數字
- [ ] `/integrations` 卡片:使用次數從 KV 讀,進度條動態顯示
### Phase 3:社群功能(2-3 天)
- [ ] 貢獻者排行從 KV 讀
- [ ] Recipe 頁面:點「查看 Recipe」展開 YAML
- [ ] 點「複製 Python 範例」自動生成對應 code snippet
- [ ] GitHub PR merge webhook → 觸發 Pages rebuild
---
## 8. 一個不能省的細節
榮譽牆的貢獻者欄位**一定要連到他的 GitHub profile**,不是只顯示名字。
工程師貢獻的動機之一是「這個會出現在我的公開作品集」。連到 GitHub 就意味著他的 followers 可能看到他貢獻了 arcrun,這比任何 badge 都有效。
@@ -0,0 +1,486 @@
# arcrun-pyPython Lib 策略分析
> **核心問題**arcrun 的 auth 層要不要獨立成 Python lib?AI 會主動選它嗎?
> **決策前提**:本地為主雲端選配 + 免費引流 SaaS + 三維度分析
---
## 0. TL;DR
做。但要做對——它不是「arcrun SDK」,是 **獨立的 OAuth 地獄解藥**SaaS 帳號只是 optional power-up。
**產品名建議**`arcrun-auth`PyPI 套件名),import 時叫 `authkit``arc`
**定位**`pip install arcrun-auth` → 一行搞定 Google/GitHub/Slack/Notion/... 的認證。本地 keyring 存 secret,零註冊可用。註冊 arcrun 帳號才能多機同步 / 團隊共用 / 獲得平台代管的 OAuth App。
---
## 1. 你的直覺:為什麼這可能是大招
你觀察到的現象:
- **寫個「本地檔案 → Google Drive 備份」這種小腳本**,光認證花 2 天,日後還反覆壞。
- **這個痛點 99% 的 Python 使用者都遇過**。Stack Overflow 上 Google OAuth 的問題累計回答數十萬。
- **AI 寫程式時,這部分它也不會寫**——訓練資料裡的標準範本就是 `InstalledAppFlow.from_client_secrets_file()`,還是要人類先去 GCP Console 建 OAuth Client、下載 JSON、設 redirect URI、加測試用戶。
**如果 arcrun 能把這整套濃縮成 `auth.bind("google_drive")`,它就是開發者工具裡的「自來水」——沒人在乎水源廠長怎麼運作,大家只想打開水龍頭有水喝。**
而且你無意中踩到一個時代轉折點:**AI 在寫程式,AI 不想 debug OAuth**。這個 lib 是給 AI 用的,比給人類用的更重要。
---
## 2. 三維度分析:AI 到底會不會選 arcrun-auth
### 維度一:零註冊摩擦(最重要)
**現實**AI coding assistant 預設會產出訓練資料裡最常見的程式碼。Google Drive 的標準答案就是官方 quickstart——那段 40 行的 `InstalledAppFlow` 樣板碼,加上「去 GCP Console 建 OAuth Client」的一串步驟。
**AI 選擇替代 lib 的條件**(觀察 Copilot / Cursor / Claude Code 的實際行為):
| 條件 | 是否能壓制預設答案 |
|---|---|
| Lib 名稱出現在 prompt 裡 | ✅ 絕對會用 |
| 專案已有 `pyproject.toml` 宣告該 lib | ✅ 會用 |
| 該 lib 是 PyPI 下載量 Top N(訓練資料權重高) | ⚠️ 或許 |
| 使用者口頭說「用 XX 比較好」 | ✅ 會用(單次) |
| 該 lib 明顯更短更容易 | ⚠️ 有機會但不保證 |
**結論****零註冊摩擦是生死線**。
如果 `pip install arcrun-auth` 之後必須先去註冊 arcrun 帳號、拿 API token、設環境變數——AI 看到這一步就會放棄,回去寫 Google 官方那套,因為「官方的至少不用註冊第二家廠商」。
**對策**
- 本地模式必須是**零配置可用**的 default path。
- Secret 存在 `~/.arcrun/secrets.db`(加密,用系統 keyring 保護 master key)。
- 註冊 arcrun 帳號是 **opt-in** 的升級,不是必要。
- 第一次用 OAuth 時,**平台提供免費共用的 OAuth App**(下面 §3 詳細說)。
這個設計讓 AI 看到的心智路徑是:
```
目標:備份檔案到 Google Drive
選項 Agoogle-api-python-client(官方,但使用者要先去 GCP 設 OAuth)
選項 Barcrun-authpip install 完直接可用)
```
在這個對比下,AI 會選 B——**特別是它被告知「使用者不想 debug 認證」或類似的 prompt 時**。
### 維度二:跟 stdlib / 主流 lib 的對比
Python Google API 的主流選項:
| Lib | PyPI 週下載(估) | AI 熟悉度 | 認證難度 |
|---|---|---|---|
| `google-api-python-client` | ~30M | 極高 | 高(要自己設 OAuth) |
| `pydrive2` | ~200k | 中 | 高 |
| `gspread`(只 Sheets | ~2M | 高 | 高(OAuth 或 SA |
| **arcrun-auth** | 0 | 0 | **極低** |
**冷啟動難題**:新 lib 要進入 AI 的選擇集合,需要:
1. **量**PyPI 下載 + GitHub stars 進到「被訓練資料收錄」的級別(大概 GitHub 5k+ stars 是門檻)。
2. **品牌**:有代表性部落格文、教學影片、官方 API 文件連結到它。
3. **簡潔**:代碼範例比主流短 5 倍以上,讓使用者「一眼就想用」。
**arcrun 的優勢**
- 你本來就在教 n8n 課程,有現成學員管道可以鋪「這是 n8n 的 Python 版 auth」。
- 「AI 寫程式的 auth lib」是個還沒被佔領的定位詞。`langchain` 做了 LLM 層,但 auth 層還沒有明顯贏家。
- Claude Code 對 lib 選擇特別敏感——它會實際讀 `pyproject.toml` 並尊重已有宣告。
**對策**
- **第一批 adopter 是你的學員**(n8n 課 + AI 自動化課),他們會在實戰中用,累積 GitHub issues 和 blog post。
- **SEO 主打**:「Python Google Drive OAuth 簡化」「AI 自動化 Python 認證」這些長尾關鍵字現在沒有明顯答主。
- **Claude Code 優化**:寫一份 `AGENTS.md``.cursorrules` 範本,示範怎麼在 prompt 裡引導 AI 選 arcrun-auth。
### 維度三:痛點強度(OAuth 地獄避免)
**量化你那兩天 debug**
| 階段 | 時間成本 | 典型錯誤 |
|---|---|---|
| GCP 註冊 + 啟用 API | 15 min | 找不到哪個 API |
| 建 OAuth Client ID | 15 min | Desktop / Web / iOS 選錯 |
| 設 OAuth Consent Screen | 30 min | External / Internal 選錯;scope 加錯 |
| 加測試用戶 | 10 min | 漏加自己的 email |
| 寫 Python flow | 30 min | `run_local_server` vs `run_console` |
| 第一次跑遇到 `redirect_uri_mismatch` | 30-120 min | port 衝突、URI 沒加 |
| Token 過期處理 | 60 min | `creds.expired``refresh_token` 沒保存 |
| Service Account 模式(如果需要) | 120 min | domain-wide delegation 設定 |
| **合計** | **5-8 hrs(順的人)** | **2 天(不順的人,你當時的情況)** |
**arcrun-auth 對應版本**
```python
from arcrun import auth
# 首次執行:自動打開瀏覽器完成 OAuth,結果存本地 keyring
drive = auth.bind("google_drive")
# 直接呼叫 API
drive.post("/upload/drive/v3/files", params={"uploadType": "media"},
data=open("backup.zip", "rb"))
```
**時間成本:首次 2 min,之後 0 min**
這個壓倒性的體驗差距是產品的核心競爭力。**只要使用者試過一次,就不會再回去寫 `InstalledAppFlow`**——即使 AI 預設會產出官方版本。
---
## 3. 關鍵設計決策
### 3.1 OAuth App 誰擁有?(核心問題)
傳統做法:使用者自己去 GCP Console 註冊自己的 OAuth App,拿 client_id/client_secret。**這就是痛點來源**。
arcrun-auth 要消滅這步,只有兩條路:
**Option A:平台提供共用 OAuth App(推薦 default**
- arcrun 註冊一個 Google OAuth App,命名類似「arcrun Auth Broker」。
- 所有 arcrun-auth 使用者共用這個 App 的 client_id/secret。
- 使用者在 Google 授權頁面看到的是「arcrun Auth Broker 想存取您的 Google Drive」。
- **好處**:使用者零配置,arcrun 品牌曝光。
- **成本**Google 有 OAuth App 的限額(Verified App 才能超過 100 users),需要申請 Google OAuth Verification(要提供隱私政策、網域驗證、可能要付 $75 安全審查)。
**Option B:使用者 BYO OAuth App**
- 企業客戶或注重稽核的人需要這個。
-`~/.arcrun/config.toml` 放自己的 client_id/secret。
**Option Carcrun SaaS 代管**(付費)
- 使用者註冊 arcrun 帳號,平台幫你管 OAuth App、token、團隊共用、audit log。
- 這是付費 tier 的主要價值。
**建議**:A + B + C 三種都支援,默認 A;免費無限制 B;付費享受 C。
### 3.2 Secret 儲存層級(本地為主雲端選配)
```
優先級 1 (default):本地 keyring
- macOS Keychain / Windows Credential Manager / Linux libsecret
- zero config,安全性靠 OS
優先級 2 (opt-in):本地加密檔
- ~/.arcrun/secrets.enc
- master key 走 keyring 或 passphrase
- 給沒有 keyring 的環境(Docker、CI
優先級 3 (opt-in)arcrun 雲端
- 多機同步、團隊共用、audit log
- 需註冊 arcrun 帳號
- 本地 lib 只保存 arcrun API token,實際 service secret 存雲端
```
### 3.3 Secret 初始化流程
**靜態 key 模式(Notion、OpenAI、Stripe...**
```bash
# 選項 A:互動式
$ arcrun setup notion
? Notion Integration Token (hidden): ***
✓ Testing connection... OK
✓ Saved to keyring as notion/default
# 選項 B:環境變數
$ export ARCRUN_NOTION_TOKEN=secret_xxx
$ python script.py # arcrun-auth 自動讀
# 選項 C:程式碼內
notion = auth.bind("notion", secret={"token": os.environ["NOTION_TOKEN"]})
```
**OAuth 模式(Google、GitHub、Slack...**
```python
drive = auth.bind("google_drive")
# 如果是第一次:
# 1. 本地啟動一個臨時 HTTP server (http://localhost:random_port)
# 2. 開瀏覽器到 Google authorize URL
# 3. 使用者點同意
# 4. Google redirect 到 localhostlib 接到 code
# 5. 換 token,存 keyring
# 6. 回傳可用的 client
```
這個流程和 `InstalledAppFlow.run_local_server()` 本質上一樣——但差別是:
- **Client ID 不用使用者自己去 GCP Console 註冊**(由 arcrun 平台提供)。
- **Scope 由 recipe 宣告**(不用使用者自己查文件)。
- **Token 儲存自動化**(不是散落在 `token.json`)。
### 3.4 Recipe 來源
Python lib 和 Cloudflare Worker 版本**共用同一份 recipe YAML**。
```
arcrun-recipes/ # GitHub repo,公開
├── recipes/
│ ├── official/
│ │ ├── google_drive.yaml
│ │ ├── notion.yaml
│ │ └── ...
│ └── community/
│ └── ...
```
Python lib 啟動時檢查本地 `~/.arcrun/recipes/` 快取,過期就從 GitHub 或 arcrun 平台 API 拉最新。
**這是關鍵架構優勢**recipe 寫一次,Web 和 CLI 和 Python lib 全部受益。社群貢獻一份 Notion recipe,所有 runtime 自動支援。
---
## 4. API 設計(Python 版)
### 4.1 最簡路徑
```python
from arcrun import auth
# 取得認證好的 HTTP client(基於 httpx
client = auth.bind("google_drive")
# 相對 base_url 的路徑
resp = client.get("/files", params={"q": "name = 'backup.zip'"})
files = resp.json()["files"]
# 上傳
client.post("/upload/drive/v3/files",
params={"uploadType": "multipart"},
files={"file": ("backup.zip", open("backup.zip", "rb"))})
```
### 4.2 進階:非同步
```python
from arcrun import auth
async with auth.bind_async("google_drive") as client:
resp = await client.get("/files")
```
### 4.3 進階:多 instance
```python
# 同一個服務,多個帳號
personal = auth.bind("google_drive", instance="personal")
work = auth.bind("google_drive", instance="work")
```
### 4.4 進階:直接取 token(給不想透過 wrapper 的情況)
```python
# 取 raw access token,自己丟進任何 lib
token = auth.get_token("google_drive")
# 丟給 googleapiclient
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
creds = Credentials(token=token.access_token)
service = build("drive", "v3", credentials=creds)
```
這個 escape hatch 很重要——不強制使用者放棄他熟悉的官方 lib,只是把**認證這一層**剝離出來。這是你想要的「避免麻煩直接用 arcrun 的 auth 功能」的精確實作。
### 4.5 服務發現
```python
# CLI
$ arcrun list
google_drive Google Drive OAuth2
notion Notion API Key
github GitHub OAuth2
openai OpenAI API Key
...
# Python
from arcrun import auth
auth.list_services() # 回傳 dict
```
---
## 5. 商業模式:免費引流 → SaaS 付費
### 5.1 免費永久可用(本地模式)
| 功能 | 免費 | 付費 |
|---|---|---|
| `pip install arcrun-auth` | ✅ | ✅ |
| 本地 keyring 儲存 secret | ✅ | ✅ |
| 所有 recipe 可用 | ✅ | ✅ |
| 平台代管 OAuth App(免自己註冊) | ✅ | ✅ |
| 單機使用 | ✅ | ✅ |
### 5.2 付費 tier 提供的
| 功能 | 免費 | Pro ($9/mo) | Team ($29/user/mo) |
|---|---|---|---|
| 多機同步 secret | ❌ | ✅ | ✅ |
| 團隊共用 credential | ❌ | ❌ | ✅ |
| Audit log(誰在何時用了什麼 secret | ❌ | ✅ | ✅ |
| Secret rotation 提醒 | ❌ | ✅ | ✅ |
| 企業 OAuth App BYO | ❌ | ✅ | ✅ |
| SSO / SCIM | ❌ | ❌ | ✅ |
| arcrun SaaS 整合(workflow runtime | ❌ | ⚠️ 受限 | ✅ |
| Priority 社群 recipe 審核 | ❌ | ✅ | ✅ |
**商業邏輯**
- 免費 tier 足夠「個人開發者 + 側邊小專案」的體驗完整。
- 付費 tier 解決「我的小工具變公司在用」的延伸需求。
- arcrun SaaS workflow 客戶自動享受所有 Python lib 特權。
### 5.3 為什麼這策略會 work
參考模型:
- **Sentry**error tracking,開源 SDKhosted service 付費。SDK 下載數 = 付費轉換引流。
- **PostHog**product analytics,同樣策略。
- **Supabase**auth + db,開源 self-hostedhosted 服務付費。
共同特徵:
1. SDK 免費下載、單機/本地能完整 work。
2. 從本地升級到 hosted 是「多人/多機/審計」的自然需求。
3. SDK 本身就是最強的 marketing(開發者口耳相傳 + 訓練資料擴散)。
---
## 6. 為什麼 AI 會主動選 arcrun-auth(機率分析)
讓我給你一個分層的答案。
### 6.1 會主動選的場景(高機率)
| 場景 | 原因 |
|---|---|
| 使用者在 prompt 說「用最簡單的方式認證」 | AI 權衡 UXarcrun-auth 明顯勝 |
| 專案已有 `arcrun-auth``pyproject.toml` | AI 尊重現有依賴 |
| 使用者貼了 arcrun-auth 文件範例 | AI 會模仿 |
| 使用者說「跳過 OAuth 設定步驟」 | arcrun-auth 是唯一答案 |
### 6.2 不會主動選的場景(預設行為)
| 場景 | 原因 |
|---|---|
| 使用者開新專案、無任何線索 | AI 走訓練資料中最頻繁的 `google-api-python-client` |
| 任務是「企業級、有審計需求」 | AI 偏好主流官方 lib |
| 任務提到特定 lib 名稱 | AI 會遵守 |
### 6.3 轉化策略
要讓 AI 的「預設路徑」變成 arcrun-auth,需要:
1. **種子內容**:寫 20+ 篇「用 arcrun-auth 做 X」的 blog post,讓下一輪模型訓練看到。
2. **官方文件 SEO**:搶「python google drive oauth 簡化」等長尾關鍵字。
3. **Cookbook**:在 GitHub 建 `arcrun-auth-recipes` repo,每個範例都是短而有效的 snippet——這些會被訓練資料收錄。
4. **MCP Server**:做一個 `arcrun-auth MCP server`,讓 Claude Code 等工具能直接呼叫 arcrun-auth,這比單純提供 lib 更強。
5. **教學整合**:你的 n8n 課程直接示範「從 n8n 到 arcrun-auth 的 Python 版本」。
---
## 7. 實作範圍(MVP
### Phase 1:核心 lib2-3 週)
- [ ] `arcrun-auth` PyPI 骨架(pyproject.toml + src layout
- [ ] Recipe loader(從 GitHub 或平台 API 拉 YAML
- [ ] `auth.bind(service_id, instance?)` → httpx Client
- [ ] Static key primitiveNotion / OpenAI / Stripe 當試金石)
- [ ] Keyring 整合 + 本地加密檔 fallback
- [ ] CLI`arcrun setup <service>`, `arcrun list`, `arcrun test`
### Phase 2OAuth22 週)
- [ ] OAuth2 primitiveauthorization_code + PKCE
- [ ] 本地 callback server(類似 `InstalledAppFlow.run_local_server`
- [ ] 共用平台 OAuth App 的 proxy 機制
- Lib 呼叫 `https://auth.arcrun.com/oauth/redirect`
- 平台把 code 交換後回傳 token
- 或者直接把平台 client_id 硬編在 recipe 裡(更簡單但要處理配額)
- [ ] Token refresh 自動化
- [ ] RecipeGoogle Drive / Gmail / GitHub / Slack
### Phase 3Service Account1-2 週)
- [ ] Google Service AccountJWT signing
- [ ] AWS SigV4
- [ ] Recipe 繼承(`extends: _google_base`
### Phase 4:雲端同步(2 週)
- [ ] `arcrun login` → 綁定雲端帳號
- [ ] Secret sync 協議(本地加密後上傳,平台只存密文)
- [ ] 多機同步
- [ ] Audit log
### Phase 5AI 生態整合(1-2 週)
- [ ] MCP server(讓 Claude Code 能直接用)
- [ ] VS Code Extension(一鍵設定 credential
- [ ] `AGENTS.md` 範本(引導 AI 選 arcrun-auth
---
## 8. 風險與坑
### 8.1 Google OAuth Verification
**問題**:共用 OAuth App 要申請 Google Verification,否則會有「未驗證 App」警告 + 100 user 上限。
**對策**
- MVP 階段接受警告頁面(使用者自己點「進階 → 前往」)。
- 到 user 量接近 100 時申請 Verification。
- 企業客戶走 BYO OAuth App 路徑,不受影響。
- 若平台 OAuth App 卡關,有 fallbacklib 自動引導使用者建自己的 OAuth App(提供 CLI wizard)。
### 8.2 其他服務的 OAuth App 政策
- **GitHub**:免費建 OAuth App,無上限。✅
- **Slack**:免費建,但安裝到使用者 workspace 需管理員同意。⚠️
- **Microsoft / Azure**:相對嚴格,需 tenant admin consent。⚠️
- **Notion**Internal Integration 可以完全走 API key,免 OAuth。✅(最簡單)
### 8.3 keyring 在 Linux server / Docker 的問題
Linux server 沒 GUI keyring daemon。對策:
- Fallback 到加密檔案(用 env var 或 CLI 互動提供 master key)。
- Docker 場景有 `docker secret`、Kubernetes Secretlib 支援直接讀這些來源。
### 8.4 競品
目前沒有完全對標的產品,但相鄰玩家:
- **[keyring](https://pypi.org/project/keyring/)**:只做儲存,不做認證流程。我們用它當底層。
- **[httpx-auth](https://pypi.org/project/httpx-auth/)**:只做認證,不做 secret 管理,也沒有 recipe。
- **[authlib](https://pypi.org/project/authlib/)**OAuth 實作 lib,低階,還是要自己組。
- **各家 SDKgoogle-auth, slack-sdk**:綁特定家,不 unify。
**arcrun-auth 的差異化定位**
> **Unified credential broker for AI-era Python apps**
> 一個 lib 搞定所有服務、所有認證機制、所有 secret 儲存後端。
---
## 9. 最後的判斷
### 9.1 這個 lib 該不該做?
**該做**。原因:
1. 你描述的痛點是真的,而且規模巨大(Python + Google API 下載量是千萬級)。
2. 技術可行,也跟既有 arcrun 架構共用 recipe,邊際成本低。
3. 對 arcrun SaaS 是完美引流——免費 lib 的使用者是精準的付費轉換潛在客戶。
4. 時間窗口正確:AI 寫程式時代剛開始,這個定位還沒被佔領。
### 9.2 跟主 SaaS 的優先順序
**建議****主 SaaS 的 credential 系統先做(前一份規劃),arcrun-auth 當後續 Phase**。
原因:
- Cloudflare Worker 版的 primitives + recipes 是基礎建設,Python lib 是其 consumer。
- 先做 Python lib 會逼你在 recipe schema 上做二次修改,不划算。
- 主 SaaS 的 recipe 累積到 20-30 個服務後,開放 Python lib 體驗最好。
時程建議:
- **Month 1-2**:主 SaaS 的 4 個 primitive + 15 個 recipe(前一份規劃)。
- **Month 3-4**arcrun-auth Phase 1-2static key + OAuth2),私人 alpha。
- **Month 5**:公開 release,寫部落格、SEO、社群推廣。
- **Month 6+**:雲端同步、MCP、AI 生態整合。
### 9.3 一句話總結
> **arcrun-auth 不是「arcrun 的 Python 綁定」,是「OAuth 地獄的解藥」**。SaaS 是延伸。這個敘事才能在 AI 寫程式的時代站住腳。
@@ -0,0 +1,55 @@
# Arcrun 推廣策略修正
20260418 by Leo
## Arcrun 的最近幾次變化
- Arcrun 原是 Matrix 的原子化純雲端 CF 程式框架,有 MCP 讓 AI 使用
- 轉以 WASM + WASI + TinyGo 成為未來具有雲端、地端、邊緣端的執行能力,可以用來做到無人機等終端。
- 再解耦成獨立的 Open Source 專案,脫離 KBDB 用 YAML 即可,允許整個 Fork,但推廣 SaaS 模式
- 今天的變化是發現成為 Lib 和 n8n 社群節點的用法。說明如下。
## 推廣方式 1:寫成 Lib
參考文件:docs/user_requirements/arcrun/ADR-lib-and-landingPage/arcrun-py-strategy-analysis.md
Leo 教 n8n 時常舉例我叫 AI 幫我寫個簡單的程式把 server 的檔案備份到 Google Drive 後刪除,光是 OAuth 用 Service Account 就花了 2 天測試,後來還發生好幾次出錯重修。
網路設定對 vibe coder 太複雜了,看到 AI 一次次修改一次次出錯,知道一週後才穩定,而 n8n 只需要申請 credential 填入,10 分鐘搞定,差距太大了。
問題是,n8n 實在太慢了,全圖像界面也難以跟程式碼整合,vibe coder 就算知道了也無法整合,他會繼續用 python 就是無法忍受 n8n 的慢速、沉重,及對 AI 的不友善。
Arcrun 用幾個基礎 Auth 零件取代 n8n 幾百個不同的 credentials 設定,arcrun 完全可以跟程式碼整合,只是目前沒有整合工具,也就是說,工程師不想面對一個認證花好幾天,他只要用 Arcrun 打 API 就幾行解決了。
用這個策略,讓具有程式知識的人會:
- 對 Arcrun 有好感,在 GitHub 按星
- 成為 Arcrun 用戶,增加會員 base
- 寫文分享,讓 Arcrun 被傳出去
反之,小白初學 vibe coding,看到老工程師說 2 天變成 10 分鐘,百行程式碼變成 2 行,也會被影響。
所以,把 API 包裝成 Lib 或 SDK 是個 Get Member 的好方法,不過一定要有 Email。
## 推廣方式 2: 讓 n8n 來 call
身為 n8n 講師,我非常清楚 n8n 有個大缺陷(或說是安全設計),就是它只能呼叫在工作流實例化前就寫好的程式,無法注入新的。
所以,雖然它可以安裝一個實作 langchain AI Agent 的 AI Agent 節點,但 AI 卻不可能在遇到問題時立刻寫個程式運行解決問題,甚至使用它內建的 task runners 或使用外部的 Python runtime 也無法。
但只要使用 http request 節點呼叫外部的 Arcrun tool,它就可以輸出三元組寫一個程式解決它現在遇到的問題,並且運算完後回傳,只需要取得一個 API Key。
## 可能的效應
工程師是意見領袖,他們會去按星,幫忙教育市場,而小白需要被教育,但他們是較大的社群,這些星數和聲量會在未來變成 AI 訓練素材,甚至推薦用戶使用最 AI Friendly 的 Arcrun。
而實際上 Arcrun 的設計讓 AI 更輕鬆。
## 要做什麼
docs/user_requirements/arcrun/ADR-lib-and-landingPage/arcrun-pages-spec.md 這是 claude.ai 寫的規劃,因為它看不到 codebase,所以你要斟酌如何開發。
另外,當前的 API Key 雖然很容易取得,卻有個問題,用戶無法管理,所以頁面應該要有取得 API Key 的界面,可以 Google, GitHub 等 OAuth 或 Email + Password 登入,用來管理它的 API Key 的 CRUD。
或許是可以外接一個 SMTP 服務來確認他的 Email 真實,SaaS 服務還是有成本,雖然成本不高。
另外,既然是 OpenSource,成本雖然不高,似乎可以銜接 Donate 服務?
+761
View File
@@ -0,0 +1,761 @@
# arcrun Credential System 設計規格
20260418
> **讀者**Claude CodeCC),負責實作
> **作者**richblack(架構決策)
> **版本**v1.0
> **狀態**:Draft — 等 CC 確認技術可行性後開工
---
## 0. TL;DR(給 CC 的三句話版)
1. **不要**為每個服務寫一個 credential 零件,n8n 是錯的。
2. 做**四個 TinyGo/WASM 零件**primitives),每個服務只需要一份 **YAML recipe** + 用戶自己的 **secret**
3. Recipe 存 arcrun 平台 KV(公共),secret 存 tenant KV(私有),兩者在 runtime 由 `AuthBroker` 組裝成可用的 HTTP client。
---
## 1. 設計目標與反目標
### 目標
- **新增一個服務的成本 = 寫一份 YAML**,不需要 rebuild、不需要改 code。
- **AI agent 理解成本 ≈ 0**:recipe 就是呼叫該服務的完整說明書。
- **人類設定成本 < 10 分鐘**:即使是對 OAuth 不熟的使用者,UI 只問「你的 API Key 是什麼」這類 secret 層級問題。
- **Secret 隔離**:每個 tenant 的 secret 絕對不互相可見,arcrun 平台本身也無法明文讀取(用 Cloudflare Secrets Store 或加密儲存)。
### 反目標(明確不做的事)
- ❌ 不做 n8n 那種「每個服務一個 credential type」的視覺化面板。
- ❌ 不支援 OAuth1(2026 年還在用的服務極少,真遇到再加)。
- ❌ 不做 credential sharing 的複雜 ACL(全 tenant scope 即可,未來再擴充)。
- ❌ 不在 arcrun 內部明文持久化任何長期 secret(只有加密過的密文或 Secrets Store reference)。
---
## 2. 核心架構:三層模型
```
┌─────────────────────────────────────────────────────────┐
│ Layer 3: Service Recipe (YAML) │
│ arcrun 平台共享,describe "如何呼叫這個服務" │
│ 存在 Workers KV: arcrun-recipes │
│ 例:recipe/notion.yaml, recipe/google_calendar.yaml │
└─────────────────────────────────────────────────────────┘
↓ 引用
┌─────────────────────────────────────────────────────────┐
│ Layer 2: Auth Primitive (TinyGo → WASM) │
│ 四個通用認證零件,實作注入邏輯與 token 交換 │
│ 1. static_key 2. oauth2 │
│ 3. service_account 4. mtls │
└─────────────────────────────────────────────────────────┘
↑ 使用
┌─────────────────────────────────────────────────────────┐
│ Layer 1: Tenant Secret (KV + Secrets Store) │
│ 每個 tenant 自己的 KV namespace │
│ 存 encrypted secret 或 Secrets Store reference │
│ 例:secret/{tenant_id}/notion-prod │
└─────────────────────────────────────────────────────────┘
```
### 為什麼這樣切?
| 切分維度 | Recipe | Primitive | Secret |
|---|---|---|---|
| **誰擁有** | arcrun 平台 | arcrun 平台 | tenant 自己 |
| **變化頻率** | 中(新服務時) | 低(認證機制穩定) | 高(rotate、revoke |
| **敏感度** | 公開 | 公開 | 最高機密 |
| **儲存位置** | 平台 KV`arcrun-recipes` | WASM binary | tenant KV + Secrets Store |
| **可否社群貢獻** | ✅ PR | ⚠️ 核心團隊 | ❌ 永遠不 |
---
## 3. 四個 Primitive 詳細規格
### 3.1 `static_key`
**適用**API Key、Bearer Token、Basic Auth、任何「一組 secret 不會自動過期」的認證。
**涵蓋 n8n 的**API Key、Basic Auth、Header Auth、Query Auth、Custom Auth、Digest Auth~80% 服務)。
**Recipe 欄位**
```yaml
primitive: static_key
inject:
# 四個注入位置,可以同時用多個
header: # HTTP headers
<key>: <value template>
query: # URL query string
<key>: <value template>
body: # request bodyJSON 欄位)
<key>: <value template>
basic_auth: # HTTP Basic Auth(會自動 base64 編碼)
username: <value template>
password: <value template>
```
**Value template 語法**`{{secret.xxx}}` 取 secret 欄位,`{{const.yyy}}` 取 recipe 內定義的常數。
**Secret schema**tenant 存 JSON,欄位由 recipe 的 `required_secrets` 宣告。
**範例(Notion**
```yaml
# arcrun-recipes KV: recipe/notion
service: notion
version: 1
primitive: static_key
base_url: https://api.notion.com/v1
required_secrets:
- key: token
label: "Internal Integration Token"
help_url: https://www.notion.so/my-integrations
inject:
header:
Authorization: "Bearer {{secret.token}}"
Notion-Version: "2022-06-28"
test:
method: GET
path: /users/me
expect_status: 200
```
**Secret 範例**
```json
// tenant KV: secret/tenant_123/notion-prod
{
"token": "secret_abc123..."
}
```
---
### 3.2 `oauth2`
**適用**:需要人類首次授權、之後用 refresh token 續命的場景。
**Grant types 支援**
- `authorization_code`(最常見:GitHub、Slack、Google 用戶授權)
- `client_credentials`(機器對機器)
- `pkce`SPA、行動應用)
- ❌ 不支援:password grant2026 已被多數 OAuth 提供者棄用)、implicit(已棄用)
**Recipe 欄位**
```yaml
primitive: oauth2
grant: authorization_code # or client_credentials, pkce
base_url: <service API base>
oauth:
authorize_url: <IdP authorize endpoint>
token_url: <IdP token endpoint>
scopes:
- <default scope 1>
- <default scope 2>
client_auth: header # or body
# 是否使用 refresh token
refresh: true
# PKCE 時額外參數
pkce_method: S256 # only for grant: pkce
required_secrets:
- key: client_id
label: "Client ID"
- key: client_secret
label: "Client Secret"
secret: true
inject:
header:
Authorization: "Bearer {{runtime.access_token}}"
```
**Runtime 欄位**primitive 自動維護,存在 tenant KV 的 `oauth_state/{secret_id}` key):
- `access_token`
- `refresh_token`
- `expires_at`
**首次授權流程**(人類要做的部分):
1. arcrun UI 呼叫 `AuthBroker.startAuth(recipe_id, tenant_id)` 回傳 authorize URL。
2. 使用者瀏覽器跳轉到 IdP,同意授權。
3. IdP redirect 回 arcrun callback endpoint(固定一個 URL,無論哪個服務)。
4. `AuthBroker` 用 authorization code 換 token,寫入 tenant KV。
**之後 agent 呼叫時完全自動**primitive 檢查 `expires_at`,過期自動用 refresh token 續,失敗再觸發重新授權通知。
---
### 3.3 `service_account`
**適用**Google Service Account、AWS IAM Roleassume role)、任何需要「私鑰簽 JWT 換短期 token」的機器身份。
**這個就是讓你 debug 兩天那個爆炸點。** 我們用 primitive 把地雷全部包起來。
**Recipe 欄位**
```yaml
primitive: service_account
kind: google_jwt # or aws_sigv4, generic_jwt
base_url: <service API base>
token_exchange:
# Google 的 JWT → OAuth access token 流程
endpoint: https://oauth2.googleapis.com/token
audience: https://oauth2.googleapis.com/token
scopes:
- https://www.googleapis.com/auth/calendar
# JWT claims
issuer_from_secret: client_email
subject_from_secret: client_email # optional, for domain-wide delegation 改成其他 user
ttl_seconds: 3600
required_secrets:
- key: service_account_json
label: "Service Account JSON"
type: json_blob # 特別型別,UI 可以接受貼整個 JSON
help: "到 GCP Console → IAM → Service Accounts → Keys → Add Key (JSON) 下載整份 JSON 貼上"
inject:
header:
Authorization: "Bearer {{runtime.access_token}}"
```
**為什麼不是每個服務一個 recipe?**
- Google Calendar、Gmail、Drive、Sheets 全部可以共用同一個 `service_account` primitive。
- 差別只在 `scopes``base_url`
- Recipe 本身可以 import 共通片段(見 §5 recipe 繼承)。
**AWS SigV4kind: aws_sigv4**:這是特例,不是 JWT-based,但概念一樣——用 access_key_id + secret_access_key 在每次 request 上簽章。Primitive 內建處理,recipe 只要宣告 region 和 service name。
---
### 3.4 `mtls`
**適用**mTLS / client certificate。銀行 API、企業內部服務、醫療系統。
**Recipe 欄位**
```yaml
primitive: mtls
base_url: <service API base>
required_secrets:
- key: client_cert
label: "Client Certificate (PEM)"
type: pem_cert
- key: client_key
label: "Client Private Key (PEM)"
type: pem_key
secret: true
- key: ca_cert
label: "CA Certificate (PEM) — optional"
type: pem_cert
optional: true
# mtls 通常不需要額外 inject,憑證在 TLS 層
inject: {}
```
**實作注意**Cloudflare Workers 有原生 mTLS 支援(`mTLSCertificate` binding),primitive 只需要把 secret 轉成 Cloudflare mTLS binding 即可。
---
## 4. Recipe YAML Schema(完整版)
```yaml
# 必填
service: string # 唯一識別,snake_casee.g. "notion", "google_calendar"
version: integer # recipe schema versionbreaking change 要升版
primitive: enum # static_key | oauth2 | service_account | mtls
base_url: string # service API base URL
# primitive 相關(依 primitive 不同)
inject: object # 如何把 secret 注入 HTTP request
oauth: object # 僅 oauth2 primitive
token_exchange: object # 僅 service_account primitive
# Secret 宣告(讓 UI 知道要問什麼)
required_secrets:
- key: string # secret 欄位名
label: string # UI 顯示
secret: boolean # 是否遮蔽顯示(default: true
type: enum # text | json_blob | pem_cert | pem_key | url
optional: boolean # default: false
help: string # 給使用者的提示
help_url: string # 導向服務文件
# 測試(驗證 credential 是否有效)
test:
method: GET | POST
path: string # 相對 base_url
expect_status: integer
expect_json: object # 選填,JSON path assertion
# Metadata
display_name: string # UI 顯示名
description: string
icon_url: string
docs_url: string
tags:
- communication
- crm
- ai
maintainers:
- github: username
# 可選:共通片段繼承
extends: string # recipe name,繼承其 schema 後覆寫
```
---
## 5. Recipe 繼承(reduce 重複)
Google 家族的 API 長得很像,重複寫 15 次太蠢。支援 `extends`
```yaml
# recipe/_google_base.yaml(底線開頭 = 抽象 recipe,不能直接用)
service: _google_base
version: 1
primitive: service_account
token_exchange:
endpoint: https://oauth2.googleapis.com/token
audience: https://oauth2.googleapis.com/token
ttl_seconds: 3600
required_secrets:
- key: service_account_json
type: json_blob
inject:
header:
Authorization: "Bearer {{runtime.access_token}}"
```
```yaml
# recipe/google_calendar.yaml
extends: _google_base
service: google_calendar
version: 1
base_url: https://www.googleapis.com/calendar/v3
token_exchange:
scopes:
- https://www.googleapis.com/auth/calendar
test:
method: GET
path: /users/me/calendarList
expect_status: 200
```
繼承規則:scalar 覆寫,object 深度合併,array 預設覆寫(可用 `!append` 標記 append)。
---
## 6. TinyGo WASM Primitive 實作介面
### 6.1 統一介面(四個 primitive 都實作這個)
```go
// primitive/interface.go
package primitive
type AuthRequest struct {
Method string
URL string
Headers map[string]string
Body []byte
}
type AuthContext struct {
Recipe Recipe // parsed YAML
Secret map[string]any // decrypted secret
Runtime RuntimeState // oauth token cache 等
Now int64 // for testing
}
type Primitive interface {
// 在 HTTP request 上注入認證資訊
Authenticate(req *AuthRequest, ctx *AuthContext) error
// 檢查是否需要 refreshoauth2 / service_account 用)
NeedsRefresh(ctx *AuthContext) bool
// 執行 refresh / token exchange,回傳新的 RuntimeState
Refresh(ctx *AuthContext) (RuntimeState, error)
// 驗證 credential 是否有效(執行 recipe.test
Test(ctx *AuthContext) error
}
```
### 6.2 編譯與部署
```bash
# 四個 primitive 各自編譯成獨立 WASM
tinygo build -o dist/static_key.wasm -target=wasi ./primitive/static_key
tinygo build -o dist/oauth2.wasm -target=wasi ./primitive/oauth2
tinygo build -o dist/service_account.wasm -target=wasi ./primitive/service_account
tinygo build -o dist/mtls.wasm -target=wasi ./primitive/mtls
# 部署時放到 Cloudflare Workers 的 Assets 或直接內嵌
```
### 6.3 Runtime 載入(Worker 端)
```typescript
// worker/src/auth-broker.ts
import staticKeyWasm from "../dist/static_key.wasm"
import oauth2Wasm from "../dist/oauth2.wasm"
// ...
const primitives = {
static_key: await instantiate(staticKeyWasm),
oauth2: await instantiate(oauth2Wasm),
service_account: await instantiate(serviceAccountWasm),
mtls: await instantiate(mtlsWasm),
}
```
> **為什麼 WASM 而不是直接 TS**
> 1. 跨 runtime 可攜性(未來若 arcrun 要跑在 Fly.io、local、或客戶自建環境,同一個 primitive 能用)。
> 2. 配合 u6u/arcrun 既定的 WASM 架構方向,不破壞統一性。
> 3. 沙箱化:primitive 只能透過明確的 host function 存取外部世界(網路、KV),降低惡意 recipe 攻擊面。
---
## 7. AuthBroker API(給 arcrun 其他部分調用)
```typescript
interface AuthBroker {
// Agent 執行時用的主要 API
bind(serviceId: string, secretRef: string, tenantId: string): Promise<AuthenticatedClient>
// 首次授權(僅 oauth2 用)
startAuth(serviceId: string, tenantId: string): Promise<{ authorizeUrl: string, state: string }>
completeAuth(state: string, code: string): Promise<{ secretRef: string }>
// 測試 credential
test(serviceId: string, secretRef: string, tenantId: string): Promise<TestResult>
// 管理
listRecipes(): Promise<Recipe[]>
getRecipe(serviceId: string): Promise<Recipe>
}
interface AuthenticatedClient {
fetch(path: string, init?: RequestInit): Promise<Response>
}
```
**使用範例(agent 端)**
```typescript
const notion = await authBroker.bind("notion", "notion-prod", ctx.tenantId)
const res = await notion.fetch("/databases/abc/query", {
method: "POST",
body: JSON.stringify({ filter: {...} })
})
```
**Agent 完全不需要知道是 API Key 還是 OAuth**——`authBroker.bind()` 回傳的 client 已經注入好認證,fetch 路徑用相對 base_url 的路徑即可。
---
## 8. Storage Layout
### 8.1 Recipe 儲存(arcrun 平台共享)
**Cloudflare KV namespace**`arcrun-recipes`
```
key: recipe/{service_id}
value: <recipe YAML 的 JSON 化版本>
key: recipe-list
value: [{ service_id, display_name, icon_url, tags }, ...] # 加速 UI 列表
```
**更新流程**
1. Recipe YAML 存在 arcrun 主 repo 的 `recipes/` 目錄下(version control + PR review)。
2. CI 跑 schema validator,通過後上傳到 KV。
3. UI 的 recipe 列表 5 分鐘 cache。
### 8.2 Secret 儲存(tenant 私有)
**雙層策略**
- **短期、低敏感** → tenant KV,用 AES-256-GCM 加密,key 從 Cloudflare Secrets Store 拿。
- **高敏感(如 service account JSON、private key** → 直接存 Cloudflare Secrets Storetenant KV 只存 reference。
```
# tenant KV namespace: arcrun-tenant-{tenant_id}
key: secret/{service_id}/{instance_name}
value: {
"recipe_version": 1,
"storage_mode": "kv_encrypted" | "secrets_store_ref",
"data": <encrypted blob> | { "ref": "secrets-store-id" },
"created_at": "...",
"last_verified_at": "..."
}
# oauth2 runtime stateprimitive 自動管理)
key: oauth_state/{service_id}/{instance_name}
value: {
"access_token": "...", # encrypted
"refresh_token": "...", # encrypted
"expires_at": 1234567890
}
```
**secretRef 格式**`{service_id}/{instance_name}`,例如 `notion/prod``google_calendar/workspace-a`
一個 tenant 可以同一個服務存多個 instance(多帳號場景)。
### 8.3 KBDB 整合(可選,但建議)
**按照 KBDB 架構,recipe metadata 可以用 Block + Template 表達**(不是 credential 本體,只是 metadata):
建立一個 `service_recipe` Template
```json
{
"name": "service_recipe",
"display_name": "服務 Recipe Metadata",
"schema": {
"fields": [
{"key": "service_id", "type": "text", "required": true, "description": "服務識別"},
{"key": "primitive", "type": "text", "required": true, "description": "使用的 primitive"},
{"key": "version", "type": "number", "required": true, "description": "Recipe 版本"},
{"key": "display_name", "type": "text", "required": false, "description": "顯示名稱"},
{"key": "docs_url", "type": "text", "required": false, "description": "文件 URL"},
{"key": "kv_key", "type": "text", "required": true, "description": "KV 實際存取 key"}
]
}
}
```
Secret **不**進 KBDBKBDB 不該存敏感資料),只有 metadata 在 KBDB 裡方便搜尋和關聯。
---
## 9. 首次授權 UI Flow(給人類看的部分)
這是「學員不知道該選哪個 credential 的痛點」的終結方案。
### 9.1 Static Key 的 UI
```
┌──────────────────────────────────────────┐
│ 連接 Notion │
├──────────────────────────────────────────┤
│ │
│ Internal Integration Token │
│ ┌────────────────────────────────────┐ │
│ │ secret_••••••••••••• │ │
│ └────────────────────────────────────┘ │
│ ↳ 如何取得?→ 開啟 Notion 整合設定頁 │
│ │
│ [ 測試連線 ] [ 儲存 ] │
└──────────────────────────────────────────┘
```
**零選項。** UI 從 recipe 的 `required_secrets` 動態生成。使用者不用選「這是 Header Auth 還是 Query Auth 還是 Custom Auth」——那是 recipe 的事,不是使用者的事。
### 9.2 OAuth2 的 UI
```
┌──────────────────────────────────────────┐
│ 連接 GitHub │
├──────────────────────────────────────────┤
│ │
│ [ 🔗 使用 GitHub 帳號登入 ] │
│ │
│ 將跳轉到 GitHub,授權後自動返回 │
│ │
└──────────────────────────────────────────┘
```
**一個按鈕。** Client ID / Secret 由 arcrun 平台統一管理(OAuth App 註冊在 arcrun 這邊),使用者看不到也不用知道。
### 9.3 Service Account 的 UI
```
┌──────────────────────────────────────────┐
│ 連接 Google Calendar │
├──────────────────────────────────────────┤
│ │
│ Service Account JSON │
│ ┌────────────────────────────────────┐ │
│ │ 將整份 JSON 貼到這裡 │ │
│ │ │ │
│ │ { │ │
│ │ "type": "service_account", │ │
│ │ "project_id": "...", │ │
│ │ ... │ │
│ │ } │ │
│ └────────────────────────────────────┘ │
│ │
│ 如何取得?→ 展開步驟說明 ▼ │
│ 1. 打開 GCP Console │
│ 2. IAM → Service Accounts │
│ 3. 建立 Service Account │
│ 4. Keys → Add Key → JSON │
│ 5. 下載後整份貼到上方 │
│ │
│ [ 測試連線 ] [ 儲存 ] │
└──────────────────────────────────────────┘
```
**貼 JSON + 按鈕**。不用寫任何程式碼,不用 debug 兩天。
---
## 10. 實作任務分解(CC 的 TODO list
### Phase 1:核心骨架(1-2 週)
- [ ] **T1.1** Recipe YAML schema 定義 + JSON Schema validator(放 `arcrun/schemas/recipe.schema.json`
- [ ] **T1.2** Recipe loader:從 `recipes/` 目錄讀 YAML → validate → 轉 JSON 存入 KV namespace `arcrun-recipes`
- [ ] **T1.3** TinyGo WASM 專案骨架(`arcrun/primitives/`),四個子目錄,統一 interface
- [ ] **T1.4** Worker runtime 的 WASM loader + host function(網路、KV 讀寫)
- [ ] **T1.5** `AuthBroker` TypeScript 類別骨架 + unit test
### Phase 2Static Key1 週)
- [ ] **T2.1** `static_key.wasm` 實作(header/query/body/basic_auth 四種注入)
- [ ] **T2.2** 寫三個 recipe`notion.yaml`, `openai.yaml`, `stripe.yaml`
- [ ] **T2.3** Tenant KV secret 加密寫入 + `AuthBroker.bind()` 整合
- [ ] **T2.4** `recipe.test` 執行器(驗證 credential 有效性)
- [ ] **T2.5** E2E test:存 secret → bind → fetch Notion API → assert
### Phase 3OAuth21-2 週)
- [ ] **T3.1** `oauth2.wasm` 實作(authorization_code + client_credentials + pkce
- [ ] **T3.2** OAuth callback endpoint(統一 URL,用 state 路由到正確 tenant/recipe
- [ ] **T3.3** Refresh token 自動續命邏輯(rate-limit 保護:同一 token 不能 1 秒內 refresh 多次)
- [ ] **T3.4** 寫三個 recipe`github.yaml`, `slack.yaml`, `google_oauth_user.yaml`
- [ ] **T3.5** UI flowstartAuth → 跳轉 → callback → 寫 secret
### Phase 4Service Account1 週)
- [ ] **T4.1** `service_account.wasm` 實作(google_jwt
- [ ] **T4.2** Google JWT signingES256 / RS256)— **這個 TinyGo 需要注意 crypto 支援**
- [ ] **T4.3** AWS SigV4 簽章實作(kind: aws_sigv4
- [ ] **T4.4** Recipe 繼承機制(`extends` 支援)
- [ ] **T4.5** 寫 recipes`_google_base`, `google_calendar`, `google_drive`, `gmail`, `aws_s3`
### Phase 5mTLS + 收尾(1 週)
- [ ] **T5.1** `mtls.wasm` 實作(對接 Cloudflare `mTLSCertificate` binding
- [ ] **T5.2** Cloudflare Secrets Store 整合(高敏感 secret 用)
- [ ] **T5.3** Recipe marketplace UI(列出可用 recipe,搜尋,一鍵設定)
- [ ] **T5.4** Observability:每次 bind / refresh / test 記錄到 KBDBmetadata,不含 secret
- [ ] **T5.5** Docs:recipe 撰寫指南(讓社群能貢獻)
### Phase 6Recipe 生成器(選配,1 週)
- [ ] **T6.1** 給 Claude 一份 API doc,自動產 recipe YAML 草稿 + 人類 review 介面
- [ ] **T6.2** 從 OpenAPI spec 自動推論 recipe
- [ ] **T6.3** 從 n8n credential file 反向轉譯(擷取 400+ 現成整合)
---
## 11. 關鍵技術風險與對策
| 風險 | 對策 |
|---|---|
| **TinyGo 的 crypto 支援不完整**ES256 / RS256 JWT 簽章) | 先用 `crypto/rsa` + `crypto/ecdsa` 確認 TinyGo 版本支援;若不行,fallback 用 Worker runtime 的 `crypto.subtle` 實作這部分,WASM 透過 host function 呼叫 |
| **Recipe 被惡意提交**(如 inject 內含 `https://evil.com` 當 token_url | Recipe 走 PR review + CI 自動檢查 URL 白名單;社群貢獻的 recipe 預設隔離在 `community/` 目錄,使用者明確選擇才啟用 |
| **OAuth state CSRF** | state 用 `crypto.randomUUID()` + 5 分鐘 TTL,存在 KVcallback 時比對 |
| **Secret 在 Worker log 外洩** | `AuthContext.Secret` 禁止 `toString` / `JSON.stringify`,用 Proxy 攔截;log 層強制 redact |
| **Token refresh 風暴**100 個並發 request 同時發現過期) | 用 Durable Object 單執行緒化每個 secret 的 refresh,其他 request 等結果 |
| **TinyGo WASM bundle size** | 四個 primitive 分開編譯,最大 500KB/個;lazy load |
| **Recipe 版本升級破壞相容** | `version` 欄位 semvertenant secret 記錄 `recipe_version`primitive 內處理遷移 |
---
## 12. 對比 n8n(給內部 review / 行銷用)
| 維度 | n8n | arcrun |
|---|---|---|
| Credential types 數量 | 400+(一個服務一個) | 4primitive + N recipe |
| 新增一個服務 | 寫 TypeScript class + rebuild + npm publish | 寫一份 YAML + PR merge |
| AI agent 使用 | 需要讀 node 文件 + 猜參數 | 讀 recipe YAML 即可 |
| 使用者首次設定 | 從 400+ 選項選一個(常選錯) | 搜尋服務名,只問必要 secret |
| OAuth App 管理 | 使用者自己註冊 OAuth app | arcrun 平台統一管理(使用者只需點「授權」) |
| 社群貢獻成本 | 高(TS + 編譯 + 測試) | 低(YAML + 測試) |
---
## 13. 接下來的決策點(需要 richblack 確認)
- [ ] **Recipe 版本管理策略**:採用 semver?每個 recipe 獨立版本?還是整個 recipe set 一個版本?
- [ ] **OAuth App 註冊**:arcrun 平台要統一註冊幾個主流服務的 OAuth AppGitHub、Google、Slack、Microsoft)?還是讓 tenant 自己帶 client_id/secret
- 建議:**雙模式**——平台模式(方便)+ BYO 模式(企業客戶用自己的 OAuth app 有稽核好處)
- [ ] **Recipe registry 的審核流程**:完全開放 PR 還是僅核心團隊維護?
- 建議:`recipes/official/`(核心維護)+ `recipes/community/`(PR 審核後 merge,使用者需明確啟用)
- [ ] **Secret rotation 政策**:要不要內建提醒 / 自動 rotate?(Phase 7+
---
## 14. 附錄:完整範例
### A. 最小可行 recipeOpenAI
```yaml
service: openai
version: 1
primitive: static_key
display_name: OpenAI
base_url: https://api.openai.com/v1
required_secrets:
- key: api_key
label: API Key
help_url: https://platform.openai.com/api-keys
inject:
header:
Authorization: "Bearer {{secret.api_key}}"
test:
method: GET
path: /models
expect_status: 200
tags: [ai]
```
### B. OAuth2 recipeSlack
```yaml
service: slack
version: 1
primitive: oauth2
display_name: Slack
base_url: https://slack.com/api
grant: authorization_code
oauth:
authorize_url: https://slack.com/oauth/v2/authorize
token_url: https://slack.com/api/oauth.v2.access
scopes:
- chat:write
- channels:read
refresh: true
client_auth: header
inject:
header:
Authorization: "Bearer {{runtime.access_token}}"
test:
method: POST
path: /auth.test
expect_json:
ok: true
tags: [communication]
```
### C. Service Account recipeGoogle Calendar
```yaml
extends: _google_base
service: google_calendar
version: 1
display_name: Google Calendar
base_url: https://www.googleapis.com/calendar/v3
token_exchange:
scopes:
- https://www.googleapis.com/auth/calendar
test:
method: GET
path: /users/me/calendarList
expect_status: 200
tags: [calendar, google]
```
---
## 15. 給 CC 的行動指引
1. **先不要動既有 arcrun 的 credential 相關 code**,保持現狀到 Phase 2 完成再切換。
2. **Phase 1 + 2 是 MVP**,做完可以接 80% 服務(API key 類)。
3. **遇到 TinyGo 的技術阻礙(特別是 crypto),立刻回報**,不要自己 workaround 兩天。
4. 每個 Phase 完成後寫一份 brief report(能跑什麼、不能跑什麼、下一步)。
5. Recipe 撰寫先做 3-5 個手工範例,**確認 schema 夠用再開始批量生成**。
@@ -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 個先做完整,之後再擴充)
@@ -0,0 +1,89 @@
# **u6u 智慧前端與工匠 AI 開發藍圖 (v4.0)**
## **一、 核心設計理念:意圖導向的雙面畫布**
u6u 的前端不是傳統的平面繪圖板,而是一個類似 Android Studio 或 Figma 的\*\*「結構化標籤編輯器」**。 畫布上的每一個元件(Web Component),本質上都是一個**「意圖發射器 (Intent Emitter)」\*\*。前端只負責「長得好看」與「收集人類動作」,後端全權負責「業務邏輯」。
### **人機協作的「雙向同步」**
* **AI 詠唱修改:** 人類說「把按鈕改醒目一點」,CEO AI 在背景將 \<u6u-btn color="blue"\> 修改為 \<u6u-btn color="neon-red"\>,畫面瞬間更新。
* **人類手動覆寫:** 人類覺得 AI 調的紅色太暗,直接在右側屬性面板 (Properties Panel) 點選色碼器,底層 HTML 屬性隨之改變。**AI 也能「看見」這個改變,從中學習人類的審美偏好。**
## **二、 畫布介面設計與運作機制**
### **1\. 正反面翻轉機制 (The "Flip" Interface)**
每個 UI 零件在畫布上都有「一體兩面」:
* **正面 (UI 視圖):** 顯示 HTML 渲染的視覺結果(按鈕、溫度計、圖表)。人類可以在此調整 CSS 屬性、對齊方式與主題顏色。
* **反面 (邏輯視圖):** 點擊「翻面」按鈕後,會進入底層的工作流設定。這裡使用 u6u 的自定義 Cypher 視覺化語法(例如 \>\> 符號)。
* *範例:* \[ UI\_Button: "緊急停機" \] \>\> (Intent: emergency\_stop) \>\> \[ WASM: gsheets\_create \]
### **2\. 智慧容器與區域感知 (Smart Zone Awareness)**
為了消滅傳統 iPaaS(如 n8n)最痛苦的「手動變數綁定」,u6u 畫布具備「區域感知」能力。
* **底層邏輯(獨立元件):** 畫布上的 TextInput 與 Button 都是各自獨立的原子元件。
* **麻瓜體驗(智慧表單):** 當使用者將這兩個元件拖入同一個排版容器(例如 \<u6u-card\>)時,系統會自動建立上下文關聯。當按下按鈕並觸發 Webhook 時,按鈕會**自動打包同容器內所有輸入框的值**一併送出:
{
"intent": "query\_attendance",
"payload": { "employee\_id": "A1234" } // 自動從旁邊的 TextInput 抓取
}
使用者完全不需要理解「表單傳值」或「變數綁定」,拖拉組合即生效。
### **3\. 多重事件插槽與靜態屬性 (Multi-Event Slots)**
一個前端元件可以具備多種觸發行為,系統透過介面將「視覺」與「後端邏輯」徹底分流:
* **靜態視覺註釋:** 例如 mouseover 顯示提示。使用者只需在屬性面板輸入 Tooltip 文字,底層僅修改 HTML 屬性 \<u6u-btn tooltip="..."\>,不消耗任何伺服器資源或 Webhook。
* **動態意圖綁定:** 在「反面」邏輯視圖中,使用者可以針對不同事件綁定不同的工作流:
* ⚡ When: 點擊 (onClick) ➡️ \[ 綁定至 Webhook A:送出查詢 \]
* ⚡ When: 獲得焦點 (onFocus) ➡️ \[ 綁定至 Webhook B:載入歷史紀錄 \]
### **4\. 智慧上下文替換 (Smart Contextual Substitution)**
當主管在畫布上對著一個已連接 Webhook 的「按鈕」點擊右鍵選擇「替換元件」時:
* 系統讀取反面的 Cypher 連線,發現需要發射一個 trigger 意圖。
* 系統過濾 KBDB 零件宇宙,**只顯示相容的 UI 零件**(如下拉選單、開關)。不具備 trigger 能力的元件(如純文字標籤)會被自動隱藏,確保替換後系統絕對不會報錯。
## **三、 原子化組裝與極致解耦:CEO AI 與工匠 AI 的分工**
當企業主管提出需求:「我需要一個『輸入工號即可查詢員工打卡紀錄』的工具」時,這在 u6u 中**並不是一個單一零件**,而是一個由多個「原子零件」構成的**工作流 (Workflow)**。
### **1\. CEO AI 的動態組裝 (Macro Assembly)**
面對需求,大腦 AI (CEO AI) 會快速從 KBDB 挑選現成積木進行組合:
* **前端 Prototype 組合:** \<u6u-text-input\> \+ \<u6u-btn\> \+ \<u6u-text-field\>。
* **後端 Pseudo Code 組合:** webhook\_receiver \>\> check\_kbdb(template\_name, value)。
AI 會自動用 Cypher 將前端的表單意圖連線到後端工作流。對不懂程式的主管來說,前端就是 Prototype,翻面的 Cypher 就是 Pseudo Code,整套系統瞬間組合完畢。
### **2\. 工匠 AI (Forge AI) 的原子生產線**
只有當現有零件庫缺乏特定原子時,機甲才會喚醒工匠 AI 進行開發。
**解耦哲學:** 後端零件開發時,根本不需要管前端零件長什麼樣子(是按鈕還是輸入框)。只要前端送來的 JSON 它能吃,就是合法的候選零件。
* **Step 1: 規格定義 (Interface Contract)**
工匠 AI 只在乎接收與回傳的 JSON 格式。
* **Step 2: 打造純粹的邏輯黑箱 (後端 TinyGo WASM)**
工匠 AI 撰寫 Go 程式,編譯成 .wasm。絕對純粹的後端邏輯,沒有任何介面程式碼。
* **Step 3: 獨立的前端零件生產 (若需要)**
獨立生成 Web Component(如 \<u6u-3d-pie-chart\>),只負責接收特定 JSON 來渲染畫面。
* **Step 4: 註冊與編目 (Cataloging into KBDB)**
新積木註冊到圖資料庫,未來的 CEO AI 即可將其與任何既有的前端或後端元件進行無限的叉積組合。
## **四、 架構總結與終極產品體驗**
這套前端架構讓 u6u 成為一個\*\*「表裡如一」**的系統,成功創造了**「麻瓜的 ERP 幻覺」\*\*:
使用者不需要知道什麼是「前後端分離」、什麼是「API 串接」。他們只是覺得:
1. 拖拉了一個溫度計。
2. 翻面把「數值更新」連線到「機台感測器」。
3. 拖拉了一個紅按鈕放在旁邊。
4. 翻面把「點擊」連線到「發送 Line 警報」。
在十分鐘的「繪圖」過程中,沒有寫一行程式碼,也沒有設定任何變數。但透過**前端 Web Components** 的視覺封裝、**智慧容器**的自動資料打包,以及**後端 TinyGo WASM \+ Cypher** 的無縫承接,他們在不知不覺中,就搭建出了一套具備微服務架構、高擴展性、且可部署至極限邊緣的企業級系統。
@@ -0,0 +1,136 @@
# **u6u 系統與零件宇宙全景規劃白皮書 (The u6u Ecosystem Blueprint)**
## **1\. 核心理念與願景**
u6u 旨在解決傳統 Workflow 軟體 (如 n8n) 存在的「單線程、沈重、複雜、難以組成系統」的痛點。
透過結合 Cloudflare Workers (輕量邊緣運算) 與 Cypher (圖形資料庫關係),u6u 提供一個由 AI 驅動的「意圖到系統」生成平台。所有的系統功能皆被拆解為可複用、可組合的「零件 (Components)」,並在一個會自然淘汰、自我修復的「零件宇宙 (Component Universe)」中演化。
## **2\. 四層架構拆解 (Four-Tier Architecture)**
u6u 的工作模式採取由上到下 (Top-Down) 的 Break-down 機制:
1. **Polaris (北極星層 / 意圖層):**
* 用戶以自然語言描述商業模式與想法(例如:「我要做一個 AI 客服表單系統」)。
* 這是整個系統的起點,AI 會根據 Polaris 將意圖拆解為 Prototype。
2. **Prototype (原型 / 前端層):**
* 定義前端的版型、頁面描述、UI 元件以及它們的屬性。
* 作為使用者互動的入口,透過觸發事件 (Triggers) 連接到後端 Workflow。
3. **Workflow (工作流層):**
* 系統的 Orchestrator (編排者),定義業務邏輯的走向。
* 透過 Cypher 語法與三元組,定義每個節點 (Component) 的執行順序與條件分支。
4. **Component (零件層 / 節點):**
* 最底層的執行單元,主要分為兩類:
* **功能型 (Logic):** 迴圈、條件判斷、資料轉換、統計等 (透過 CF Workers 執行 JS 邏輯)。
* **介接型 (API):** 呼叫外部服務 (Webhook, HTTP Request)。
## **3\. 統一描述語言:擴展三元組與跨層級 YAML**
為了解決跨 YAML 檔案串接的問題,u6u 採用易於人類閱讀與 AI 生成的 **「A \>\> 關係 \>\> B」** 三元組語法,結合自定義的 URI 協議 (workflow://, component://, ui://),實現跨層級的連結。
### **綜合 YAML 範例與三元組串接**
*\# 1\. Prototype YAML (描述前端)*
kind: Prototype
id: ui\_dashboard
triplets:
*\# 結構與版型零件*
\- "ui\_dashboard \>\> CONTAINS \>\> layout\_admin"
\- "layout\_admin \>\> CONTAINS \>\> btn\_submit"
*\# UI 零件與屬性零件 (CSS/行為)*
\- "btn\_submit \>\> IS\_A \>\> ui://components/Button"
\- "btn\_submit \>\> HAS\_STYLE \>\> style://tokens/GlowEffect"
\- "btn\_submit \>\> HAS\_BEHAVIOR \>\> anim://motions/Pulse"
*\# 跨層級串接:前端觸發 Workflow*
\- "btn\_submit \>\> ON\_CLICK \>\> workflow://workflows/process\_data.yaml"
*\# 2\. Workflow YAML (描述工作流編排)*
kind: Workflow
id: wf\_process\_data
triplets:
*\# 跨層級串接:Workflow 呼叫 Component*
\- "START \>\> TRIGGERS \>\> step\_validate"
\- "step\_validate \>\> IS\_A \>\> component://components/validate\_json"
*\# Workflow 節點間的流轉 (轉譯為 Cypher 關係)*
\- "step\_validate \>\> ON\_SUCCESS \>\> step\_call\_api"
\- "step\_validate \>\> ON\_FAIL \>\> step\_notify\_error"
*\# 跨 Workflow 串接*
\- "step\_call\_api \>\> CALLS\_SUBFLOW \>\> workflow://workflows/save\_to\_db.yaml"
## **4\. 零件宇宙 (Component Universe) 的審核與淘汰機制**
在 u6u 中,所有的 UI、Style、Logic、API 都是「零件」。當 AI 發現缺乏所需零件時,會自動創造它。為了確保生態系的健康,必須建立嚴格的**審核標準**與**自然淘汰機制**。
### **4.1 零件的創建與審核標準 (Pass/Fail Criteria)**
當 AI 或開發者提交一個新零件時,系統會啟動自動化沙盒測試。必須完全通過以下標準,零件才能進入「宇宙」供他人使用:
1. **功能型零件 (Logic Components):**
* **Gherkin BDD 驗收:** 必須附帶 Feature/Scenario 測試規格,且執行結果 100% 通過 (例如:Given input JSON, When split, Then returns Array)。
* **效能門檻:** 邊緣運算 (CF Workers) 執行時間需低於設定閾值 (例如 \< 50ms),無記憶體洩漏。
2. **介接型零件 (API Components):**
* **連線驗證:** 端點 (Endpoint) 必須能 ping 通,或回傳正確的 2xx HTTP Status (提供 Mock Payload 測試)。
* **Credential 安全:** 不可將 Token 或 Secret 寫死在代碼中,必須嚴格宣告所需的 Environment Variables 規格。
3. **前端與屬性零件 (UI & Style Components):**
* **渲染驗證:** CSS / 組件代碼不能導致瀏覽器 Crash。
* **相容性檢查:** 不可包含嚴格衝突的樣式 (例如寫死 \!important 破壞全域版型)。
### **4.2 零件宇宙的自然淘汰 (Natural Selection)**
零件一旦上架,將面臨殘酷的達爾文機制:
* **AI 偏好權重:** AI (透過 MCP 搜尋時) 會優先選擇「成功率高、執行速度快、被調用次數多」的零件。
* **降級與墓地:** 連續 30 天無人/無 AI 使用,或錯誤率飆升的零件,會被降級 (Deprecated)。最終轉入「零件墓地」,從首選搜尋清單中剔除。
## **5\. 系統自癒與 AI 避坑機制 (Auto-Healing & Pitfall Avoidance)**
這是 u6u 維持系統穩定運作的最核心機制。工作流不只要能跑,跑完後還必須經歷 **「強制 AI 評價 (Mandatory AI Evaluation)」**。
### **5.1 運行後的強制評價迴圈**
每當一個 Workflow 在 CF Workers 上執行完畢 (或發生異常中斷),系統攔截日誌並強制啟動 AI 評價代理 (Evaluator Agent)。
* **評估維度:**
* **狀態:** 成功 / 失敗 (Crash) / 逾時 (Timeout)。
* **效能:** 耗時是否合理 (例如 API 突然變得很慢)。
* **警告訊息:** 資源消耗過大、API 回傳即將停用的 Warning。
### **5.2 自癒與避坑流程 (The Feedback Loop)**
當 Evaluator Agent 發現問題時,會觸發以下流程:
1. **回報與通知 (Notify):** 系統自動生成修復 Ticket,並通知當初建立該零件/工作流的製作人 (或系統管理員)。
2. **AI 嘗試修復 (Auto-Fix):** 系統派遣「修復型 AI」嘗試讀取錯誤日誌並修復代碼 (例如:API 規格變更導致 JSON 解析錯誤,AI 自動修改解析邏輯)。
3. **驗收與部署:** 修復後的代碼若通過 Gherkin 驗收,則無縫熱更新。
4. **避坑標記 (Pitfall Marking):** \- 如果 AI 無法修復 (例如:外部第三方 API 永久倒閉,或邏輯存在根本性死結)。
* 系統會在 Cypher 圖形資料庫中,將該零件或該特定的三元組關係標記為 \[HAS\_PITFALL\]。
* **結果:** 下一個生成系統的 AI 在透過 MCP 搜尋時,會讀取到這個坑的紀錄,並**強制繞道**,改用其他方案或生成新的零件,實現「前人踩坑,後 AI 避坑」的群體智慧。
## **6\. 結論**
u6u 不是一個單純的開發工具,它是一個**生物體積木系統**。
透過「三元組」統一語言打破系統壁壘,透過「零件審核」保證基因優良,再透過「強制評價與避坑機制」實現演化。當這套系統運轉起來,AI 就能在其中無止盡地為人類組裝出越來越強大、越來越穩定的商業應用。
@@ -0,0 +1,99 @@
# **u6u 自動演化 ERP:全端統一架構規格書 (v3.0)**
## **1\. 架構核心思想 (The Core Philosophy)**
u6u ERP 是一套具備自我修復與功能擴充能力的「有機體」系統。
為確保系統在跨國雲端、機密地端與斷網邊緣皆能無縫運作,系統採用\*\*「向下相容的絕對標準化」\*\*:由最嚴苛的無人機環境來定義全域零件標準。
系統運作依賴三位一體的語言與載體:
1. **大腦戰略層 (Markdown / Gherkin)** CEO AI 負責閱讀與撰寫,定義全域戰略、系統設計文件 (SDD) 與商業演算法則 (如 ROI 門檻)。
2. **神經編排層 (Cypher)** u6u 引擎的核心。AI 透過撰寫 Cypher 語法來進行業務邏輯的動態編排、狀態流轉與意圖攔截。
3. **肌肉執行層 (TinyGo WASM)** 系統中**唯一合法**的零件規格。負責所有具體的 I/O、資料轉換與運算,保證極小體積與極速冷啟動。
## **2\. 實戰演練:離岸風機巡檢的黑天鵝事件 (三層架構實踐)**
為了具體理解這套系統如何運作,我們以一次「離岸風電場巡檢」的突發事件為例,展示雲、地、邊三層架構的完美協同。
### **第一階段:戰略下達與沙盤推演 (Tier 1 ➡️ Tier 2 ➡️ Tier 3\)**
跨國能源集團的**雲端總部 (Tier 1\)** 收到年度檢修排程。雲端的 **CEO AI** 讀取了全局的 Markdown 戰略文件,向遠在海岸線的**地端指揮中心 (Tier 2\)** 下達指令。
地端指揮中心(配備強大伺服器與 workerd 叢集)的**部門主管 AI** 將任務拆解給 50 台即將出海的無人機。無人機 07 號 **(Tier 3\)** 的小腦 AI 透過本地的 Cypher 引擎進行沙盤推演,從地端資料庫下載了 rgb\_vision.wasm (光學影像)、lidar\_scan.wasm (光達) 等 60 個可能會用到的 TinyGo 零件,存入本地記憶體後隨船出航。
### **第二階段:邊緣的極限生存 (Tier 3 獨立運作)**
無人機 07 號來到海上 50 公里處,完全失去對外網路。突然,海上濃霧降臨。
原本執行中的 Cypher 圖譜卡住了,因為 rgb\_vision.wasm 回報「無法獲取清晰影像」。07 號沒有驚慌,它內建的輕量級 Go \+ Wazero 引擎在 0.1 秒內動態重組了圖譜邏輯:剔除光學零件,瞬間載入並執行 lidar\_scan.wasm,不需人類介入,繼續在濃霧中精準貼行。
### **第三階段:游擊網與地端代工 (Tier 3 ↔️ Tier 2\)**
巡檢中途,07 號發現風機葉片上有極罕見的「蜂巢狀熱應力微裂紋」,但它帶出來的 60 個零件中沒有對應的分析工具。
07 號飛昇至濃霧上方,短暫連上母船的微弱區域網路發起「短點射傳輸 (Burst)」:{"intent": "計算蜂巢狀熱應力微裂紋擴散率"},拿到任務單號後立刻斷網潛回霧中。
海岸線的**地端指揮中心 (Tier 2\)** 收到需求。強大的**工匠 AI** 瞬間啟動,生成了一段 TinyGo 程式碼,並在本地編譯與測試。三分鐘後,07 號再次探頭連網,下載了熱騰騰的 honeycomb\_analyzer.wasm,並將其編織進 Cypher 圖譜中完成測量。
### **第四階段:CEO AI 的全局戰略覆寫 (Tier 2 ➡️ Tier 1\)**
同時,地端指揮中心匯整了無人機傳回的陣風數據,同步給**雲端總部 (Tier 1\)**。雲端的 CEO AI 呼叫 roi\_calculator.wasm 進行試算,發現風暴將造成設備重大損壞(ROI 極低)。
CEO AI 立刻修改總部的 Markdown 戰略文件,新增一條 BDD 規則:「風速大於 22m/s,立刻轉為陣列抗風模式」。新的最高指導 Cypher 範本瞬間下發至地端,再廣播給所有無人機。07 號收到新命令,掛起原任務,與機群組成抗風陣型,安全度過危機。
## **3\. 物理拓撲與技術棧 (The 3-Tier Tech Stack)**
透過 **KBDB Adapter** 抽象層,AI 在任何環境中呼叫的 API 介面皆一致,但底層基礎設施依據物理環境的豐饒度進行適配。
### **Tier 1: 雲端總部 (Cloud \- The Global Brain)**
* **場景:** 跨國集團資料整合、全域戰略備份、對外公開 API、跨國部門協調。
* **AI 角色:** **CEO AI (大型語言模型)**。負責解析 Markdown、跨區資源調度、修改全域演算法參數。
* **技術規格:**
* **調度引擎:** Cloudflare Workers (原生執行 TinyGo WASM)。
* **圖資料庫 (狀態/關聯)** Cloudflare D1 \+ u6u Cypher 轉換層。
* **零件與儲存:** Cloudflare R2 / KV。
* **向量檢索 (意圖/型錄)** Cloudflare Vectorize。
* **架構優勢:** 無限橫向擴展 (Serverless),無須維運硬體,扛載全球級別的 API 併發。
### **Tier 2: 企業地端/基地台 (On-Premise \- The Basecamp & Forge)**
* **場景:** 高機密廠房內網、財務核心系統、無人機/機器人的母艦基地。
* **AI 角色:** **部門主管 AI** (廠區派工);**工匠 AI** (專職接收規格,透過 TDD 閉環動態生成 TinyGo 程式碼)。
* **技術規格 (企業級高可用架構):**
* **負載平衡:** Nginx 或 HAProxy (負責將請求分發給後端叢集)。
* **調度引擎:** **workerd 叢集 (Cloudflare 開源執行環境)**。在本地實體伺服器或 VM 上平行部署多個 workerd 行程,完美相容雲端環境,提供極高的並發處理能力 (V8 JIT 極限算力)。
* **圖資料庫 (狀態/關聯)** **Kùzu** (單機極速圖庫) 或 PostgreSQL \+ AGE (超高併發)。
* **零件與儲存:** 企業本地 NVMe 硬碟叢集 / MinIO (S3 相容)。
* **向量檢索 (意圖/型錄)** pgvector 或 Milvus。
* **架構優勢:** 兼具資料不出網的「絕對資安」與雲端級別的「叢集擴展性」。內建「代工坊 (Forge)」,是推動企業系統自動演化的核心引擎。
### **Tier 3: 邊緣載具 (Extreme Edge \- The Operatives)**
* **場景:** 無網環境的巡檢無人機、工廠無軌導引車 (AGV)、機械手臂。
* **AI 角色:** **導航/執行 AI (極小參數 SLM)**。不具備寫程式能力,只負責解讀現場狀況、執行 Cypher 圖譜,並透過 DTN 呼叫地端請求新零件。
* **技術規格 (極限微縮架構):**
* **調度引擎:** 輕量級 Go 排程引擎 \+ **內嵌 Wazero**。不依賴 V8 或 workerd,確保在極低 RAM 的晶片上流暢運行,實例化延遲僅需數微秒。
* **圖資料庫 (狀態/關聯)** 嵌入式 Kùzu 或 SQLite。
* **零件與儲存:** SD 卡 / eMMC 實體檔案系統。
* **向量檢索 (意圖/型錄)** sqlite-vss (極輕量本地向量)。
* **架構優勢:** 絕對的離線生存能力。只帶必要的 TinyGo WASM 零件出門,無任何編譯環境,體積最小化。
## **4\. 自動演化工作流 (The Auto-Evolution Loop)**
當企業環境發生變化(例如:新增硬體規格、外部 API 變更),u6u 的演化路徑如下:
1. **遭遇未知 (Anomaly Detection)**
無人機 (Tier 3\) 或雲端服務 (Tier 1\) 在執行 Cypher 任務時,發現本地 KBDB 向量庫中缺乏對應的工具零件。
2. **意圖攔截與 ROI 評估 (CEO/Manager AI)**
機甲 (Harness) 攔截缺失意圖,呼叫 roi\_calculator.wasm 等評估零件。若認定具備開發價值,系統會生成一份標準的 Input/Output JSON Schema。
3. **地端代工 (The Forge @ Tier 2)**
規格需求透過網路或 DTN 送達 Tier 2 地端機房的「工匠 AI」。
工匠 AI 生成 TinyGo 程式碼 \-\> 在沙盒中執行 tinygo build \-target=wasi \-\> 通過測試迴圈 \-\> 輸出正式的 .wasm 檔案。
4. **全域派發 (Distribution & Versioning)**
新零件註冊進入企業的零件圖資料庫 (KBDB)。
* **雲端:** 同步至 R2。
* **邊緣:** 載具下次連網時,透過游擊網 (Burst Transmission) 下載更新檔。
5. **動態編織 (Execution)**
各端 AI 獲知新零件上線,瞬間將其編入新的 Cypher 圖譜中執行,完成企業能力的自動擴展。
@@ -0,0 +1,360 @@
# u6u 系統規格書 v1.0
## 給 AI 的架構思考指引
> 本文件用途:讓 AI 理解 u6u 的完整設計意圖、現況、與未來路徑,
> 在實作決策時能自行判斷方向正確性,而不只是執行單一任務。
---
## 一、系統本質(先理解再動手)
u6u 不是 workflow 工具,不是 no-code 平台,不是 iPaaS。
u6u 是一個**「意圖到系統」的生物體積木平台**:
- 人類說出意圖(自然語言)
- AI 從零件宇宙組裝出可運行的系統
- 系統會自動評價、演化、淘汰舊零件
- 累積的零件就是核心資產,越積越有價值
**設計的終極體驗:** 工廠主管拖拉十分鐘,組出具備微服務架構的企業系統,零程式碼,但底層是真正的分散式系統。
---
## 二、四層邏輯架構
```
Polaris(意圖層)
↓ 自然語言 → AI 拆解
Prototype(前端層)
↓ UI 元件 + 觸發事件
Workflow(編排層)
↓ Cypher 語法定義執行順序
Component(零件層)
↓ .wasm 實際執行
```
每一層向下只透過標準介面溝通,層與層之間完全解耦。
---
## 三、物理三層部署
```
Tier 1:雲端總部(Cloudflare Workers
- CEO AI 讀取 Markdown 戰略文件
- 全域零件同步至 R2
- Cloudflare D1 + VectorizeKBDB
Tier 2:企業地端(workerd 叢集)
- 部門主管 AI 派工
- 工匠 AI 生成並測試新零件
- Kùzu 或 PostgreSQL + AGE(圖資料庫)
- pgvector 或 Milvus(向量搜尋)
Tier 3:邊緣載具(無人機、AGV、工廠設備)
- 極小參數 SLM
- Go 排程引擎 + 內嵌 Wazero(無 V8
- SQLite + sqlite-vss
- 離線生存,DTN 短點射傳輸
```
**關鍵約束:** Tier 3 沒有 V8,沒有 Node.js,沒有網路。
所有零件必須在 Wazero 上跑,所有資料傳輸透過 stdin/stdout JSON。
---
## 四、零件規格(Component Contract
這是整個系統最核心的不變量。零件規格定錯,累積的資產會變成技術債。
### 4.1 零件的本質定義
**一個零件只做一件事。**
```
✅ gsheets_create_table
✅ gsheets_delete_table
✅ gsheets_get_entries
❌ gsheets_manager(做太多事,禁止)
```
### 4.2 零件合約格式(component.contract.yaml
每個零件必須附帶此合約,這是 AI 讀取零件的唯一介面描述:
```yaml
id: "gsheets_get_entries" # 功能合約名稱(永久不變)
version: "v2" # 實作版本
wasi_target: "preview1" # 明確標記 WASI 版本,未來升級用
stability: "floating" # floating | stable | pinned
runtime_compat:
- "cf-workers"
- "workerd"
- "wazero"
constraints:
max_size_kb: 2048 # 超過視為打包了 runtime
max_cold_start_ms: 50
no_network_syscall: true # 禁止零件自己發 HTTP
no_filesystem_syscall: true # 只能 stdin/stdout
io_model: "stdin_stdout_json" # 唯一合法的 I/O 模型
input_schema:
type: object
required: ["spreadsheet_id", "sheet_name"]
properties:
spreadsheet_id: { type: string }
sheet_name: { type: string }
limit: { type: integer, default: 100 }
output_schema:
type: object
properties:
rows: { type: array }
total: { type: integer }
error: { type: string }
gherkin_tests:
- scenario: "正常取得資料"
given: '{"spreadsheet_id":"abc","sheet_name":"Sheet1"}'
then_contains: '{"total":1}'
- scenario: "不存在的表格回傳錯誤"
given: '{"spreadsheet_id":"abc","sheet_name":"不存在"}'
then_contains: '{"error":'
tags: ["google", "sheets", "data", "read"]
description: "從 Google Sheets 取得指定工作表的所有資料列"
```
### 4.3 語言無限制原則
**零件開發語言完全不限制**,只要輸出符合以上合約的 .wasm 即可。
可接受語言(非排他):TinyGo、Rust、AssemblyScript、C/C++
注意事項(不是禁止,是要求自行驗證):
- TypeScript via Extism:會打包 QuickJS,體積通常超過 2MB 限制
- 標準 Go(非 TinyGo):runtime 過肥,通常超過體積限制
- 任何語言:不可在 .wasm 內部呼叫網路或檔案系統 syscall
**驗收標準只有一個:通過沙盒測試。** 語言是零件作者自己的事。
### 4.4 零件的前後端分類
| 類型 | 執行位置 | I/O | 範例 |
|------|----------|-----|------|
| 後端邏輯零件 | Workers/workerd/Wazero | JSON stdin/stdout | validate_json, http_request |
| 前端 UI 零件 | 瀏覽器 | HTML attributes / DOM events | u6u-btn, u6u-chart |
| **混合零件** | **禁止** | — | **強制拆成兩個** |
---
## 五、零件版本控制策略
### 5.1 命名規則
```
gsheets_get_entries ← 功能合約名稱(搜尋用,永遠存在)
gsheets_get_entries_v1 ← 第一個實作(慢但能用)
gsheets_get_entries_v2 ← 更快的實作(由另一個 AI/用戶提交)
```
### 5.2 穩定性標籤
Workflow 引用零件時可指定穩定性需求:
```
gsheets_get_entries → 預設 floating,AI 自動選最優版本
gsheets_get_entries@stable → 有更好版本時提示,人工確認才換
gsheets_get_entries@pinned:v1 → 版本凍結,宇宙怎麼演化都不影響
```
| 標籤 | 適用情境 | 更新行為 |
|------|----------|----------|
| `floating` | 一般企業應用 | AI 自動換成最優版本 |
| `stable` | 重要業務流程 | 有更好版本時提示,人工確認 |
| `pinned` | 工廠控制器、嵌入式設備 | 永遠不動,即使進入墓地也保留 .wasm |
### 5.3 淘汰機制
- AI 搜尋零件時,KBDB 依「成功率 × 速度 × 被調用次數」排序
- 連續 30 天無使用且評價下降 → Deprecated
- Deprecated 後繼續 90 天無復活 → 進墓地(從搜尋清單移除)
- **墓地的 .wasm 永遠保留**pinned 的 Workflow 永遠能拉到
---
## 六、零件製造指引書(給用戶 AI 的規範)
u6u 不限制誰來造零件,任何 AI(用戶自己的 Claude、GPT、本地模型)都可以。
但必須遵守此指引書,否則沙盒測試不過,無法上架。
### Step 1:理解介面合約
造零件前,先定義合約 YAML。
**零件只在乎輸入 JSON 和輸出 JSON,完全不管前端長什麼樣子。**
```
人類:我要一個可以查 Google Sheets 的零件
AI 的第一步:定義 input_schema 和 output_schema,不是寫程式
```
### Step 2:選擇開發語言
選擇你最熟悉的、能產出 WASI preview1 相容 .wasm 的語言。
建議:
- 小型邏輯零件(轉換、計算)→ TinyGo 或 AssemblyScript(體積小)
- 效能敏感零件 → Rust(生態最成熟)
- 任何語言都可以,只要通過合約限制
### Step 3:實作規則
```
✅ 只用 stdin 讀取輸入 JSON
✅ 只用 stdout 輸出結果 JSON
✅ 錯誤也用 stdout 輸出:{"error": "說明"},不要 panic/crash
✅ 無狀態:每次呼叫都是獨立的,不依賴上一次執行的結果
✅ 需要打外部 API?透過 host function 注入,不在 .wasm 裡自己發 HTTP
❌ 禁止網路 syscall
❌ 禁止檔案系統 syscall
❌ 禁止打包 runtimeQuickJS、Node.js 等)
❌ 禁止超過 2MB
```
### Step 4:本地測試方式
```bash
# 用任何 WASI runtime 本地測試
echo '{"spreadsheet_id":"abc","sheet_name":"Sheet1"}' | \
wasmtime gsheets_get_entries.wasm
# 預期輸出
{"rows":[...],"total":5}
```
### Step 5:提交審核
提交 `.wasm` + `component.contract.yaml`,系統自動執行:
1. 體積檢查(< 2MB
2. 冷啟動時間(< 50ms
3. Syscall 掃描(不能有網路/檔案系統呼叫)
4. Gherkin 測試(合約裡的所有 scenario 必須 100% 通過)
5. 多 runtime 相容測試(cf-workers / workerd / wazero
全部通過 → 上架進入零件宇宙,開始累積評價。
---
## 七、Cypher 編排語言
Workflow 使用擴展三元組語法描述執行邏輯:
```yaml
kind: Workflow
id: wf_query_attendance
triplets:
# 基本流程
- "START >> TRIGGERS >> step_receive"
- "step_receive >> IS_A >> component://webhook_receiver_v1"
# 條件分支
- "step_receive >> ON_SUCCESS >> step_validate"
- "step_receive >> ON_FAIL >> step_notify_error"
# 跨 Workflow 串接
- "step_validate >> CALLS_SUBFLOW >> workflow://save_to_db"
# 前端觸發後端
- "btn_submit >> ON_CLICK >> workflow://wf_query_attendance"
```
**URI 協議規範:**
- `component://` → 引用零件
- `workflow://` → 引用子 Workflow
- `ui://` → 引用前端零件
- `style://` → 引用樣式零件
---
## 八、KBDB 在 u6u 的角色
u6u 的所有狀態都在 KBDB 裡:
| KBDB Block 類型 | 存放內容 |
|-----------------|----------|
| Component Block | 零件合約、.wasm 位置、版本、評價指標 |
| Workflow Block | Cypher 三元組、依賴零件清單 |
| Prototype Block | 前端結構、UI 零件樹 |
| Pitfall Block | 避坑記錄,AI 搜尋時強制讀取 |
| Evaluation Block | 每次 Workflow 執行後的強制評價結果 |
**KBDB 不變量:永遠只有三張表(blocks/templates/slots),不新增表。**
所有以上類型都用 Template + Slot 實現。
---
## 九、自動演化迴圈
```
執行 Workflow
強制 AI 評價(Evaluator Agent
↓ 發現問題
生成修復 Ticket → 通知製作人
↓ AI 嘗試修復
通過 Gherkin 驗收 → 熱更新
↓ 無法修復
標記 [HAS_PITFALL] 到 Cypher 圖
下一個 AI 搜尋時讀到坑,強制繞道
```
---
## 十、現況與未來路徑
### 現在已有
- KBDBblocks/templates/slots + Vectorize
- IS-Squad MCPexecute_cypher 等工具)
- Cloudflare Workers 環境
### 最小可 demo 路徑
1. **Cypher 執行引擎**:三元組 → 實際執行順序(確認 execute_cypher 邊界)
2. **首批核心零件**5 個):
- `webhook_receiver`
- `json_transform`
- `http_request`(透過 host function
- `notify_line`
- `validate_json`
3. **機甲最小版本**:意圖 → 零件搜尋 → 組裝 Workflow(先用硬編碼路由)
4. **前端畫布 MVP**:靜態 HTML 模擬雙面翻轉體驗
### 技術監控項目
- **WASI Component Modelpreview2**:目前用 preview1,未來 3-5 年會有遷移壓力。
合約裡已有 `wasi_target: "preview1"` 標記,升級時知道要改什麼。
- **Kùzu 成熟度**:地端圖資料庫首選,持續觀察 v1.0 穩定性。
---
## 十一、實作決策原則(CC 行動準則)
遇到不確定的實作決策時,依序問自己:
1. **這個決策會影響零件合約嗎?** 如果是,停下來討論,不要自行決定。
2. **這個實作是否限制了未來換 runtime 的自由?** 如果是,重新設計介面。
3. **這個零件做超過一件事嗎?** 如果是,拆成兩個零件。
4. **這個設計在 Tier 3 離線環境能跑嗎?** 如果不能,重新考慮。
5. **有沒有現成零件可以組合?** 先搜尋 KBDB,不要重造輪子。
---
*本文件版本:v1.0*
*綜合自:u6u 系統與零件宇宙全景規劃白皮書、自動演化 ERP 架構藍圖、智慧前端與工匠開發藍圖,加入技術評論與補充建議。*
+116
View File
@@ -0,0 +1,116 @@
# u6u 系統與零件宇宙全景規劃白皮書 (The u6u Ecosystem Blueprint)
## 1. 核心理念與願景
u6u 旨在解決傳統 Workflow 軟體 (如 n8n) 存在的「單線程、沈重、複雜、難以組成系統」的痛點。
透過結合 Cloudflare Workers (輕量邊緣運算) 與 Cypher (圖形資料庫關係),u6u 提供一個由 AI 驅動的「意圖到系統」生成平台。所有的系統功能皆被拆解為可複用、可組合的「零件 (Components)」,並在一個會自然淘汰、自我修復的「零件宇宙 (Component Universe)」中演化。
## 2. 四層架構拆解 (Four-Tier Architecture)
u6u 的工作模式採取由上到下 (Top-Down) 的 Break-down 機制:
1. Polaris (北極星層 / 意圖層):
- 用戶以自然語言描述商業模式與想法(例如:「我要做一個 AI 客服表單系統」)。
- 這是整個系統的起點,AI 會根據 Polaris 將意圖拆解為 Prototype。
2. Prototype (原型 / 前端層):
- 定義前端的版型、頁面描述、UI 元件以及它們的屬性。
- 作為使用者互動的入口,透過觸發事件 (Triggers) 連接到後端 Workflow。
3. Workflow (工作流層):
- 系統的 Orchestrator (編排者),定義業務邏輯的走向。
- 透過 Cypher 語法與三元組,定義每個節點 (Component) 的執行順序與條件分支。
4. Component (零件層 / 節點):
- 最底層的執行單元,主要分為兩類:
- 功能型 (Logic): 迴圈、條件判斷、資料轉換、統計等 (透過 CF Workers 執行 JS 邏輯)。
- 介接型 (API): 呼叫外部服務 (Webhook, HTTP Request)。
## 3. 統一描述語言:擴展三元組與跨層級 YAML
為了解決跨 YAML 檔案串接的問題,u6u 採用易於人類閱讀與 AI 生成的 「A >> 關係 >> B」 三元組語法,結合自定義的 URI 協議 (workflow://, component://, ui://),實現跨層級的連結。
綜合 YAML 範例與三元組串接
```YAML
# 1. Prototype YAML (描述前端)
kind: Prototype
id: ui_dashboard
triplets:
# 結構與版型零件
- "ui_dashboard >> CONTAINS >> layout_admin"
- "layout_admin >> CONTAINS >> btn_submit"
# UI 零件與屬性零件 (CSS/行為)
- "btn_submit >> IS_A >> ui://components/Button"
- "btn_submit >> HAS_STYLE >> style://tokens/GlowEffect"
- "btn_submit >> HAS_BEHAVIOR >> anim://motions/Pulse"
# 跨層級串接:前端觸發 Workflow
- "btn_submit >> ON_CLICK >> workflow://workflows/process_data.yaml"
# 2. Workflow YAML (描述工作流編排)
kind: Workflow
id: wf_process_data
triplets:
# 跨層級串接:Workflow 呼叫 Component
- "START >> TRIGGERS >> step_validate"
- "step_validate >> IS_A >> component://components/validate_json"
# Workflow 節點間的流轉 (轉譯為 Cypher 關係)
- "step_validate >> ON_SUCCESS >> step_call_api"
- "step_validate >> ON_FAIL >> step_notify_error"
# 跨 Workflow 串接
- "step_call_api >> CALLS_SUBFLOW >> workflow://workflows/save_to_db.yaml"
```
## 4. 零件宇宙 (Component Universe) 的審核與淘汰機制
在 u6u 中,所有的 UI、Style、Logic、API 都是「零件」。當 AI 發現缺乏所需零件時,會自動創造它。為了確保生態系的健康,必須建立嚴格的審核標準與自然淘汰機制。
### 4.1 零件的創建與審核標準 (Pass/Fail Criteria)
當 AI 或開發者提交一個新零件時,系統會啟動自動化沙盒測試。必須完全通過以下標準,零件才能進入「宇宙」供他人使用:
1. 功能型零件 (Logic Components):
- Gherkin BDD 驗收: 必須附帶 Feature/Scenario 測試規格,且執行結果 100% 通過 (例如:Given input JSON, When split, Then returns Array)。
- 效能門檻: 邊緣運算 (CF Workers) 執行時間需低於設定閾值 (例如 < 50ms),無記憶體洩漏。
2. 介接型零件 (API Components):
- 連線驗證: 端點 (Endpoint) 必須能 ping 通,或回傳正確的 2xx HTTP Status (提供 Mock Payload 測試)。
- Credential 安全: 不可將 Token 或 Secret 寫死在代碼中,必須嚴格宣告所需的 Environment Variables 規格。
3. 前端與屬性零件 (UI & Style Components):
- 渲染驗證: CSS / 組件代碼不能導致瀏覽器 Crash。
- 相容性檢查: 不可包含嚴格衝突的樣式 (例如寫死 !important 破壞全域版型)。
## 4.2 零件宇宙的自然淘汰 (Natural Selection)
零件一旦上架,將面臨殘酷的達爾文機制:
- AI 偏好權重: AI (透過 MCP 搜尋時) 會優先選擇「成功率高、執行速度快、被調用次數多」的零件。
- 降級與墓地: 連續 30 天無人/無 AI 使用,或錯誤率飆升的零件,會被降級 (Deprecated)。最終轉入「零件墓地」,從首選搜尋清單中剔除。
## 5. 系統自癒與 AI 避坑機制 (Auto-Healing & Pitfall Avoidance)
這是 u6u 維持系統穩定運作的最核心機制。工作流不只要能跑,跑完後還必須經歷 「強制 AI 評價 (Mandatory AI Evaluation)」。
### 5.1 運行後的強制評價迴圈
每當一個 Workflow 在 CF Workers 上執行完畢 (或發生異常中斷),系統攔截日誌並強制啟動 AI 評價代理 (Evaluator Agent)。
- 評估維度:
- 狀態: 成功 / 失敗 (Crash) / 逾時 (Timeout)。
- 效能: 耗時是否合理 (例如 API 突然變得很慢)。
- 警告訊息: 資源消耗過大、API 回傳即將停用的 Warning。
### 5.2 自癒與避坑流程 (The Feedback Loop)
當 Evaluator Agent 發現問題時,會觸發以下流程:
- 回報與通知 (Notify): 系統自動生成修復 Ticket,並通知當初建立該零件/工作流的製作人 (或系統管理員)。
- AI 嘗試修復 (Auto-Fix): 系統派遣「修復型 AI」嘗試讀取錯誤日誌並修復代碼 (例如:API 規格變更導致 JSON 解析錯誤,AI 自動修改解析邏輯)。
- 驗收與部署: 修復後的代碼若通過 Gherkin 驗收,則無縫熱更新。
- 避坑標記 (Pitfall Marking): - 如果 AI 無法修復 (例如:外部第三方 API 永久倒閉,或邏輯存在根本性死結)。
- 系統會在 Cypher 圖形資料庫中,將該零件或該特定的三元組關係標記為 [HAS_PITFALL]。
- 結果: 下一個生成系統的 AI 在透過 MCP 搜尋時,會讀取到這個坑的紀錄,並強制繞道,改用其他方案或生成新的零件,實現「前人踩坑,後 AI 避坑」的群體智慧。
## 6. 結論
u6u 不是一個單純的開發工具,它是一個生物體積木系統。
透過「三元組」統一語言打破系統壁壘,透過「零件審核」保證基因優良,再透過「強制評價與避坑機制」實現演化。當這套系統運轉起來,AI 就能在其中無止盡地為人類組裝出越來越強大、越來越穩定的商業應用。
+19
View File
@@ -0,0 +1,19 @@
# u6u Design
u6u 是一個 AI Friendly 的 n8n。
- 用 workers 天生比 n8n 速度快
- 用 Cypher binding,不需 deploy 就可以隨時修改執行,不然原生 workers 的 binding 要 deploy
- 未來要有一個 GUI 可以解析 YAML 產生畫面,反之人拉的圖會產生 YAML
- 內建核心元件,http request, webhook, cron, if, switch, set, credential 等功能
- 用戶自建功能多數是 http request 只是去 call 不同的 API,可以隨時建立,它的「配方」recipe 可以分享
- 每個 API Call 獨立但搜尋會整合,例如有人實作 call google sheets create table API,它不用做完整的,因為另一人要 delete table 時發現沒有,AI 直接做一個,下次搜尋 google sheets 時,就提供了 create table, delete sheets 兩個端點,也就是哪些是大家需要的功能自然產生
- marketplace 機制,但是是給 AI 的,強制 AI 使用後要回覆使用的評價,如果一個零件被幾次評為不佳,其他的 AI 就可以避開這個零件
- 自動審核:如果是 call API,只要成功 Call 通就是通過,如果是功能性的,只要通過他設置的 Gherkin 就是通過,省去人工審核的麻煩
## 觀念想法
- u6u 通過前端網頁開發功能,每個元件是一個零件
- 視覺優先的開發:要解釋什麼是 webhook 很難,但一般用戶做一個前端的按鈕、輸入框... 後面就會綁定某個 webhook,點擊這個前端界面就看到後端邏輯的工作流,這樣就不用解釋太多。
- 系統功能:我是一個用戶,我建立不同的功能,例如我建立 CRM,又建立 ERP,這些系統有很多流程是共用的,但當我建立多個工作流時,zoom out 就會看到我的公司內不同流程間的關係,因為 cypher 放大就是 graph,但每個功能要可以摺疊成一個點,又可以 zoom in 展開來調整某一段工作流,再 zoom in 調整一個零件
- 考慮讓他自己 OWN,就是企業版可以讓資料是獨立的
+24
View File
@@ -0,0 +1,24 @@
# Wishlist
這個檔案記錄討論到但還不直接實作的想法,避免干擾,後續再來排入。
## Code 零件
目前的想法是,用戶發現有一個工作無法用現成零件產出,就建立一個新的零件投稿,測試通過 gherkin 就 publish。
這表示流程比較慢,跟其他的零件不符,例如:
- 打 API 時用內建 http request 零件 + recipe,一個抵多個。
- 內建 credential 零件 + recipe,一個零件可以連到各個服務的 auth。
- 按照此邏輯,code 也可以內建 code 節點 + recipe,一個零件可以做多種任務。
例如我要一個把 Logseq outliners md 讀入,轉成 json 輸出的功能,實際上 Logseq 用戶不多,我不一定需要 publish 它。
或是因為某些機密的理由,用戶不想 publish 他的處理邏輯。
此時有個簡單的 code 節點可以寫簡單的 JS 當 recipe,而 code 寫在資料庫中與 code 節點分離,如果他要 publish 就直接 publish 這個 recipe 即可。
### 架構決策備忘(實作時請讀)
code 零件的 JS recipe **不在 WASM 內部執行**,而是由 code 零件(TinyGo WASM)將 recipe 字串透過 host function 傳遞給外部執行環境。arcrun 的 host 是 Cloudflare Workers isolateV8),本身就是沙箱,不需要在 WASM 內嵌入 QuickJS 或 javy,也不需要引入 Rust。這與 http_request 零件 + recipe 的模式完全一致:零件本身是穩定的能力抽象(WASM),recipe 是存在 RECIPES KV 的可替換邏輯字串。
JS recipe 可用的 API 範圍為 Cloudflare Workers 標準 Web APIES2023、fetch、crypto、TextEncoder 等),但 code 零件語意上應為純計算節點(無 network),實作時可考慮用 Proxy 遮蔽 fetch 等 I/O API,初期自用階段可暫時跳過此限制。第三方 lib 的問題留待實作時再決定白名單策略(預注入 lodash-es、dayjs、yaml 等到 global scope 即可覆蓋九成用例)。