feat(registry): Phase 3 零件投稿靜態把關 + component-gatekeeping SDD

新 SDD .agents/specs/component-gatekeeping/(richblack 確認,含 venue 修訂 + 信任模型)。

registry 端靜態把關(CF Worker 可跑,不執行 wasm):
- G1 detectFakeComponent: 外部 URL/domain + http_request 子集偵測,硬擋退稿指回 recipe
- G3 wasmImports: 解析 wasm import section,只准 wasi_snapshot_preview1 + u6u 白名單
- G5/G6: unimplemented_steps 明列 gherkin/cold_start/runtime_compat,不假綠(§3c/§7)
- gherkin_evidence 一致性驗證(投稿者本地跑,registry 不重跑——CF 禁 runtime 編譯 wasm)

把關範圍:公共庫 + self-hosted 私人庫同一套(design §0.0)。
信任模型(design §4.5):Gherkin 全綠≠安全;純 WASI 沙箱框死能力才是發佈底氣;
第一期 evidence 可造假(誠實標明),平台重跑列未來。

hook: pre-write-guard 白名單加 component-gatekeeping / component-registry-canon SDD 目錄。

測試: sandboxAcceptance.test.ts 4 綠(含 G1 假零件被擋)。

待續(同 SDD): G4 CLI 投稿指令本地跑 Gherkin、G0 人類閘門、R5 白名單+本機 hook。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-29 17:53:03 +08:00
parent fdb62e8b27
commit 202a5ab8d6
9 changed files with 609 additions and 66 deletions
@@ -0,0 +1,54 @@
# Tasks: Component Gatekeeping
> 對應 design.md。每完成一個 task 立刻標 [x],不批次。
> Design 已 richblack 確認(2026-05-29,含 Q1-Q3 決議)。
---
## G1 假零件偵測(R2,Q2=兩者硬擋)
- [x] 1.1 `registry/src/actions/detectFakeComponent.ts`(a) 外部 URL/domain 偵測(掃 contract 文字 + wasm binary 文字)硬擋;(b) http_request 子集偵測硬擋
- [x] 1.2 排除 `auth_*` primitive 與 `http_request` 自己
- [x] 1.3 接進 sandboxAcceptance 步驟鏈(fake_component_scan 為第一步)
- [x] 1.4 退稿訊息指回正路(「這該是 recipe/工作流」)
## G3 純 WASI 把關(R3
- [x] 3.1 `wasmImports.ts` 解析 wasm import section,取出所有 import module name(已對真實零件驗證)
- [x] 3.2 白名單:只准 `wasi_snapshot_preview1` + `u6u`;其他 module → 退稿
- [x] 3.3 接進 scanSyscalls(白名單為主,黑名單為次)
## G4 Gherkin 真實作(R1)— venue 修訂:CLI 本地跑,非 registrydesign §4 修訂)
> CF Worker 不能 runtime 編譯 wasm + §8 不依賴 CI → Gherkin 在投稿指令本地(Node)跑。
> 在第一段(tinygo build→wasm 之後)測,跟 worker 無關。registry 只存 evidence 不重跑。
- [x] 4.1 `runGherkin.ts`createWasiShim 跑 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 禁假綠)
- [x] 5.1 SandboxResult 增 `unimplemented_steps: string[]`
- [x] 5.2 cold_start / runtime_compat 列入 unimplemented_stepssubmit 回應明示
## G0 人類閘門(R4,核心)
- [ ] 0.1 submit 請求增 `human_confirmation { confirmed_by_human, reason_why_not_workflow, confirmed_at }`
- [ ] 0.2 submit 邏輯:非 skip_acceptance 的新投稿,無 human_confirmation/空 reason → 403 指回正路
- [ ] 0.3 reason_why_not_workflow 寫進 KV metadata(軌跡可審)
- [ ] 0.4 CLI `acr component create`:互動式問人類(工作流為何做不到 + 確認),非 TTY 拒絕
- [ ] 0.5 MCP / Python lib / JS lib 補 human_confirmation 欄位支援(薄)
- [ ] 0.6 誠實限制寫進 mindset Skill(步驟 7+ SDK 文件
## 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
## 驗收(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 不假綠)