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:
2026-05-29 16:18:18 +08:00
parent 8c1dedaa2f
commit 17a076d35c
88 changed files with 661 additions and 15449 deletions
@@ -59,6 +59,9 @@ type AuthInjectSpec struct {
Header map[string]string `json:"header,omitempty"`
Query map[string]string `json:"query,omitempty"`
Body map[string]string `json:"body,omitempty"`
// Path:要注入 endpoint URL path 的 secret(如 telegram /bot{token}/)。
// key = 模板變數名(recipe endpoint 用 {{auth.K}} 引用),value = {{secret.X}} 模板。
Path map[string]string `json:"path,omitempty"`
}
type AuthRecipe struct {
@@ -159,6 +162,7 @@ func main() {
authHeaders := interpolateRecord(recipe.Inject.Header, secrets, runtime)
authQuery := interpolateRecord(recipe.Inject.Query, secrets, runtime)
authBody := interpolateRecord(recipe.Inject.Body, secrets, runtime)
authPath := interpolateRecord(recipe.Inject.Path, secrets, runtime)
// 3.5 Basic Auth 自動編碼:若 header 值為 "Basic <x>:<y>" (冒號代表未編碼的 user:pass),
// 將冒號分隔部分做 base64。這涵蓋 twilio / jira / mailgun 等 Basic Auth recipe。
@@ -185,6 +189,7 @@ func main() {
"auth_headers": authHeaders,
"auth_query": authQuery,
"auth_body": authBody,
"auth_path": authPath,
"runtime": runtime,
})
os.Stdout.Write(out)