Files
Arcrun/.agents/specs/component-gatekeeping/tasks.md
Leo fb2d0b0c2d feat(self-hosted): acr init --self-hosted installer + recipe push 把關 + commit 部署 wasm
讓任何 CC 用自己的 CF 帳號一鍵 self-host arcrun(戰法轉 self-hosted 開源)。

Task 1 — acr init --self-hosted installer(用戶只給 CF Account ID + token,其餘自動):
- cli/src/lib/cf-api.ts: CfAccountClient(驗 token / 建 KV 冪等 / 建 R2 / 查 workers.dev subdomain)
- cli/src/lib/deploy.ts: 從 GitHub codeload tarball 拉部署物 → 注入用戶 KV id → wrangler deploy
  (tier1 component-builds 先、tier2 cypher-executor/registry 後;部分失敗誠實回報不假綠)
- cli/src/lib/api-recipe-seeds.ts: 10 個現役 API recipe 種子(KBDB 採 Supabase 模式)
- cli/src/commands/init.ts: initSelfHosted() 改寫成 installer 流程
- cli/src/commands/update.ts: acr update(拉新 ref 重部署)
- cypher-executor/scripts/seed-api-recipes.ts: prod 補灌腳本

Task 2 — recipe 入庫把關(封鎖自製零件後,CC 唯一能擴充的是 recipe):
- cli/src/commands/recipe.ts: 新增 probeRecipeEndpoint 打通檢查(提醒級不硬擋,
  含模板誠實說明待 run 才知,401/403 標多半缺 credential 非 bug)
- 資料外流提醒沿用既有 obtainExposureConsent(非 TTY 拒絕)

部署物產製:commit 預編譯 wasm 進 repo(推翻 rule 05「wasm 不 commit」):
- .gitignore: 放行 .component-builds/**/component.wasm(registry 中間產物仍排除)
- 只 commit 19 個正當零件 wasm;claude_api / km_writer / kbdb_upsert_block 排除
  (非薄殼、是把工作流硬塞進零件,違反 DECISIONS §1,待降級)
- rule 05 同步記錄此慣例變更 + 膨脹 trade-off

SDD: sdk-and-website/self-hosted-init.md(installer 定案)、
     component-gatekeeping/recipe-push-gatekeeping.md(recipe 把關)
README 重寫成單一 self-hosted 路徑。CLI typecheck exit 0。

未完(待 richblack):push 此 commit 到 GitHub 後 codeload 才拿得到 wasm;
用第二 CF 帳號端對端驗收 acr init --self-hosted。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:44:41 +08:00

7.4 KiB
Raw Permalink Blame History

Tasks: Component Gatekeeping

對應 design.md。每完成一個 task 立刻標 [x],不批次。 Design 已 richblack 確認(2026-05-29,含 Q1-Q3 決議)。


⚠️ 收尾狀態(2026-05-30,方向修正後)

投稿改走 GitHub PR(廢 registry self-service,見 design 頂部「方向修正」)。本 SDD 收尾於:

  • 已完成且 commitG1detectFakeComponent)、G3wasmImports)、G5/G6unimplemented_steps)、 G0 registry 人類閘門(保留不刪)。測試 15 綠。
  • 改去向G4 Gherkin / 覆蓋檢查 → 未來接 CI PR checkCI 能跑 wasm)。G1/G3 邏輯可複用。
  • 不做CI PR checkrichblack:人工 review 就夠,primitive 極少)、R5 本機 hook PR/merge + G1 + 沙箱已防「未經同意變公共零件」,hook 過度工程)、registry self-service、 acr parts publish 加閘門、平台 sandbox 重跑。
  • 黃金向量:人工核對(另起 session 從語義寫),不急、不機器自動化。
  • 轉出範圍:真正的裸奔風險在「資料外流」(recipe/webhook 把資料送出去),不分公私庫 → 另開新 SDD「資料外流警示」(API 層警示 + AI 動手前 hook)。用戶 API 保護(入站認證)
    • recipe/part/function 架構釐清 → 記 BACKLOG 待決策。

G1 假零件偵測(R2,Q2=兩者硬擋)

  • 1.1 registry/src/actions/detectFakeComponent.ts(a) 外部 URL/domain 偵測(掃 contract 文字 + wasm binary 文字)硬擋;(b) http_request 子集偵測硬擋
  • 1.2 排除 auth_* primitive 與 http_request 自己
  • 1.3 接進 sandboxAcceptance 步驟鏈(fake_component_scan 為第一步)
  • 1.4 退稿訊息指回正路(「這該是 recipe/工作流」)

G3 純 WASI 把關(R3

  • 3.1 wasmImports.ts 解析 wasm import section,取出所有 import module name(已對真實零件驗證)
  • 3.2 白名單:只准 wasi_snapshot_preview1 + u6u;其他 module → 退稿
  • 3.3 接進 scanSyscalls(白名單為主,黑名單為次)

G4 Gherkin 真實作(R1)— venue 修訂:CLI 本地跑,非 registrydesign §4 修訂)

