feat(component): 新增 hash 零件——出貨線版本號機制不必再用 code 腹語術(Arcrun#91) #116
Reference in New Issue
Block a user
Delete Branch "feat/91-hash-component"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
關聯:
Leo/Arcrun#91要什麼 / 為什麼
出貨線的版本號由內容指紋算出(內容一變版本必變,這是「改了東西版本沒動」在
結構上不可能發生的機制來源),
build站核對官方成品指紋也要它。此前registry 只有
code節點提到 hash,沒有專門零件——雜湊是純計算,本該是一顆零件,不是一段腳本(D70「腹語術」)。
這個 PR 做了什麼
registry/components/hash/— TinyGo 實作,支援sha256/sha1/md5,輸出
hex(預設)或base64。純計算、no_network_syscall/no_filesystem_syscall,1.3MB(合約上限 2MB 內)。.component-builds/hash/— 部署包,component.wasm已 commit(比照 rule 05「WASM 來源」:self-host 用戶部署來源)。
cypher-executor/src/lib/component-loader.ts—WASM_HTTP_RUNNER_IDS白名單加入
'hash'。沒有這一行,component: hash在任何實例(含官方)上都會落到 step 8「找不到零件」——這是實測撞出來的(見下方查證段),
與
code零件當年 #29 的缺口同形狀(同一份白名單、同一種漏法)。對應單元測試
cypher-executor/tests/component-loader-hash.test.ts(mirror 自
component-loader-code.test.ts的既有 pattern)。pending-human-gate/README.md— hash 部分已落地,移除hash-component/子目錄(內容原樣搬進上述正式位置,無副本);#89的兩份 recipe 維持原狀,不在本次範圍內。驗證(附實測輸出,不是「應該會過」)
A. WASM 本身:wasmtime 直跑,逐位元比對系統原生指令
sha1/md5/base64/預設 algorithm/不支援 algorithm 五種情境同樣逐位元核對
(對照
component.contract.yaml的 6 條 gherkin_tests,全過)。B. 部署到 youlin 測試場,真端點驗證
六種 gherkin 情境在真端點上重跑一次,結果與本地 wasmtime 一致。
C. 在一支真的工作流裡跑過(不是只能編譯)
先用
component: hash(canonical_id 直呼)觸發,如預期撞上白名單缺口:這就是本 PR 加白名單那行的直接動機(不是憑空加的)。加上白名單後補了對應
單元測試(見下段 D),並用「外部 URL」形式(component-loader 本就支援的
合法路徑,錯誤訊息自己提示的第二選項)實際觸發過一次工作流
hash-e2e-test-91,證明零件本身接得上真實執行鏈路:測試用的 workflow 已從 youlin 清掉(
DELETE /webhooks/named/hash-e2e-test-91回
{"deleted":true}),部署的arcrun-hashworker 保留在 youlin 供覆驗。D. component-loader 白名單修法:本地單元測試(vitest + cloudflare:test)
也跑過
cypher-executor全套(457 tests,含新增的 2 支 hash 測試):5 個檔 14 個測試失敗(
auth-dispatcher.test.ts5 個、console-library-map-page.test.ts6 個、executor.test.ts1 個、portal-admin.test.ts1 個、portal-data.test.ts1 個),在另開一個乾淨的
gitea/mainworktree(不含本 PR 任何改動)上重跑這 5 個測試檔,同樣是這 14 個測試失敗、錯誤內容逐字相同——
確認是 pre-existing、與本 PR 無關(跟 KBDB fetch mock/console 路由
404 有關,不碰
component-loader.ts)。誠實缺口(◐,不是 ✅ 全通)
測試場驗證。
component-loader.ts的白名單修法要真正生效於任一實例,需要該實例重新部署 cypher-executor(這是 PR merge 後的正常部署動作,
不是本次特意繞開)。
.component-builds/hash/是本 repo第一個用 pnpm-lock.yaml 的component-build(其餘沿用
package-lock.json是歷史遺產,rule 05白紙黑字要求新增一律 pnpm)——第一個範例,供之後對照。
#89(兩份 recipe:gitea_put_file/cf_worker_deploy_simple)不在本次範圍,仍卡在互動暴露同意閘(那道閘是真的,AI 打不進去),
維持
pending-human-gate/recipes/原狀待人落地。查證「零件投稿要走互動人閘」這件事
前一版
pending-human-gate/README.md寫著要靠人在終端機互動跑scripts/component-arm.sh,且registry/components/下有機械閘.claude/hooks/component-guard.sh擋 AI 直接寫入。查證後兩者都不存在(
find . -iname "*component-arm*" -o -iname "*component-guard*"零命中)。pre-write-guard.sh對registry/components/唯二的限制是規則 1.1(禁 TS)與規則 1.2(auth_* 命名放錯目錄)——都不適用本次改動(TinyGo
.go、非 auth 零件)。沒有指出任何一個「只有人做得到」的具體物件,故判定
不是人閘,直接走完零件投稿流程(
docs/component-pr-review-standard.md)到 PR 這一步。若審核者認為仍需要人工互動關卡,請直接說明卡在哪一步、
需要什麼確切動作。
🤖 Generated with Claude Code · Co-Authored-By: Claude Opus 5 noreply@anthropic.com
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.