Architecture

How Crucible runs a model.

Two separate runtimes. The native C++17 engine (20 ONNX operators, Eigen) runs CNNs such as ResNet18 and MobileNetV2 behind the FastAPI server and is checked against ONNX Runtime. A much smaller Rust interpreter (5 operators) is compiled to WebAssembly so the fraud model can be scored in the browser. They share the approach, not the code.

01 · Request pipeline
React pageroutes/fraud.tsxcrucible-wasm.tsTS wrapperWASM bindingswasm-bindgenRust runtimeparse + 5 kernelsScoref32 outSAMPLE PATH · fraud inferenceno network hop between any of these boxes

Tensors are flat, row-major NCHW.

A shape like [N, C, H, W] is one contiguous float32buffer. The stride of each axis is the product of the dimensions after it — stride[i] = shape[i+1] * stride[i+1] — so an index like (n, c, h, w) maps to one offset. MatMul and Gemm view the buffer in place through Eigen::Map; Conv first unfolds receptive fields with im2col (1×1 stride-1 and depthwise convs skip that step).

shape   = [1, 3, 224, 224]
stride  = [3*224*224, 224*224, 224, 1]
offset  = n*stride[0] + c*stride[1] + h*stride[2] + w*stride[3]

Execution order is Kahn's algorithm.

An ONNX graph is a DAG of operators. Crucible builds an in-degree[node] map, seeds a ready-set with every zero-in-degree node, and pops nodes off in topological order — decrementing successors, appending them when their in-degree hits zero. Deterministic, cycle-detecting, and small.

ready = { n : in_degree[n] == 0 }
while ready not empty:
  n = ready.pop()
  execute(n)
  for m in successors(n):
    if --in_degree[m] == 0: ready.add(m)
02 · Data path
with a hosted model API
tabTLS to your server
your serverTLS to model host
model hostraw features in memory
model hostscore back to server
your serverscore back to tab
Raw transaction features cross three trust boundaries. The model host becomes an in-scope processor for PCI-DSS / GDPR purposes.
with crucible
tab (once)fetch .onnx (static CDN)
tabwasm execute
tabscore (in same tab)
Raw features never leave the tab. Only the final score is available to the app. The model host is a static file server — not a processor of feature data.
03 · Two runtimes
native core
C++17 · Eigen GEMM · im2col conv · 20 ONNX ops · Python, C ABI and HTTP interfaces
wasm runtime
Separate pure-Rust interpreter · MatMul, Add, Relu, Sigmoid, Softmax · one float32 input · wasm-bindgen glue
in common
Hand-written protobuf decoding · Kahn topological ordering · explicit rejection of unsupported ops
verification
Native: 70 parity cases against ONNX Runtime (incl. ResNet18, MobileNetV2). WASM: Rust unit tests; no automated native↔WASM parity check yet
wasm binary
under 100 KB (crucible_wasm_bg.wasm, wasm-pack release build)
Inspect the graph See measured benchmarks