Skip to main content

telltale_vm/
lib.rs

1//! Bytecode VM for choreographic session type protocols.
2//!
3//! This crate provides a standalone, embeddable virtual machine that executes
4//! choreographic protocols projected to local session types. The VM validates
5//! every instruction against its session type monitor, ensuring protocol
6//! conformance at runtime.
7//!
8//! # Architecture
9//!
10//! The VM follows the Lean specification in `lean/Runtime/VM/`:
11//! - **Instructions** ([`instr::Instr`]): bytecode ops for send/recv/choice/session lifecycle
12//! - **Coroutines** ([`coroutine::Coroutine`]): lightweight execution units, one per role
13//! - **Sessions** ([`session::SessionStore`]): manage session lifecycle and namespaces
14//! - **Buffers** ([`buffer::BoundedBuffer`]): bounded message channels with backpressure
15//! - **Scheduler** ([`scheduler::Scheduler`]): policy-based coroutine scheduling
16//! - **Loader** ([`loader`]): dynamic choreography loading with validation
17//! - **Compiler** ([`compiler`]): compile `LocalTypeR` to bytecode
18//!
19//! The VM is the **single execution engine** for simulation and runtime
20//! orchestration. Higher-level systems (e.g. `telltale-simulator`) wrap the
21//! VM with deterministic middleware for network latency, faults, property
22//! monitoring, and checkpointing.
23//!
24//! **Nested simulation** is supported via [`nested::NestedVMHandler`], which
25//! allows a VM coroutine to host an inner VM for distributed or hierarchical
26//! simulations.
27//!
28//! # Effect Handler Contract
29//!
30//! The VM's [`effect::EffectHandler`] is synchronous, deterministic, and
31//! **session-local**. It must not depend on global time or shared mutable
32//! state across sessions. This is distinct from the async, typed
33//! `telltale_choreography::ChoreoHandler` used by generated choreography code.
34//!
35//! # Usage
36//!
37//! ```ignore
38//! use telltale_vm::{VM, VMConfig, compiler, loader::CodeImage};
39//!
40//! let config = VMConfig::default();
41//! let mut vm = VM::new(config);
42//! let image = CodeImage::from_local_types(&local_types, &global_type);
43//! let sid = vm.load_choreography(image, &handler)?;
44//! while vm.step(&handler)? {}
45//! ```
46
47use cfg_if::cfg_if;
48
49pub mod architecture;
50pub mod backend;
51pub mod bridge;
52pub mod buffer;
53pub mod clock;
54pub mod commit_common;
55pub mod communication_replay;
56pub mod compiler;
57pub mod composition;
58pub mod coroutine;
59pub mod determinism;
60pub mod driver;
61pub mod effect;
62pub mod envelope_diff;
63pub mod exec;
64pub mod exec_api;
65pub mod faults;
66pub mod guard;
67pub mod identity;
68pub mod instr;
69pub mod instruction_semantics;
70pub mod integration;
71pub mod intern;
72pub mod kernel;
73pub mod loader;
74pub mod nested;
75pub mod output_condition;
76pub mod persistence;
77pub mod runtime_contracts;
78pub mod scheduler;
79pub mod serialization;
80pub mod session;
81pub mod trace;
82pub mod transfer_semantics;
83pub mod verification;
84pub mod vm;
85
86cfg_if! {
87    if #[cfg(feature = "multi-thread")] {
88        pub mod threaded;
89    }
90}
91
92cfg_if! {
93    if #[cfg(target_arch = "wasm32")] {
94        pub mod wasm;
95    }
96}
97
98pub use architecture::{
99    EngineOwnership, EngineRole, CANONICAL_ENGINE, CROSS_TARGET_CONTRACT, ENGINE_OWNERSHIP,
100    EQUIVALENCE_SURFACES,
101};
102pub use backend::VMBackend;
103pub use bridge::{
104    EffectGuardBridge, IdentityGuardBridge, IdentityPersistenceBridge, IdentityVerificationBridge,
105    PersistenceEffectBridge,
106};
107pub use clock::SimClock;
108pub use communication_replay::{
109    CommunicationConsumeResult, CommunicationConsumption, CommunicationConsumptionArtifact,
110    CommunicationIdentity, CommunicationReplayError, CommunicationReplayMode,
111    CommunicationReplayState, CommunicationStepKind, DefaultCommunicationConsumption,
112    COMM_IDENTITY_DOMAIN_TAG, COMM_REPLAY_DUPLICATE_TAG, COMM_REPLAY_SEQUENCE_MISMATCH_TAG,
113};
114pub use composition::{
115    ComposedRuntime, CompositionCertificate, CompositionError, DeterminismCapability, MemoryBudget,
116    MemoryUsage, ProtocolBundle, SchedulerCapability, TheoremPackCapabilities,
117};
118pub use coroutine::{CoroStatus, Coroutine, CoroutineState, KnowledgeSet, Value};
119pub use determinism::{DeterminismMode, EffectDeterminismTier};
120pub use driver::NativeSingleThreadDriver;
121pub use effect::{
122    classify_effect_error, classify_effect_error_owned, send_fast_path_key, CorruptionType,
123    EffectError, EffectErrorCategory, EffectTraceEntry, EffectTraceTape, RecordingEffectHandler,
124    ReplayEffectHandler, SendDecisionFastPathInput, SendPayloadKind, TopologyPerturbation,
125};
126pub use envelope_diff::{
127    EffectOrderingClass, EnvelopeDiff, EnvelopeDiffArtifactV1, FailureVisibleDiffClass,
128    SchedulerPermutationClass, WaveWidthBound,
129};
130pub use exec_api::{ExecResult, ExecStatus, StepEvent, StepPack};
131pub use faults::{classify_fault, fault_code, fault_code_of, FaultClass};
132pub use guard::{GuardLayer, InMemoryGuardLayer, LayerId};
133pub use identity::{IdentityModel, ParticipantId, SiteId as IdentitySiteId, StaticIdentityModel};
134pub use instr::Instr;
135pub use integration::{run_loaded_vm_record_replay_conformance, LoadedVmReplayConformance};
136pub use intern::{EdgeId, EdgeSymbol, EdgeSymbolTable, StringId, SymbolTable};
137pub use kernel::VMKernel;
138pub use nested::NestedVMHandler;
139pub use output_condition::{
140    verify_output_condition, OutputConditionCheck, OutputConditionHint, OutputConditionMeta,
141    OutputConditionPolicy,
142};
143pub use persistence::{NoopPersistence, PersistenceModel};
144pub use runtime_contracts::{
145    admit_vm_runtime, determinism_profile_supported, enforce_vm_runtime_gates,
146    request_determinism_profile, requires_vm_runtime_contracts, runtime_capability_snapshot,
147    DeterminismArtifacts, RuntimeAdmissionResult, RuntimeContracts, RuntimeGateResult,
148};
149pub use scheduler::{
150    CrossLaneHandoff, LaneId as SchedulerLaneId, PriorityPolicy, SchedPolicy, SchedState,
151    Scheduler, StepUpdate,
152};
153pub use serialization::{
154    canonical_effect_trace, canonical_replay_fragment_v1, canonical_trace_v1,
155    CanonicalReplayFragmentV1, CanonicalTraceV1,
156};
157pub use session::{
158    decode_edge_json, ClosedSessionSummary, Edge, HandlerId, SessionId, SessionStore,
159    SessionStoreMemoryUsage, SessionStoreRetainedBytes,
160};
161pub use trace::{
162    normalize_trace, normalize_trace_v1, obs_session, strict_trace, with_tick, NormalizedTraceV1,
163    TRACE_NORMALIZATION_SCHEMA_VERSION,
164};
165pub use transfer_semantics::{decode_transfer_request, move_endpoint_bundle, TransferRequest};
166pub use verification::{
167    signValue, sign_value, verifySignedValue, verify_signed_value, AuthProof, AuthTree, Commitment,
168    DefaultVerificationModel, Hash, HashTag, Nullifier, Signature, SigningKey, VerificationModel,
169    VerifyingKey,
170};
171pub use vm::{
172    EffectTraceCaptureMode, MonitorMode, ObservabilityRetentionConfig, ObservabilityRetentionMode,
173    PayloadValidationMode, Program, ProgramStore, RuntimeTuningProfile, SchedExecStatus,
174    SchedStepDebug, ThreadedRoundSemantics, VMConfig, VMState, VmMemoryUsage, VmRetainedBytes, VM,
175};
176
177cfg_if! {
178    if #[cfg(feature = "multi-thread")] {
179        pub use driver::NativeThreadedDriver;
180        pub use threaded::{
181            ContentionMetrics, LaneHandoff, LaneId, LaneSchedulerState, LaneSelection, ThreadedVM,
182        };
183    }
184}
185
186cfg_if! {
187    if #[cfg(target_arch = "wasm32")] {
188        pub use wasm::WasmVM;
189    }
190}