feat(arcrun): Phase 2 降級假零件成 recipe + credential 鏈路修復
Phase 1(credential 注入鏈路):
- 修 auth_static_key ENCRYPTION_KEY 漂移根因(見 docs/incidents)
- component-loader: readBodyOnce() 修 "Body has already been used"
Phase 2(降級假零件成 recipe,registry/components 33→22):
- 引擎: RecipeDefinition 加 auth_service(多 recipe 共用一把 auth)
auth-dispatcher 先查 recipe.auth_service 再 fallback componentId
- 引擎: auth_static_key inject.path + makeRecipeRunner {{auth.K}}
(endpoint 可插 secret,解 telegram 類 URL-path token)
- 引擎: makeRecipeRunner auto-body 剔除 _ 前綴內部欄位
- 降級並刪除: kbdb_{get,create_block,patch_block,delete,ingest}
gmail/telegram/line_notify/google_sheets(改建為 recipe)
- 刪除: ai_transform_{compile,run}(Arcrun 是 AI 呼叫的工具,
工作流不該內嵌 AI 節點回頭呼叫 AI)
- deferred(源碼暫留): claude_api/km_writer(交 Mira 收成工作流)、
kbdb_upsert_block(交 KBDB 出 upsert endpoint)
文件: DECISIONS.md(工作流是 default/建零件人類閘門/AI→工具)、
BACKLOG.md、auth-recipe.md §七、docs/incidents 加密 key 漂移
驗收: KBDB get/create/ingest/delete 2xx;telegram auth 注入綠;
gmail/sheets/line recipe 正確但缺 credential 未驗收;
kbdb patch 403 為 KBDB 端 bug(已交 kbdb/docs)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,12 @@ interface AuthRecipeDefinition {
|
||||
header?: Record<string, string>; // "Authorization": "Bearer {{secret.token}}"
|
||||
query?: Record<string, string>;
|
||||
body?: Record<string, string>;
|
||||
// path:注入 endpoint URL path 的 secret(2026-05-29 加)。
|
||||
// 解 telegram 類「token 在 URL path」(/bot{token}/)—— header/query/body 都不適用。
|
||||
// key = 模板變數名,API recipe 的 endpoint 用 {{auth.K}} 引用。
|
||||
// 例:auth_recipe:telegram inject.path = { bot_token: "{{secret.telegram_bot_token}}" }
|
||||
// recipe:telegram_send endpoint = "https://api.telegram.org/bot{{auth.bot_token}}/sendMessage"
|
||||
path?: Record<string, string>;
|
||||
};
|
||||
|
||||
created_at: number;
|
||||
@@ -131,8 +137,22 @@ injectCredentials
|
||||
| `_auth_headers` | `Record<string, string>` — 要合併進 fetch headers |
|
||||
| `_auth_query` | `Record<string, string>` — 要附加到 URL query string |
|
||||
| `_auth_body` | `Record<string, string>` — 要合併進 request body |
|
||||
| `_auth_path` | `Record<string, string>` — endpoint URL path 用(2026-05-29 加)。`makeRecipeRunner` 的 endpoint interpolate 用 `{{auth.K}}` 從這裡取值 |
|
||||
|
||||
`makeAuthRecipeRunner` 在發出 fetch 前讀取這三個欄位,之後從 body 中剔除(不迴傳給下游)。
|
||||
`makeAuthRecipeRunner` / `makeRecipeRunner` 在發出 fetch 前讀取這些 `_auth_*` 欄位,
|
||||
之後從 auto-body 中剔除所有 `_` 前綴欄位(不洩漏給下游)。
|
||||
|
||||
## 七、API recipe 的 auth_service(多 recipe 共用一把 auth,2026-05-29 加)
|
||||
|
||||
`RecipeDefinition` 加 `auth_service?: string` 欄位:API recipe **自報它屬於哪個服務**,
|
||||
auth-dispatcher 用它查 `auth_recipe:{auth_service}`,而非假設 componentId == service name。
|
||||
|
||||
- 讓多個 recipe 共用同一把 auth:`recipe:kbdb_get` / `kbdb_create_block` 都設 `auth_service: "kbdb"`
|
||||
→ 共用唯一的 `auth_recipe:kbdb`,加新 action 不必複製 auth recipe。
|
||||
- auth-dispatcher 解析順序:先查 `recipe:{componentId}` 拿 `auth_service`,有就用它;
|
||||
沒有則 fallback 把 componentId 當 service name(向後相容舊行為)。
|
||||
- 這是「服務身分標籤」非「許可清單」:auth_recipe 只定義「怎麼認證」,不含「誰准用」。
|
||||
授權由發 API key 的服務裁決,arcrun 不做內部授權判斷(見 DECISIONS.md「arcrun 不做授權判斷」)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user