Files
Leo 20c7610371 refactor: 移除已廢棄的自管加密金鑰機制(credential 全面託管 CF Workers Secrets)
leo 2026-07-20 明令:「已經改用 cf 自己的 secrets,不要再說它了」
「我希望以後再也看不到這個詞再出現」

背景:credential 早已遷移至 CF Workers per-script Secrets + D1 目錄,
舊的自管金鑰(client 端 AES-GCM + KV 密文 + crypto_decrypt)是遷移期遺留。
本次連根移除,含一併作廢的死 SaaS 碼。

移除:
- 舊 KV 密文解密路徑(credential-injector.ts 整檔、dual-read fallback)
  前置驗證:leo21c / youlin 兩帳號 CREDENTIALS_KV 實測 *:cred:* 皆 0 筆
- migrate-to-workers-secrets 搬家端點(回填已完成,無可回填)
- /register 路由與 generateApiKey(HMAC 產 ak_ key 是 SaaS 遺物;
  self-hosted 走 namespace 明碼 D21,已無人使用)
- platform_crypto component(三帳號實測 404 已退役,無 workflow 引用)

保留(附理由):
- crypto_decrypt 保留為永遠回失敗的 stub——現役三個 auth .wasm 仍宣告該
  import,缺項會讓 WASM instantiate 直接失敗。待零件重編後可真正刪除。

順帶修復(原不在範圍,但會實際壞事):
- /auth/callback 有 `if (!key) redirect(server_error)` 閘,未設該 secret 的
  實例會登入直接失敗 → 已移除
- OAuth 兩處把 provider token 寫進舊加密 KV(租戶鍵與實際 api_key 在 rotate
  後必然分歧,已失效)→ 改導向 Workers Secrets,包 try/catch 不影響登入
- acr init Standard 模式呼叫已刪除的 /register → 改引導 OAuth 取 key
- .claude/rules 與 system-dev/docs 是同一規範的兩份鏡像,先前只改 rules
  導致鏡像仍在教舊做法 → 已同步(此類雙檔同步應納入檢查)

新用戶安裝從此零 secret 前置。
測試 187/188(唯一 fail 為 pre-existing,stash 驗證與本次無關);
cypher-executor 與 cli typecheck 全綠。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 01:32:48 +08:00