CF Worker 不能 runtime 編譯 wasm + §8 不依賴 CI → Gherkin 在投稿指令本地(Node)跑。 在第一段(tinygo build→wasm 之後)測,跟 worker 無關。registry 只存 evidence 不重跑。

  • 4.1 runGherkin.tscreateWasiShim 跑 wasm,邏輯正確)—— 但 venue 要從 registry 改 CLI
  • 4.2 回退 sandboxAcceptanceregistry 不跑 Gherkin(移除 await runGherkin),改回靜態步驟
  • 4.3 Gherkin 邏輯搬到 CLI 投稿指令(Node 環境 instantiate wasm
  • 4.4 投稿 payload 帶 gherkin_evidencescenario/given/actual_stdout/passed),registry 存 metadata 可審
  • 4.5 誠實標明第一期 evidence 可造假(mindset + 文件);平台重跑列未來
  • 4.6 投稿指令(暫名 acr component submit+ 公私庫分流(-p 公共)— 新 CLI 工程

G5/G6 誠實標未實作(R3 禁假綠)

  • 5.1 SandboxResult 增 unimplemented_steps: string[]
  • 5.2 cold_start / runtime_compat 列入 unimplemented_stepssubmit 回應明示

G0 人類閘門(R4,核心)

  • 0.1 submit 請求增 human_confirmationSubmitOptions in submitComponent.ts+ route 解析(multipart/JSON 皆支援)
  • 0.2 submit 邏輯:非 skip_acceptance 的新投稿,無 human_confirmation/空 reason → gateError(指回正路)
  • 0.3 human_confirmation + gherkin_evidence 寫進 KV metadata(軌跡可審)
  • 0.4 CLI acr parts publish(既有指令):互動式問人類(工作流為何做不到 + 確認),非 TTY 拒絕
  • 0.5 MCP / Python lib / JS lib 補 human_confirmation 欄位支援(薄)
  • 0.6 誠實限制寫進 mindset Skill(步驟 7+ SDK 文件

命名修正(2026-05-29):投稿走既有 acr parts publishcli/src/commands/parts.ts), 非另建 acr component create(符合「修改現有不重建」)。G0-CLI(0.4)與 G4-CLI 合併在此指令做。

R5 白名單 + 本機 hook

  • 5.3 registry/MVP_COMPONENTS.txt(現役 22 個 canonical_id
  • 5.4 submit 過閘門成功 → 自動 append canonical_id 進白名單(Q3
  • 5.5 pre-write-guard.sh:寫 registry/components/{白名單外}/ → exit 2
  • 5.6 pre-bash-guard.shmkdir registry/components/{白名單外} → exit 2

W1 CLI workflow validate 擋假零件式 component 名2026-06-01 作廢,方向修正)

作廢原因(richblack 2026-06-01:「擋假零件」這件事不再存在——因為自製/修改零件的路 已被封鎖(CC 根本造不出零件),workflow 引用 recipe(如 component: kbdb_get)是合法且 未來唯一的擴充方式,不該被當「假零件」擋。把關點從「workflow validate」移到 recipe 入庫 push)那一刻。已動的 yaml-parser.ts LEGAL_PRIMITIVES/findSuspectComponents 已回退。 取而代之 → 見 W2。

W2 封鎖自製零件 + recipe 入庫把關(2026-06-01 新方向)

richblack 2026-06-01 定調:

  • 零件由維護者管理,CC 不能自製/修改零件(hook + CLI 拒絕)→ 不再有「假零件」。
  • CC 唯一能擴充的是 recipe。recipe 一律用「推(push)」,自有庫與公共庫同一套指令
  • 把關依庫別分強度:
    • 自有庫(self-hosted:只能提醒(無法在別人機器強制)。兩個提醒: (1) 資料外流提醒——某動作會讓外界看到你的東西(如 workflow 產對外 webhook),同意後是他的責任; (2) 打通檢查——查他要打的 API 是否打得通(2xx)。
    • 公共庫:由維護者機制檢核「實際打通、真收到成功回傳」(PR/CI relayDECISIONS §3c,第一期後)。 屬 change,需先寫 design 給 richblack review 才動 code。本節先記框架。
  • W2.1 封鎖自製零件 — 釐清完成(richblack 2026-06-02:靠「零件投稿走 GitHub PR + 人 merge」 天然閘門(DECISIONS §8)。BACKLOG 步驟5「不做 hook」真意 = 零件少、不為零件 PR 蓋自動化把關 (量少人工檢查;爆量才回頭想),不是不阻止自製。無矛盾,不需新做 hook。
  • W2.2 acr recipe push 資料外流提醒 — 既有實作已涵蓋recipe.ts:70-79 obtainExposureConsent exposure-warning.ts:互動打資源名確認、非 TTY 拒絕、首次問記住)。data-exfil-warning SDD 已做,確認涵蓋 recipe push 路徑。
  • W2.3 acr recipe push 打通檢查 — 新增 probeRecipeEndpointrecipe.ts):push 成功後實打 endpoint 回報 2xx/⚠。提醒級不硬擋;endpoint 含 {{模板}} → 誠實說明待 run 才知;401/403 → 標「多半缺 credential,非 recipe bug」(不假綠,mindset §7
  • W2.4 公共庫 push--public= 維護者 relay 檢核(DECISIONS §3c)— 第一期後,本期只做自有庫提醒級

驗收(design §8

  • V1 投寫死 endpoint 假零件 → G1 退稿(終端輸出)
  • V2 投 .ts 進 registry/components → hook exit 2
  • V3 本機造白名單外零件目錄 → hook exit 2
  • V4 無 human_confirmation 的 submit → 403
  • V5 帶 human_confirmation + 過 Gherkin 真零件 → 通過 + reason 留 metadata + 白名單 append
  • V6 故意改壞 then_contains → Gherkin 退稿
  • V7 回應含 unimplemented_stepscold_start/runtime_compat 不假綠)