moxzi
Docs / Compatibility / Known differences

Known differencesalpha

Where does moxzi differ from moc or from a real replica, and why?

A difference is a place where moxzi's behaviour is deliberately not the reference's, with a reason that survives being written down. Everything on this page is intended and gated; anything not on this page and not obviously a limit is a bug worth reporting.

Differences from moc, the reference compiler#

The output bytes are the thing that must match, and they do — 221 corpus programs, byte-identical across independent builds. The differences are in what the compiler says.

DifferencemocmoxziWhy
Non-toplevel actorM0069 plus M0037 and M0038M0069 aloneone cause, one message. Gated by scripts/nontoplevel_actor_matrix.sh
Parse errorsM0001M0000moxzi's M0000 is a catch-all; match the text as well as the code
Warningsmany, with -A/-W/-E levelingeight (M0089, M0145, M0146, M0173, M0194, M0198, M0254, M0265, M0266 among them), no levelingM0145/M0146 pattern coverage is a faithful port of moc's checker; M0194/M0198 unused-identifier covers blocks, match arms and loops (function parameters, top-level program ids and object fields do not warn yet). As measured against moc, warnings from --package libraries are suppressed; errors never are
Legacy actorsacceptedrejected with M0220persistent is how a program says its state survives; silence is the bug. --default-persistent-actors rewrites bare actors
Unimplemented front-end formsn/aM9000 unimplemented: …moxzi names its own gaps at the point they are hit rather than miscompiling

Three corpus programs are known to be classified under a different code by each compiler and are recorded as such in the parity harness: moc M0106 → moxzi M0220, moc M0086 → moxzi M0220, moc M0076 → moxzi M0077.

Differences from a real replica, off-chain#

These apply to moxzid and to the browser runtime. Each is a property the Internet Computer gets from having a subnet, and none of them is faked.

DifferenceWhat actually happensWhy not faked
No certificatesic0.data_certificate_present returns 0a certificate is a subnet threshold signature. A forged one would be verified and believed — worse than none. @dfinity/agent's Actor is therefore unsupported; the generated idlFactory path is
raw_rand is derived, not drawnSHA-256 over (host seed, canister, counter)the runtime replays a write-ahead log to recover; fresh entropy would make a replayed message take a different branch than the one journalled. Honest property: unpredictable without the host seed, entirely predictable with it
ic0.time is journalledthe clock value a message saw is recorded and replayedsame reason: recovery must reproduce the state that was lost, not a new one
Outcall responses are journalledrecorded in their own file, replayed on recoverya network response is not the same twice; without this an actor that called out could not be recovered at all
Ingress callerthe anonymous principal [4] by default; an authenticated client names one per request with x-caller: <principal>claiming a caller is an operator capability, like dfx minting identities against a local replica — the WAL records it, so replay reproduces the identities that spoke. Signed ingress envelopes are a later milestone
Trap textIC0503 for explicit ic0.trap, IC0502 only for a recognised wasm trap (currently just stack overflow)the IC's first line is reproduced; its version-dependent second sentence is not
Stable-type compatibilitymoxzid pre-flights through moxzi stable-compatible and refuses a proven incompatibility, as the replica does; ?force=true skips the pre-flight (the RTS's memory check still has the final word)with no moxzi binary on the machine (MOXZI_BIN), moxzid cannot ask and falls back to a loud warning
HTTP verbsmoxzid's gateway forwards every verbmainnet's boundary nodes do not. This is why an actor can speak WebDAV off-chain; the REST subset of the same actor runs unchanged on-chain

Differences specific to the browser#

DifferenceDetail
Per-instruction metering in a browser is opt-inV8 has no fuel, so moxzi-web instruments a module at install time to count its own. With meter: true an instruction limit is enforced as it is in moxzid and on the IC; without it, only creation and message fees are charged
Preemption is wall-clocka runaway message is killed by a worker deadline, not an instruction count
Preemption rewinds coarselyto the last completed message, not the trapping one — a terminated worker cannot report where it got to. Autosave makes the window one message wide
Lower nesting ceiling for the compilera guest frame on V8's stack costs far more than one on wasmtime's; ~60 chained operators compile in a tab, and past ~400 the limit moves into parsing

None of these changes what a program computes: 149 corpus programs run zero-diverging against the native runtime, which was itself validated against a real replica.

Differences that only exist on-chain#

DifferenceDetail
An on-chain build returns an unlinked artifactby design. moxzi link is a real step; validation failing on the unlinked module is expected, not a symptom
Builds serialize per canisterone compiler canister is one job queue. Parallelism means more canisters
Actor-class librariesa remote build cannot pre-build an imported actor class library; build the library first or compile locally
The operator can read uploaded sourcethe VFS is canister state. Build from a mops tag — which uploads zero bytes — or accept the disclosure

Differences that are not differences#

Three things that look like divergences and are not, recorded because each one cost time:

Looks likeActually
Query output missing on a replicaquery prints are not replicated
An actor's log truncatedthe IC log is a ring buffer
A sweep reporting many new failuresvery often a stale binary or an orphaned server process — check what is actually running before believing a divergence

Next#

On this pageDifferences from moc, the reference compilerDifferences from a real replica, off-chainDifferences specific to the browserDifferences that only exist on-chainDifferences that are not differencesNext