Files
Arcrun/system-dev/docs/3-specs/arcrun/sdk-and-website/config-layering.md
T
uncle6me-web 5d00e71275 chore: D22 落地——docs/SDD/wiki/CLAUDE.md 進 repo(Gitea private 預設全 push)
頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定,
Gitea private=除機敏值/build 產物/.github 外全 push。
解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。
機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:13:33 +08:00

6.4 KiB
Raw Blame History

Design 補充:設定分層(env > 專案層 > 全域)+ init 非互動

2026-06-04 建立。sdk-and-website/design.md 的單檔補充(規則 02 §4.3 允許)。 來源:docs/壓測報告.md §1.2(方案 C+ §2.2init 非互動)= 阻斷項 #7、#8。 richblack 2026-06-04 授權:「#7#8 是同一問題,明顯發現的問題當然要解決,完成後就要推。」


1. 問題(壓測實測)

acr v1.1.0 把設定寫死在全域唯一一份 ~/.arcrun/config.yamlconfig.ts CONFIG_DIR = join(homedir(), '.arcrun')),且 init 只能 readline 互動。後果:

  • #8 多帳號:同一台電腦只能一個 arcrun 身份 → 接案者 / 多公司 / 個人+公司混用做不到。 壓測者克難法是覆寫 HOME(需讀原始碼才找得到、不直覺)。
  • #7 非互動init 只能 TTY 問答 → AI / CI 無法用 flag / env 完成。

兩者本質同一:設定來源不該只有「全域單檔 + 強制 TTY」一條路

2. 設計(richblack 2026-06-04 拍板:三層全上 + init flag/env

2.1 設定分層優先序(仿 git config / Claude Code MCP

1. 環境變數          ARCRUN_* / CLOUDFLARE_*        ← 最高,解 #7(AI/CI 非互動)
2. 專案層設定        <就近往上找>/.arcrun.yaml      ← 解 #8(接案多帳號),有 fallback
3. 全域設定          ~/.arcrun/config.yaml          ← 平常自動用(自己的帳號)
  • 就近往上找:從 process.cwd() 往上層目錄逐層找 .arcrun.yaml,找到第一個即用(停在檔案系統根)。 → 自己的專案不放檔 → 自動 fallback 全域;客戶資料夾放檔 → 只在該樹生效,離開自動切回。零心智負擔、不會忘記切換。
  • 覆蓋是「欄位級 merge」:高層只覆蓋它有提供的欄位,未提供的欄位 fallback 到低層。 (例:專案層只放 cypher_executor_url,其餘仍用全域。)

2.2 env 變數對應(最高層,欄位級覆蓋)

env 覆蓋 config 欄位 用途
ARCRUN_MODE mode local/standard/self-hosted
ARCRUN_API_KEY api_key standard
ARCRUN_ENCRYPTION_KEY encryption_key standard/self-hosted
ARCRUN_CYPHER_EXECUTOR_URL cypher_executor_url self-hosted 指向自己的 cypher
CLOUDFLARE_ACCOUNT_ID cloudflare_account_id self-hosted(沿用 wrangler 慣用名)
CLOUDFLARE_API_TOKEN cf_api_token self-hosted(沿用 wrangler 慣用名)

CF 兩個用 CLOUDFLARE_* 而非 ARCRUN_*:與 wrangler / deploy.ts 既有慣例一致(deploy.ts 跑 wrangler 時就是設這兩個 env),CI 設一次兩邊通用。

2.3 init 非互動(flag > env > 互動問答)

acr init --self-hosted 取得 account-id / api-token 的順序:

  1. flag--account-id <id> / --api-token <token>
  2. envCLOUDFLARE_ACCOUNT_ID / CLOUDFLARE_API_TOKEN
  3. 互動:前兩者缺才 readline 問(保留現有 UX

mindset §7 判準:帳號設定不是「暴露資料 / 建零件」類風險確認,是單純設定值,flag/env 合法、不違反「非 TTY 拒絕代人類確認」。 風險確認(exposure_consent 等)仍維持需人類明示,不在本次放寬範圍。

3. 實作(只動 cli/

檔案 動作
cli/src/lib/config.ts loadConfig() 改三層解析:全域 → merge 專案層 findProjectConfig() → merge envapplyEnvOverrides())。新增 acr config --where 用的 resolveConfigSources()
cli/src/commands/init.ts cmdInit / initSelfHostedaccountId/apiToken options,缺才走 env 再 fallback 互動
cli/src/index.ts init 加 --account-id <id> / --api-token <token> option

loadConfig() 是唯一設定入口(12 個指令全走它)→ 改它一處,全指令自動受益分層。

3.1 acr config --where(壓測 §1.2 建議 #3,避免用錯帳號)

新增輕量 acr config 指令,印出「現在這個資料夾正用哪個帳號 / 設定來自哪一層」:

mode: self-hosted(來源:專案層 /path/客戶A/.arcrun.yaml
cloudflare_account_id: abc...(來源:env CLOUDFLARE_ACCOUNT_ID
cypher_executor_url: https://...(來源:全域 ~/.arcrun/config.yaml

安全價值:部署前一眼確認「沒用錯帳號」。本次一併做(成本低、直接回應壓測痛點)。

3.2 安全:專案層 .arcrun.yaml 含憑證 → 必須 gitignore

專案層 .arcrun.yaml 可能含 cf_api_tokencreateCredentialsYamlIfMissing() 既有 gitignore 邏輯 擴充為一併忽略 .arcrun.yaml(壓測 §1.2 安全附帶發現:憑證進版控 = 帳號外洩)。

4. 驗收標準(客觀證據,mindset §7)

  1. 專案資料夾放 .arcrun.yamlacr config --where 顯示來源為該專案層;離開該樹 → 顯示全域。
  2. CLOUDFLARE_ACCOUNT_ID=x CLOUDFLARE_API_TOKEN=y acr init --self-hosted → 不問互動直接跑(#7)。
  3. acr init --self-hosted --account-id x --api-token y → 同上(flag 優先於 env)。
  4. 三者皆缺 → fallback 互動問答(既有 UX 不破壞)。
  5. env > 專案層 > 全域 的欄位級覆蓋:單元測試覆蓋三層 merge。
  6. npx tsc --noEmit 全綠。

4.1 實作完成記錄(2026-06-04

全部 task 完成,客觀證據如下(mindset §7):

  • config.ts 三層解析:loadConfig() = 全域 → 專案層 → env 欄位級 merge;新增 findProjectConfig()(就近往上找)/ resolveConfigSources() / activeProjectConfigPath()
  • init.tsinitSelfHosted 收 flag/env,缺才互動;gitignore 一併排除 .arcrun.yaml
  • index.tsinit 加 --account-id/--api-token;新增 acr config [--where] 指令
  • 新增 commands/config.tstoken 遮罩、來源層標示)
  • 驗收證據
    • 端對端測試(真實 fs 臨時目錄樹)8/8 通過:深層就近找專案層、未提供欄位 fallback、env 最高層覆蓋、來源層標示、離開專案樹回全域
    • acr init --help 顯示 flagacr config --where 正確標來源 + token 遮罩 secret_t…
    • npx tsc --noEmit 全綠

5. 為何不違反鐵律

  • 只動 cli/,不碰零件 / cypher-executor 執行路徑 / Service Binding。
  • flag/env 是帳號設定值,非風險確認(mindset §7 風險確認仍須人類明示)。
  • 不新增頂層 SDD 目錄(本檔是 sdk-and-website 子系統內單檔補充,rule 02 §4.3)。