VM Simulation Runner
This page documents runner behavior in telltale-simulator.
It covers trace shapes, runner APIs, harness APIs, and sampling logic.
Core Data Types
Trace is the simulator output container.
Each StepRecord stores one role snapshot at one sampled step.
#![allow(unused)]
fn main() {
pub struct StepRecord {
pub step: u64,
pub role: String,
pub state: Vec<FixedQ32>,
}
pub struct Trace {
pub records: Vec<StepRecord>,
}
}
step is a simulator sampling index.
state is extracted from VM registers as fixed-point values.
Runner Entry Points
The runner exposes single choreography, multi choreography, and scenario entry points.
#![allow(unused)]
fn main() {
pub fn run(
local_types: &BTreeMap<String, LocalTypeR>,
global_type: &GlobalType,
initial_states: &BTreeMap<String, Vec<FixedQ32>>,
steps: usize,
handler: &dyn EffectHandler,
) -> Result<Trace, String>
pub fn run_concurrent(
specs: &[ChoreographySpec],
steps: usize,
handler: &dyn EffectHandler,
) -> Result<Vec<Trace>, String>
pub fn run_with_scenario(
local_types: &BTreeMap<String, LocalTypeR>,
global_type: &GlobalType,
initial_states: &BTreeMap<String, Vec<FixedQ32>>,
scenario: &Scenario,
handler: &dyn EffectHandler,
) -> Result<ScenarioResult, String>
}
run returns one trace.
run_concurrent returns one trace per input choreography in deterministic input order.
run_with_scenario adds middleware, property checks, and replay artifacts.
Harness API
SimulationHarness is the integration path for external projects.
#![allow(unused)]
fn main() {
pub trait HostAdapter {
fn effect_handler(&self) -> &dyn EffectHandler;
fn initial_states(&self, scenario: &Scenario)
-> Result<Option<BTreeMap<String, Vec<FixedQ32>>>, String>;
fn validate_result(&self, scenario: &Scenario, result: &ScenarioResult)
-> Result<(), String>;
}
}
DirectAdapter wraps a direct EffectHandler.
MaterialAdapter constructs handlers from scenario material parameters.
Initial State Derivation
derive_initial_states(&Scenario) builds default states by material type.
mean_field broadcasts one concentration vector to every role.
hamiltonian maps each role index to [position, momentum].
continuum_field assigns one scalar field value per role.
Sampling and Step Mapping
The simulator records samples on invocation boundaries. It does not record after every VM instruction.
For each round, the runner counts new ObsEvent::Invoked events.
When invoke count reaches role count, the runner records one sample for each role.
The runner also inserts a Mu-step sample at active-node boundaries from active_per_role.
Scenario Execution Order
Scenario runs use a fixed per-round order for determinism.
- Compute
next_tickfrom VM clock. - Advance fault schedule from newly appended VM events.
- Deliver due delayed messages into VM buffers.
- Deliver network middleware queues when network is enabled.
- Update paused roles from active crash faults.
- Execute
vm.step_round(handler, scenario.concurrency as usize). - Update trace samples from new invoke events.
- Run online property checks.
- Persist checkpoint when interval policy triggers.
The replay binary mirrors this order when resuming from checkpoints.
Determinism and Reproducibility
Simulator randomness is scoped to SimRng and seeded from scenario seed.
The VM core remains deterministic given effect outcomes and scheduler inputs.
Record ordering is stable within each sampling pass for role snapshots.