MoonBit runtime adapter for generating and replaying Quint MBT traces
Dependencies
Quint specification
-> quint run --mbt or quint test
-> temporary ITF JSON traces
-> parse_itf_with_config
-> fresh MoonBit driver for each trace
-> apply(action, nondet_picks)
-> project(driver)
-> compare with expected Quint statenix develop -c just checkjust check| Example | Positive control | Negative control |
|---|---|---|
| OrderCheckout simulation | 8 traces / 34 states | cancellation produces the wrong terminal state |
| OrderCheckout named test | 1 trace / 2 states | the same cancellation drift through custom paths |
| BankAccount | 8 traces / 72 states | withdrawal debits twice the selected amount |
| CommandSink | 8 traces / 72 actions | the implementation omits the reset mapping |
| Path | Responsibility |
|---|---|
| adapter.mbt | ITF types, parsing, path projection, replay, and error boundaries |
| generator.mbt | validated quint run and quint test command construction plus seed precedence |
| runner/ | native async Quint process execution and temporary ITF collection |
| examples/ | complete Quint spec + MoonBit driver + executable + negative-control samples |
| scripts/check.sh | end-to-end regression controls for every example |
| justfile | reproducible formatting, type-checking, unit-test, and integration tasks |
apply : (Driver, String, Json) -> Result[Driver, String]
project : (Driver) -> Snapshot
expected : (Json) -> Result[Snapshot, String]| Error | Meaning |
|---|---|
| TraceDecode | ITF structure, configured path, metadata, or expected-state decoding is invalid |
| DriverRejected | the MoonBit driver cannot execute the Quint action or decode its arguments |
| StateDiverged | the action ran, but the projected MoonBit state differs from the Quint state |
| TraceFailed | one trace in a multi-trace suite failed; the trace index is preserved |
| process error | Quint failed, generated no traces, or an ITF file could not be read |
| Example | What it teaches |
|---|---|
| OrderCheckout | lifecycle transitions, sets and variants, nondeterministic item selection, generated traces, named traces, and nested projections |
| BankAccount | integer arguments, Quint #bigint decoding, a minimal state projection, and embedded-ITF Wasm replay |
| CommandSink | stateless action replay and detection of an incomplete command mapping |
| Official Rust concept | This MoonBit package | Status |
|---|---|---|
| Driver::step | apply callback | supported |
| State::from_driver | project callback | supported |
| generated simulation traces | RunConfig + runner.generate_run | supported |
| named scenario traces | TestConfig + custom trace paths | supported |
| multiple traces | replay_suite with a fresh driver per trace | supported |
| nondeterministic value helpers | required_nondet / optional_nondet | supported manually |
| unit-state driver | replay_stateless | supported |
| QUINT_SEED | explicit seed resolution and reproduction output | supported |
| Rust switch! macro | ordinary MoonBit pattern matching | manual equivalent |
| Rust attribute macros | explicit config and executable code | not implemented |
| Serde-derived typed ITF conversion | domain-specific JSON decoding | not implemented |
| trace shrinking | — | not implemented |
just fmt # format MoonBit source
just --fmt # format the justfile
just fmt-check # verify MoonBit formatting
just typecheck # all-target MoonBit type checking with warnings denied
just test-js # 16 unit/contract tests on JavaScript
just test-wasm # the same 16 tests on Wasm
just test-native # the same 16 tests on native
just test # run all three runtime test suites
just wasm-demo # replay an embedded ITF trace in Wasm
just integration # generate and replay real Quint traces on native
just check # run everythingpub(all) struct ReplaySuiteSummary {
traces_checked : Int
states_checked : Int
}pub(all) struct RunConfig {
spec : String
main : String?
init : String?
step : String?
max_samples : Int?
max_steps : Int?
backend : String?
seed : String
}pub(all) struct TestConfig {
spec : String
main : String?
test_name : String
max_samples : Int?
backend : String?
seed : String
}fn[D, S : Eq + Debug] replay(trace : ItfTrace, initial_driver : D, apply : (D, String, Json) -> Result[D, String], project : (D) -> S, expected : (Json) -> Result[S, String]) -> Result[ReplaySummary, ConnectError]fn[D] replay_stateless(trace : ItfTrace, initial_driver : D, apply : (D, String, Json) -> Result[D, String]) -> Result[ReplaySummary, ConnectError]fn[D, S : Eq + Debug] replay_suite(traces : Array[ItfTrace], new_driver : () -> D, apply : (D, String, Json) -> Result[D, String], project : (D) -> S, expected : (Json) -> Result[S, String]) -> Result[ReplaySuiteSummary, SuiteError]fn resolve_seed(cli_seed : String?, env_seed : String?, generated_seed : String) -> Result[String, String]MoonBit runtime adapter for generating and replaying Quint MBT traces
Dependencies