142 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 部署慣例(CI/CD)
> **核心原則:新增 Worker = 新目錄 + `wrangler.toml`,不用改 workflow。**
`.github/workflows/deploy.yml` 是**通用掃描式** workflow,不該為每個 Worker 手寫 job。
---
## Workflow 如何找到要部署的 Worker?
```
find . -name 'wrangler.toml' -not -path '*/node_modules/*' -not -name 'wrangler.test.toml'
```
每一個命中的目錄 = 一個部署單位。無論是:
- `cypher-executor/` (orchestration Worker)
- `registry/` (合約管理 Worker)
- `.component-builds/{name}/` (零件 Worker,25+ 個)
- 未來新增的任何 Worker
**無需改 workflow,只要符合掃描規則就會自動部署**
---
## 觸發邏輯
| 觸發 | 部署範圍 |
|------|---------|
| `push` 到 main | diff 涉及的 Worker 目錄才部署 |
| `push` 到 main + 改 `registry/components/{name}/` | 連動 rebuild `.component-builds/{name}/component.wasm` 再 deploy |
| `workflow_dispatch` + `force_all=true` | 全部 Worker |
| `workflow_dispatch` + `only=a,b,c` | 只部署指定清單 |
| `push` 但 base sha 不可及(首次) | 全部 Worker |
---
## 新增 Worker 的步驟
### 如果是新 WASM 零件 Worker
1.`registry/components/{new_name}/``main.go` + `component.contract.yaml`
2.`.component-builds/{new_name}/` 建 Worker 模板:
- `wrangler.toml`(name/routes/bindings)
- `package.json`(hono + workers-types + wrangler 即可,參考 `auth_static_key/package.json`)
- `tsconfig.json`(可直接複製)
- `src/index.ts`(WASI shim,方案 A:import `../../cypher-executor/src/lib/wasi-shim`)
3. 本地跑 `pnpm install``pnpm-lock.yaml`
4. 本地跑 `tinygo build -target=wasi -o {new_name}.wasm main.go` 先驗證 build 通過
5. Commit push → CI 自動 rebuild WASM + deploy
### 如果是新 orchestration/service Worker
1. 在 repo 根建新目錄(類似 `cypher-executor/`)
2. `wrangler.toml` + `package.json` + `pnpm-lock.yaml` + `src/index.ts` + `tsconfig.json`
3. Push → CI 自動部署
---
## Runtime Secret 管理
**CI 只提供 Cloudflare 驗證,不碰 runtime secret**
- GH Actions secrets:`CLOUDFLARE_API_TOKEN``CLOUDFLARE_ACCOUNT_ID`(一次性設好)
- Runtime secret(例:`CF_SECRETS_API_TOKEN``OPENAI_KEY``GOOGLE_API_KEY`):
- **由 richblack 一次性手動** `wrangler secret put <KEY>` 設進各 Worker
- 不進 CI,不進 `wrangler.toml` `[vars]`
- 需要的 Worker:`arcrun-cypher-executor`(`CF_SECRETS_API_TOKEN`——寫 credential 進
Workers Secrets 用;`CF_ACCOUNT_ID` 非機密由 `acr init` 自動注入)
> `auth_static_key` / `auth_service_account` 不需要任何 secret。
---
## Lockfile 規範
- **統一使用 pnpm**。新增 Worker 只放 `pnpm-lock.yaml`,不要 `package-lock.json`
- 若新建 Worker 時用 `npm install` 產出 `package-lock.json`,**刪掉它**,改跑 `pnpm install`
- `cypher-executor/``registry/``package-lock.json` 已於 2026-04-20 刪除
**現存例外**(歷史遺產,混合期不強制遷移):
- `.component-builds/{if_control, switch, ... 16 個舊邏輯零件}/` 仍是 `package-lock.json`,workflow 有 fallback 分支(`pnpm install --no-frozen-lockfile`)可跑
- `builtins/``landing/` 同上
**新增 Worker 一律 pnpm,不要製造新的混合情況**
---
## WASM 來源
> **⚠️ 慣例變更(richblack 2026-06-02self-hosted 開源策略)**
> 原慣例「`.component-builds/{name}/component.wasm` 不 commit 進 repo」**已推翻**。
> 現在 **commit `.component-builds/*/component.wasm` 進 repo**,因為 self-host 用戶 / `acr init --self-hosted`
> 從 GitHubcodeload tarball)直接拿這份 wasm 部署到自己的 CF——repo 必須自帶可部署的 wasm。
> 決策依據:`docs/3-specs/arcrun/sdk-and-website/self-hosted-init.md §6`。
### 現行規則(2026-06-02 起)
- **`.component-builds/*/component.wasm` → commit 進 repo**(部署來源)。`.gitignore` 用否定規則放行:
```
*.wasm # 預設排除
!.component-builds/**/component.wasm # 例外放行部署物
```
- **`registry/components/*.wasm` → 仍不 commit**(build 中間產物,部署不直接用,`.gitignore` 仍排除)。
- 本地開發 build`cd registry/components/{name} && tinygo build -target=wasi -o {name}.wasm main.go && cp {name}.wasm ../../../.component-builds/{name}/component.wasm`**然後 commit `.component-builds/{name}/component.wasm`**。
- CIdeploy.yml):仍在 deploy 前自動 rebuild + copy(部署 prod 用最新 source;與 repo 內 commit 的 wasm 不衝突——前者給 CI deploy prod,後者給 self-host 用戶當部署來源)。
### 誠實 trade-offmindset §7
commit wasm 進 repo → 每次 rebuild 在 git 歷史累積二進位,**repo 長期會膨脹**。
可接受(self-host 體驗優先),未來若膨脹過劇再考慮 git-lfs / 按需安裝(self-hosted-init.md §6.6)。
---
## 並行度
`max-parallel: 5` — 避免觸發 Cloudflare Workers API rate limit。
Worker 數量 > 5 時,deploy 會分批跑。25 個 Worker 大約 5 輪 × ~30 秒 = 2-3 分鐘可完成全部。
---
## 禁止事項
1. **禁止**為新 Worker 手動加 deploy job 到 `deploy.yml`。通用掃描會自動處理,手加就是重複工作。
2. **禁止**把 runtime secret(API key / encryption key / credential)放進 GH Actions secrets 或 `wrangler.toml` `[vars]`,只能用 `wrangler secret put`。
3. **禁止**在 CI 裡跑不必要的測試阻擋 deploy。測試在 PR / 本地跑,`main` 推上去就 deploy(trunk-based)。若要測試關,開新 workflow 檔,不要污染 deploy workflow。
4. **禁止**跳過 TinyGo rebuild 直接 deploy 舊 `.wasm`。CI 的 rebuild 步驟是確保部署的是最新 source。
---
## 驗證指令
本地模擬 CI 的掃描結果:
```bash
find . -name 'wrangler.toml' -not -path '*/node_modules/*' -not -name 'wrangler.test.toml' \
| xargs -n1 dirname | sort -u
```
應列出 ~25 個目錄。任何「我新增了 Worker 但沒被 deploy」的問題,先跑這條確認目錄被掃到。