API Reference
Serialization
Last updated 2026-04-13
Serialization
This document covers the serialized forms that already exist in the runtime and the safety rules they are expected to follow.
Formats
mustard serializes:
- Compiled programs
- Suspended execution snapshots
Compiled-Program Format Goals
- preserve lowered bytecode without reparsing source
- remain private to
mustardrather than becoming a public stable bytecode - round-trip only within the same
mustardversion - fail safely on corrupt or unsupported input
Versioning
- Serialized data is versioned explicitly.
- Round-tripping is only guaranteed within the same
mustardversion. - Cross-version loads are rejected.
Safety Rules
- The current loader validates the outer format by decoding the tagged payload and checking the serialized version.
- Compiled-program loads validate root function ids, closure targets, jump targets, and stack/scope discipline before execution.
- Snapshot loads also validate live frame pointers across synchronous frames, async continuations, and queued microtasks, plus referenced runtime objects, iterator references, promise references, and queued host-call state before restore.
- Loaded snapshots are inert until the host rebinds explicit resume policy. Restores fail closed if the host does not reassert allowed capability names and authoritative runtime limits.
- Public
ExecutionSnapshotserde deserialization reuses the same validation, accounting recomputation, cached post-load accounting state, and explicit-policy gate asload_snapshot(), so callers cannot bypass restore checks by deserializing the public type directly. - Opaque host references, native handles, and host futures are never serialized.
- Snapshots are only created at explicit suspension points.
- Pending host work is represented by suspended or queued capability metadata plus the resumable VM snapshot and internal promise state, not by native futures.
- Active array
for...ofiterators are serialized as internal runtime state that preserves their source array reference and next index, so resumed loops continue from the next unvisited element. MapandSetvalues are serialized only inside internal runtime snapshots, where their insertion-ordered entry lists and referenced guest values are preserved after validation.- In the Node wrapper,
start()andProgress.dump()happen before any async capability promise is awaited, so JavaScriptPromiseobjects never enter the serialized snapshot. - The public Rust
dump_snapshot()/load_snapshot()format remains self-contained, but current addon-mode suspended steps now serialize detached snapshot state plus an external compiled-program binding. Those detached snapshot bytes carry the originating compiled-program identity, and addon restore fails closed if the supplied detached program does not match. - Live addon
Progressobjects now keep their suspended runtime in a process-local opaque native snapshot handle until the host asks to dump raw bytes. That handle never crosses the public boundary, so same-processresume()no longer needs to round-trip serialized snapshot bytes through JavaScript. - In the Node wrapper,
Progress.dump()includes detachedsnapshot_id,snapshot_key_digest, andtokenmetadata authenticated by the configuredsnapshotKey. Current dumps also include detachedprogrambytes plusprogram_id, along with an authenticated suspended-manifest blob for capability metadata, andProgress.load(...)verifies that bundle before it trusts the manifest. Current addon restore also reapplies explicit snapshot policy once when it rebuilds the live native handle, falls back to legacy inspection only when the authenticated manifest is absent, and then resumes future same-process steps through that opaque handle. Progress.load(...)always requires explicitcapabilitiesorconsole, explicitlimitsas an object (use{}for defaults), and the originalsnapshotKeybefore inspection or resume. Consumed same-process dumps stay single-use acrossworker_threadsand duplicate package copies in the same PID.
Value Encoding
The encoding is tagged so that values such as undefined, NaN, Infinity,
and -0 can round-trip safely.
Serialization Exclusions
The following values may never be serialized:
- opaque host references
- native handles
- unresolved host futures
- JavaScript callback identities from the embedding host
Map and Set are intentionally absent from StructuredValue, sidecar wire
messages, and host-call payloads even though validated snapshots may preserve
them as internal runtime objects.