arcrun — AI workflow execution engine (clean history)

Self-hosted 開源:WASM 零件 + recipe + cypher-executor,跑在你自己的 Cloudflare。

此為重建的乾淨歷史起點(移除曾誤 commit 的 GCP SA 金鑰,舊歷史保留在
richblack/arcrun 與本地 backup 分支)。含:
- acr init --self-hosted installer(建 KV/R2 + codeload 拉預編譯 wasm + wrangler deploy + seed recipe)
- recipe push 把關(資料外流提醒 + 打通檢查)
- 19 個正當零件預編譯 wasm(claude_api/km_writer/kbdb_upsert_block 排除:違反 DECISIONS §1)
- CLI / cypher-executor / registry / 完整 SDD

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
uncle6me-web
2026-06-03 15:52:38 +08:00
commit 922a57fe34
485 changed files with 89356 additions and 0 deletions
@@ -0,0 +1,56 @@
canonical_id: "platform_crypto"
display_name: "Platform Crypto Primitive"
category: "platform"
version: "v1"
wasi_target: "preview1"
stability: "stable"
runtime_compat:
- "cf-workers"
- "workerd"
- "wazero"
constraints:
max_size_kb: 2048
max_cold_start_ms: 50
no_network_syscall: true
no_filesystem_syscall: true
io_model: "stdin_stdout_json"
input_schema:
type: object
required: [action]
properties:
action:
type: string
enum: [generate_api_key, encrypt, random_token]
email:
type: string
description: generate_api_key 用
plaintext:
type: string
description: encrypt 用
bytes:
type: integer
description: random_token 用,預設 32
output_schema:
type: object
properties:
success:
type: boolean
api_key:
type: string
description: generate_api_key 結果,ak_ 前綴
encrypted:
type: string
description: encrypt 結果,base64
iv:
type: string
description: encrypt 結果,base64
token:
type: string
description: random_token 結果,hex
tags: [platform, crypto, internal]
description: |
平台內部 crypto primitive。
- generate_api_key: HMAC-SHA256(email, ENCRYPTION_KEY) → ak_xxx
- encrypt: AES-GCM(plaintext, ENCRYPTION_KEY) → {encrypted, iv}base64
- random_token: crypto random bytes → hex string
ENCRYPTION_KEY 由 host 持有,永不進入 WASM。
+206
View File
@@ -0,0 +1,206 @@
// platform_crypto — Arcrun 平台內部 crypto primitive
//
// Actions:
// generate_api_key — HMAC-SHA256(email, ENCRYPTION_KEY) → ak_{hex[:32]}
// encrypt — AES-GCM(plaintext, ENCRYPTION_KEY) → {encrypted, iv}base64
// random_token — crypto random bytes → hex string
//
// ENCRYPTION_KEY 由 host 持有,永不進入 WASM。
//
// Host imports:
// u6u.crypto_hmac_sha256 — HMAC-SHA256(data, key=ENCRYPTION_KEY) → raw bytes
// u6u.crypto_aes_encrypt — AES-GCM(plaintext, key=ENCRYPTION_KEY) → encrypted_b64 + iv_b64
// u6u.crypto_random_bytes — crypto-random bytes → hex string
//
//go:build tinygo
package main
import (
"encoding/json"
"io"
"os"
"strings"
"unsafe"
)
// ── host function 宣告 ───────────────────────────────────────────────────────
// crypto_hmac_sha256(dataPtr, dataLen, outPtr, outLenPtr) → 0 成功
// key = host 的 ENCRYPTION_KEYoutput = raw byteshex encode 由 WASM 做)
//
//go:wasmimport u6u crypto_hmac_sha256
func hostCryptoHmacSha256(
dataPtr uintptr, dataLen uint32,
outPtr uintptr, outLenPtr uintptr,
) uint32
// crypto_aes_encrypt(plaintextPtr, plaintextLen, outEncPtr, outEncLenPtr, outIvPtr, outIvLenPtr) → 0 成功
// output: encryptedbase64)放 outEncivbase64)放 outIv
//
//go:wasmimport u6u crypto_aes_encrypt
func hostCryptoAesEncrypt(
plaintextPtr uintptr, plaintextLen uint32,
outEncPtr uintptr, outEncLenPtr uintptr,
outIvPtr uintptr, outIvLenPtr uintptr,
) uint32
// crypto_random_bytes(numBytes, outPtr, outLenPtr) → 0 成功
// output: hex string
//
//go:wasmimport u6u crypto_random_bytes
func hostCryptoRandomBytes(
numBytes uint32,
outPtr uintptr, outLenPtr uintptr,
) uint32
// ── 型別 ─────────────────────────────────────────────────────────────────────
type Input struct {
Action string `json:"action"`
Email string `json:"email,omitempty"`
Plaintext string `json:"plaintext,omitempty"`
Bytes int `json:"bytes,omitempty"`
}
// ── main ─────────────────────────────────────────────────────────────────────
func main() {
raw, err := io.ReadAll(os.Stdin)
if err != nil {
writeError("failed to read stdin: " + err.Error())
return
}
var input Input
if err := json.Unmarshal(raw, &input); err != nil {
writeError("invalid input JSON: " + err.Error())
return
}
switch input.Action {
case "generate_api_key":
if input.Email == "" {
writeError("email 必填")
return
}
sig, ok := hmacSha256([]byte(input.Email))
if !ok {
writeError("HMAC-SHA256 失敗")
return
}
apiKey := "ak_" + hex(sig)[:32]
out, _ := json.Marshal(map[string]interface{}{
"success": true,
"api_key": apiKey,
})
os.Stdout.Write(out)
case "encrypt":
if input.Plaintext == "" {
writeError("plaintext 必填")
return
}
encB64, ivB64, ok := aesEncrypt([]byte(input.Plaintext))
if !ok {
writeError("AES-GCM 加密失敗")
return
}
out, _ := json.Marshal(map[string]interface{}{
"success": true,
"encrypted": encB64,
"iv": ivB64,
})
os.Stdout.Write(out)
case "random_token":
n := input.Bytes
if n <= 0 {
n = 32
}
token, ok := randomBytes(uint32(n))
if !ok {
writeError("random bytes 失敗")
return
}
out, _ := json.Marshal(map[string]interface{}{
"success": true,
"token": token,
})
os.Stdout.Write(out)
default:
writeError("不支援的 action: " + input.Action)
}
}
// ── helpers ───────────────────────────────────────────────────────────────────
func writeError(msg string) {
out, _ := json.Marshal(map[string]interface{}{
"success": false,
"error": msg,
})
os.Stdout.Write(out)
}
func hmacSha256(data []byte) ([]byte, bool) {
if len(data) == 0 {
return nil, false
}
outBuf := make([]byte, 64) // SHA-256 = 32 bytes raw
var outLen uint32
status := hostCryptoHmacSha256(
uintptr(unsafe.Pointer(&data[0])), uint32(len(data)),
uintptr(unsafe.Pointer(&outBuf[0])), uintptr(unsafe.Pointer(&outLen)),
)
if status != 0 {
return nil, false
}
return outBuf[:outLen], true
}
func aesEncrypt(plaintext []byte) (string, string, bool) {
if len(plaintext) == 0 {
return "", "", false
}
encBuf := make([]byte, 65536)
ivBuf := make([]byte, 64)
var encLen, ivLen uint32
status := hostCryptoAesEncrypt(
uintptr(unsafe.Pointer(&plaintext[0])), uint32(len(plaintext)),
uintptr(unsafe.Pointer(&encBuf[0])), uintptr(unsafe.Pointer(&encLen)),
uintptr(unsafe.Pointer(&ivBuf[0])), uintptr(unsafe.Pointer(&ivLen)),
)
if status != 0 {
return "", "", false
}
return string(encBuf[:encLen]), string(ivBuf[:ivLen]), true
}
func randomBytes(n uint32) (string, bool) {
outBuf := make([]byte, n*2+4) // hex = 2 chars per byte
var outLen uint32
status := hostCryptoRandomBytes(
n,
uintptr(unsafe.Pointer(&outBuf[0])), uintptr(unsafe.Pointer(&outLen)),
)
if status != 0 {
return "", false
}
return string(outBuf[:outLen]), true
}
// hex encodes raw bytes to lowercase hex string
func hex(b []byte) string {
const hexChars = "0123456789abcdef"
out := make([]byte, len(b)*2)
for i, v := range b {
out[i*2] = hexChars[v>>4]
out[i*2+1] = hexChars[v&0xf]
}
return string(out)
}
// strings import 只為了 strings.Builderinterpolate 用,這裡不需要但 import 要保留給未來)
var _ = strings.Builder{}