TL;DR: bun-sticky now embeds the Mk4 WASM engine โ€” the same Rust compiler that powers faf-cli, mcpaas.live, and builder.faf.one. One kernel interface. Rust today, Zig Cascade tomorrow. All engines produce identical scores. 284 microseconds per score.

The Problem

Four scoring engines. Same algorithm. Four implementations. Score divergence. A CLI tool scores 100% locally but 43% through WASM because the engines disagree on what counts.

The root cause: type-aware scoring lived in TypeScript. The WASM engine scored flat โ€” all 21 slots, always. A CLI project could never hit 100% through WASM because frontend slots dragged it down.

The Fix

Data-Driven Slotignore

The .faf file carries the truth. If your project doesn't use frontend slots, they're marked slotignored in the file itself โ€” not inferred at score time by TypeScript.

# CLI project โ€” non-applicable slots marked in the file
stack:
  frontend: slotignored
  css_framework: slotignored
  ui_library: slotignored
  state_management: slotignored
  runtime: Bun
  build: bun build

Every engine reads the same file. Every engine skips the same slots. Every engine gets the same score.

The WASM doesn't care about types.

It counts. Populated, empty, slotignored. Fast.

faf-wasm-core โ€” The Kernel Router

faf-wasm-core is not a rewrite. It's a router. It wraps faf-wasm-sdk (the published, blogged, "compiler is the spec" WASM) behind a FafKernel interface. When Zig Cascade ships, it slots in โ€” same interface, no consumer changes.

import { init } from "faf-wasm-core";

const kernel = await init("rust");  // or "zig" when Cascade ships
const result = kernel.score(yaml);  // Same interface. Any engine.

// result.score = 100
// result.populated = 11
// result.ignored = 10
// result.active = 11

bun-sticky v2.0.0

Three new commands. Same zero dependencies.

bunx bun-sticky wasm-score

Score via the Mk4 WASM kernel. Shows populated/active slots, powered-by line.

bunx bun-sticky bench

Benchmark: 100 scores, average time per score. 284 microseconds on a 2017 iMac.

bunx bun-sticky badge

Get your mcpaas.live badge markdown. Drop it in your README.

init writes slotignored

bunx bun-sticky init my-cli now writes proper slotignored values for non-applicable slots based on project type. CLI projects get frontend/backend slots marked. Fullstack gets all 21 active. The file carries the scoring truth from birth.

Parity Proof

=== TS ===
  ๐Ÿ† 100%  Trophy
  Filled: 11/11 slots

=== WASM ===
  ๐Ÿ† 100%  Trophy
  Filled: 11/11 slots

Same file. Same count. Same score. Same tier. Two engines, one truth.

WASM Roundup

The FAF WASM stack, top to bottom:

PackageWhatSize
faf-wasm-sdkRustโ†’WASM compiler (the engine)322KB
faf-wasm-coreKernel router (wraps sdk, FafKernel interface)155KB npm
bun-stickyBun CLI (embeds core)185KB npm
xai-faf-zigZig ghost (scorer only, Cascade future)2.7KB

sdk is the compiler. core wraps it behind an interface. bun-sticky embeds core. builder.faf.one runs both Rust and Zig WASM in the browser.

The Numbers

  • faf-wasm-core v1.0.0 โ€” 36 tests passing
  • bun-sticky v2.0.0 โ€” 369 tests passing
  • 405 total โ€” across 2 packages, 0 failures
  • 284ฮผs โ€” average WASM score (Mk4, Rust)
  • 322KB โ€” embedded WASM binary
  • 0 dependencies โ€” still zero

The Links

bun-sticky

v2.0.0 WASM Edition

GitHub Release

faf-wasm-core

v1.0.0 Kernel Router

GitHub Release