@zarzalejo/wasm-manifest
v0.1.0
Published
What does this WebAssembly module ask for? Parse the import surface of any .wasm and get a capability manifest plus a determinism verdict — before running a single instruction. Zero dependencies, browser and Node.
Maintainers
Readme
@zarzalejo/wasm-manifest
What does this WebAssembly module ask for? Parse the import surface of
any .wasm and get a capability manifest plus a determinism verdict —
statically, before running a single instruction. Zero dependencies,
browser and Node.
The idea it rests on: a wasm module cannot be non-deterministic on its own. No clock, no entropy, no network, no disk — everything effectful enters through an import the host chooses to provide. So the import section is the module's honest self-declaration, and reading it answers the two questions you should ask before instantiating third-party code:
- What does it want? — every import, classified (clock / random / net / fs / process / env / log / custom), WASI-aware, with readable signatures.
- Can it surprise me? —
puro(no imports: output is a pure function of inputs, deterministic by construction) orfrontera(its imports are its entire boundary: deterministic exactly when the host journals or serves those crossings).
Install
npm i @zarzalejo/wasm-manifestUse
import { parseManifest } from '@zarzalejo/wasm-manifest';
const manifest = parseManifest(await file.arrayBuffer());
manifest.verdict.level; // 'puro' | 'frontera'
manifest.verdict.reasons; // ["asks for random: wasi_snapshot_preview1.random_get", …]
manifest.capabilities; // { random: [...], clock: [...], custom: [...] }
manifest.imports[0]; // { module, name, kind, capability, signature }
manifest.hasStart; // runs code at instantiation — flagged
manifest.memories.imported;// host-shared memory — flagged as a wide channelNothing executes: the parser only decodes the sections the manifest needs
(types, imports, memories, exports, start) and never touches code.
Malformed input throws ManifestError with the byte offset.
What it's for
- The doorman of a plugin runtime — audit a third-party module and
decide what to grant before
WebAssembly.instantiate. Denying a capability then means omitting the import: the module fails at link time, not behind a runtime guard. - CI / supply-chain checks — fail a build when a dependency's wasm starts asking for the network.
- The static half of record/replay — the dynamic half (journaled
boundaries, cryptographic receipts, verified replay) is its sibling
@zarzalejo/agent-receipts.
Status
0.1.x — core binary format (wasm 1.0 sections; limits parse memory64
and shared flags). Component-model (wasi:* world) imports are reported
with their literal names; richer component parsing is future work.
