From 1eefce952b863dc2ecb923152566e44bd82263e6 Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 6 Jul 2026 12:40:25 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20=E9=9B=B6=E4=BB=B6/binding=20PR=20?= =?UTF-8?q?=E5=AF=A9=E6=A0=B8=E8=A6=8F=E7=AF=84=E2=80=94=E2=80=94=E7=B5=90?= =?UTF-8?q?=E6=A7=8B=E6=80=A7=E9=98=B2=E6=9E=B6=E6=A7=8B=E9=8C=AF=E8=AA=A4?= =?UTF-8?q?(=E4=B8=8D=E9=9D=A0=E8=A8=98=E8=A6=8F=E5=89=87):A=E5=8F=8D?= =?UTF-8?q?=E9=81=8E=E5=BA=A6=E5=B7=A5=E7=A8=8B(D27)/B=20binding=E5=B1=A4?= =?UTF-8?q?=E7=B4=9A(D28)/C=20contract/D=E9=A9=97=E8=AD=89=E8=AA=A0?= =?UTF-8?q?=E5=AF=A6/E=E9=83=A8=E7=BD=B2=E8=B3=87=E6=96=99=E9=90=B5?= =?UTF-8?q?=E5=BE=8B/F=E8=B5=B0PR+=E6=A9=9F=E6=A2=B0=E5=8C=96CI=E8=A3=9C?= =?UTF-8?q?=E5=BC=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/component-pr-review-standard.md | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/component-pr-review-standard.md diff --git a/docs/component-pr-review-standard.md b/docs/component-pr-review-standard.md new file mode 100644 index 0000000..1a3ded8 --- /dev/null +++ b/docs/component-pr-review-standard.md @@ -0,0 +1,49 @@ +# 零件 / binding PR 審核規範 + +> **為什麼有這份**:靠「AI 記住規則」防架構錯誤不 scale(規定說幾次都沒用)。零件與 service binding 本來就**要走 PR**——所以把錯誤擋在 **PR 審核這道結構性閘**,讓錯誤路徑「根本碰不到」,不靠自覺。 +> **適用**:任何「新增/改一個 component」或「改 worker binding(`[[services]]` 等)」或「新增 workflow/部署到 cypher」的 PR。 +> **審核者**:先由 reviewer(AI subagent 戴 reviewer 人格)逐條過;未過不得 merge/deploy。逐步補機械化 CI(見文末)。 + +--- + +## Checklist(逐條,任一「否」→ 打回) + +### A. 這東西該不該存在(反過度工程,D27) +- [ ] **新增命名零件?** 只准當它是「**常用、多人/多 workflow 會用的可複用原語**」(如 http_request/cron)。 + - 一次性 / 專案專用邏輯 → **打回**,改用通用 **`code` 零件**內聯。 + - 判準:**三個月後會有第二個 workflow 用它嗎?** 不會=不是零件。 + - 反例:`km_wiki_card_parse`(card→envelope 一次性解析)被否。 + +### B. binding 層級對不對(D28,最常踩) +- [ ] **用了 Service Bindings(`[[services]]` / `env.SVC.fetch()`)?** + - 只准**唯一例外**:把**幾個 wasm 綁成「一個複合零件」**(零件等級的組合)。 + - **跨-worker 編排**(workflow 串多個 worker/零件,如 ingest 串 code+kbdb+graph)→ **打回**,走 **cypher binding=跑成 cypher 上的 workflow**。 + - 判準:這是「**零件內部組 wasm**」還是「**工作流編排多 worker**」?後者一律 cypher binding。 + - 反例:ingest drainer 自建 standalone worker + service binding 串 code/kbdb/graph=錯位,被否。 + +### C. 零件 contract 合規 +- [ ] stdin JSON → stdout JSON;`no_network`/`no_filesystem`(除非明確申報且審核放行);資源限制(timeout/mem/輸出/code 上限);錯誤**結構化回傳**(不讓 Worker 掛)。 + +### D. 驗證誠實(測試≠執行路徑) +- [ ] 驗證打的是**部署後的真端點**,不是只 `wrangler dev`/miniflare 本地(本地不強制 worker-to-worker 等生產限制,會假綠)。**禁假綠。** + - 反例:drainer 本地 miniflare 綠、production 撞 1042。 + +### E. 部署 / 資料鐵律 +- [ ] 部署 **wrangler 直推**、**不用 `acr update`**(部署源綁 GitHub codeload,會假綠蓋改動)。 +- [ ] account 正確(self-hosted=leo21c;別讓 repo `.env` 的官方帳號 id 污染)。 +- [ ] 碰 KBDB=**零建表、全走 base API、零 SQL**(插件層)。 + +### F. 走 PR(結構性,不繞道) +- [ ] component/binding/workflow 變更**走 PR + 本規範審核 + merge 才 deploy**,不 ad-hoc 從 branch 直接 wrangler deploy 上 production。 + +--- + +## 機械化補強(讓它「根本碰不到」,待實作) +逐步把可機械判的移到 CI,PR 命中即 fail,不等人審: +- lint `wrangler.toml` 出現 `[[services]]` → 標記需 B 條人工放行理由(wasm-composite 例外)。 +- 偵測新增 `registry/components//` 目錄 → 要求 A 條「可複用原語」論證。 +- 偵測 KBDB migration/`CREATE TABLE` → 直接 fail(鐵律)。 +- 偵測 `acr update` 於部署腳本 → 警告。 + +## 對應決策 +D27(一次性用 code 零件不鑄 domain 零件)、D28(跨-worker 走 cypher binding 不走 service binding)、KBDB 鐵律(D6)、測試≠執行路徑(mistakes)。