moonbit-causalkit

    Deterministic causal clocks and event simulation for MoonBit

    distributed-systems
    causality
    clock
    simulation
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    3 days ago
    Downloads
    4

    #MoonBit CausalKit

    MoonBit CausalKit is a deterministic, pure-MoonBit toolkit for modelling causal time in distributed systems. It provides Hybrid Logical Clocks (HLC), version-vector comparison, and a caller-controlled simulator for delayed or partitioned message delivery.

    #Why it exists

    Physical timestamps cannot explain whether two writes are causally related, especially when device clocks drift or messages arrive out of order. CausalKit keeps that logic as a reusable algorithm library: applications keep control of networking, persistence, authentication, and wall-clock acquisition.

    #Current capabilities

    • Validated HLC timestamps and rollback-safe local/remote clock transitions.
    • Version vectors with merge, causal comparison, and concurrency detection.
    • A deterministic simulator with local events, delayed messages, offline replicas, recovery, and append-only causal traces.
    • A state-based multi-value register that preserves concurrent values and resolves them only after a causally newer write.
    • Trace analysis with direct causal edges, concurrent-event pairs, and causal layers for debuggers or visualizers.
    • Replica acknowledgement tracking and stable-frontier calculation for safe event-log compaction decisions.
    • A causal operation buffer that holds out-of-order replicated operations until their prerequisites and per-replica sequence are present, while deduplicating retransmitted dots.
    • An immutable operation-log split that turns a stable prefix into a checkpoint and preserves the exact replay suffix.
    • Dot and DotSet primitives, anti-entropy range planning, replication batches, checkpoint validation, and replay-gap detection.
    • Observed-remove sets, PN counters, LWW registers, and conflict-preserving causal maps as reusable CRDT building blocks.
    • Dynamic membership views, clock anomaly diagnostics, vector-distance metrics, advanced causal graph queries, and Graphviz/Mermaid-friendly trace export.

    #Run locally

    Add the package to a MoonBit project:

    moon add cauchyQ/moonbit-causalkit

    Check this repository and run its example:

    moon check --deny-warn moon test --deny-warn moon run cmd/main

    The command-line example simulates a message held during a replica outage and delivered after recovery. The example and all core algorithms run without network, storage, or runtime dependencies.

    #Minimal use

    let local = @causal.VersionVector::new().increment("device-a").unwrap() let remote = @causal.VersionVector::new().increment("device-b").unwrap() assert_eq(local.compare(remote), @causal.Concurrent)

    Add cauchyQ/moonbit-causalkit to your package imports as @causal. Public types and functions are listed in pkg.generated.mbti.

    #Scope

    This is an algorithm, CRDT-building-block, and simulation library, not a production replication protocol, database, network transport, cryptographic identity system, or consensus implementation. The narrow boundary keeps its behavior reproducible across native, JavaScript, and WebAssembly targets.

    The implementation is original and AI-assisted. It does not copy or port an upstream codebase and uses no runtime dependencies or third-party test data.

    #License

    Apache-2.0. See LICENSE.

    BatchDelivery

    pub(all) struct BatchDelivery {
    buffer : CausalBuffer
    released : Array[CausalOperation]
    accepted_count : Int
    duplicate_count : Int
    } derive(
    Debug
    )

    Result of feeding a batch through a causal buffer.

    BatchDelivery::append_to_log

    fn BatchDelivery::append_to_log(self : BatchDelivery, log : OperationLog, applied_at : Int) -> OperationLog

    Append released operations to an existing log with one application time.

    BatchDelivery::frontier

    fn BatchDelivery::frontier(self : BatchDelivery) -> VersionVector

    Causal frontier after delivery.

    BatchError

    pub(all) enum BatchError {
    EmptyBatchSource
    EmptyBatchId
    DuplicateBatchOperation(String)
    DuplicateBatchDot(String, Int)
    BatchCounterBeyondFrontier(String, Int, Int)
    BatchDependencyBeyondFrontier(String, String, Int, Int)
    } derive(Eq,
    Debug
    )

    Batch validation failures.

    BufferError

    pub(all) enum BufferError {
    EmptyOperationId
    EmptyReplicaId
    NonPositiveCounter(Int)
    } derive(Eq,
    Debug
    )

    CausalBuffer

    pub struct CausalBuffer {
    applied : VersionVector
    pending : Array[CausalOperation]
    } derive(
    Debug
    )

    prerequisites and per-replica predecessor dot have arrived.

    CausalBuffer::applied

    fn CausalBuffer::applied(self : CausalBuffer) -> VersionVector

    CausalBuffer::new

    CausalBuffer::offer

    causally ready. The returned array is the exact application order.

    CausalBuffer::pending

    CausalCheckpoint

    pub(all) struct CausalCheckpoint {
    frontier : VersionVector
    state : String
    operation_count : Int
    created_at : Int
    } derive(Eq,
    Debug
    )

    state is application-defined so the causal core remains storage-neutral.

    CausalCheckpoint::created_at

    fn CausalCheckpoint::created_at(self : CausalCheckpoint) -> Int

    Logical or physical host time recorded for observability.

    CausalCheckpoint::frontier

    Captured causal frontier.

    CausalCheckpoint::new

    fn CausalCheckpoint::new(frontier : VersionVector, state : String, operation_count : Int, created_at : Int) -> Result[CausalCheckpoint, CheckpointError]

    Construct a checkpoint supplied by a persistence adapter.

    CausalCheckpoint::operation_count

    fn CausalCheckpoint::operation_count(self : CausalCheckpoint) -> Int

    Number of operations folded into the snapshot.

    CausalCheckpoint::state

    fn CausalCheckpoint::state(self : CausalCheckpoint) -> String

    Opaque application snapshot.

    CausalEdge

    pub(all) struct CausalEdge {
    earlier : TraceEvent
    later : TraceEvent
    } derive(
    Debug
    )

    omit transitive predecessors so a rendered graph stays useful to people.

    CausalLayer

    pub(all) struct CausalLayer {
    index : Int
    events : Array[TraceEvent]
    } derive(
    Debug
    )

    causal dependency on an earlier event in that layer.

    CausalMap

    pub struct CausalMap {
    entries : Array[CausalMapEntry]
    tombstones : Array[CausalMapTombstone]
    context : VersionVector
    } derive(
    Debug
    )

    suppresses writes observed by that removal; a concurrent put survives.

    CausalMap::compact

    fn CausalMap::compact(self : CausalMap, stable_frontier : VersionVector) -> CausalMap

    Compact removal contexts already covered by a stable frontier.

    CausalMap::contains_key

    fn CausalMap::contains_key(self : CausalMap, key : String) -> Bool

    Whether a key is visible.

    CausalMap::context

    fn CausalMap::context(self : CausalMap) -> VersionVector

    Causal history observed by this map, including removed values.

    CausalMap::entries

    fn CausalMap::entries(self : CausalMap) -> Array[CausalMapEntry]

    Visible entries.

    CausalMap::get

    fn CausalMap::get(self : CausalMap, key : String) -> MultiValueRegister?

    Find a visible register by key.

    CausalMap::keys

    fn CausalMap::keys(self : CausalMap) -> Array[String]

    Visible keys.

    CausalMap::merge

    fn CausalMap::merge(self : CausalMap, other : CausalMap) -> CausalMap

    Merge independently updated map states.

    CausalMap::new

    fn CausalMap::new() -> CausalMap

    Create an empty map.

    CausalMap::put

    fn CausalMap::put(self : CausalMap, key : String, writer : String, value : String) -> Result[CausalMap, CausalMapError]

    Put a new value using the register's current causal context.

    CausalMap::remove

    fn CausalMap::remove(self : CausalMap, key : String) -> Result[CausalMap, CausalMapError]

    Remove the currently observed versions of a key.

    CausalMap::tombstones

    fn CausalMap::tombstones(self : CausalMap) -> Array[CausalMapTombstone]

    Retained removal contexts.

    CausalMapEntry

    pub(all) struct CausalMapEntry {
    key : String
    register : MultiValueRegister
    } derive(
    Debug
    )

    One key and its conflict-preserving register.

    CausalMapError

    pub(all) enum CausalMapError {
    EmptyMapKey
    EmptyMapWriter
    } derive(Eq,
    Debug
    )

    Causal-map validation failures.

    CausalMapTombstone

    pub(all) struct CausalMapTombstone {
    key : String
    context : VersionVector
    } derive(Eq,
    Debug
    )

    A removed key and the context observed by the removal.

    CausalOperation

    pub(all) struct CausalOperation {
    id : String
    replica : String
    counter : Int
    prerequisites : VersionVector
    payload : String
    } derive(
    Debug
    )

    An operation with an explicit causal prerequisite context and one dot.

    CausalOperation::new

    fn CausalOperation::new(id : String, replica : String, counter : Int, prerequisites : VersionVector, payload : String) -> Result[CausalOperation, BufferError]

    CausalOrder

    pub(all) enum CausalOrder {
    Before
    After
    Equal
    Concurrent
    } derive(Eq,
    Debug
    )

    The causal relation between two version vectors.

    CausalPath

    pub(all) struct CausalPath {
    events : Array[TraceEvent]
    } derive(
    Debug
    )

    A path through causally ordered events.

    CheckpointError

    pub(all) enum CheckpointError {
    NegativeCheckpointOperationCount(Int)
    NegativeCheckpointTime(Int)
    CheckpointAheadOfLog(String, Int, Int)
    ReplayGap(String, Int, Int)
    ReplayDependencyMissing(String)
    } derive(Eq,
    Debug
    )

    Validation failures for restored checkpoints.

    CheckpointPlan

    pub(all) struct CheckpointPlan {
    checkpoint : CausalCheckpoint
    stable_entries : Array[LoggedOperation]
    replay_log : OperationLog
    } derive(
    Debug
    )

    A checkpoint and the unstable suffix still required for replay.

    ClockDiagnosticError

    pub(all) enum ClockDiagnosticError {
    NegativeRollbackThreshold(Int)
    NegativeForwardJumpThreshold(Int)
    NegativeClockReading(Int)
    } derive(Eq,
    Debug
    )

    Policy and sample validation failures.

    ClockDiagnosticPolicy

    pub(all) struct ClockDiagnosticPolicy {
    maximum_rollback : Int
    maximum_forward_jump : Int
    } derive(Eq,
    Debug
    )

    when a reading is suspicious; this policy is observability, not rejection.

    ClockDiagnosticPolicy::new

    fn ClockDiagnosticPolicy::new(maximum_rollback : Int, maximum_forward_jump : Int) -> Result[ClockDiagnosticPolicy, ClockDiagnosticError]

    Construct diagnostic thresholds.

    ClockDiagnostics

    pub struct ClockDiagnostics {
    policy : ClockDiagnosticPolicy
    last_reading : Int
    samples : Array[ClockSample]
    rollback_count : Int
    forward_jump_count : Int
    } derive(
    Debug
    )

    Immutable diagnostics accumulated for one clock source.

    ClockDiagnostics::anomalies

    Only anomalous samples, suitable for telemetry emission.

    ClockDiagnostics::forward_jump_count

    fn ClockDiagnostics::forward_jump_count(self : ClockDiagnostics) -> Int

    Number of excessive forward jumps.

    ClockDiagnostics::has_anomaly

    fn ClockDiagnostics::has_anomaly(self : ClockDiagnostics) -> Bool

    Whether any suspicious sample has been observed.

    ClockDiagnostics::last_reading

    fn ClockDiagnostics::last_reading(self : ClockDiagnostics) -> Int

    Most recent physical reading.

    ClockDiagnostics::new

    fn ClockDiagnostics::new(policy : ClockDiagnosticPolicy, initial_reading : Int) -> Result[ClockDiagnostics, ClockDiagnosticError]

    Start diagnostics at a known physical reading.

    ClockDiagnostics::observe

    fn ClockDiagnostics::observe(self : ClockDiagnostics, reading : Int) -> Result[ClockDiagnostics, ClockDiagnosticError]

    Classify and append one reading.

    ClockDiagnostics::reset

    reading as the next comparison baseline.

    ClockDiagnostics::rollback_count

    fn ClockDiagnostics::rollback_count(self : ClockDiagnostics) -> Int

    Number of excessive rollbacks.

    ClockDiagnostics::samples

    Recorded samples in observation order.

    ClockError

    pub(all) enum ClockError {
    NodeMismatch(expected~ : String, found~ : String)
    } derive(Eq,
    Debug
    )

    Clock-specific domain errors.

    ClockReadingStatus

    pub(all) enum ClockReadingStatus {
    ClockReadingAccepted
    ClockRollback(Int)
    ClockForwardJump(Int)
    } derive(Eq,
    Debug
    )

    Classification of a physical clock reading relative to the prior sample.

    ClockSample

    pub(all) struct ClockSample {
    reading : Int
    previous : Int
    status : ClockReadingStatus
    } derive(Eq,
    Debug
    )

    One classified host-clock sample.

    ConcurrentPair

    pub(all) struct ConcurrentPair {
    first : TraceEvent
    second : TraceEvent
    } derive(
    Debug
    )

    Two trace events whose contexts are genuinely concurrent.

    CounterComponent

    pub(all) struct CounterComponent {
    replica : String
    positive : Int
    negative : Int
    } derive(Eq,
    Debug
    )

    One replica's monotonic positive and negative components.

    CounterError

    pub(all) enum CounterError {
    EmptyCounterReplica
    NegativeCounterComponent(String, Int, Int)
    NegativeCounterAmount(Int)
    } derive(Eq,
    Debug
    )

    Counter validation errors.

    Dot

    pub(all) struct Dot {
    replica : String
    counter : Int
    } derive(Eq,
    Debug
    )

    A dot identifies exactly one event in one replica's monotonic sequence.

    Dot::compare

    fn Dot::compare(self : Dot, other : Dot) -> Int

    Deterministic MoonBit string ordering by replica and then counter.

    Dot::context

    fn Dot::context(self : Dot) -> VersionVector

    Convert a dot to the version vector that covers only its own sequence.

    Dot::is_covered_by

    fn Dot::is_covered_by(self : Dot, context : VersionVector) -> Bool

    Test whether a version vector has observed this dot.

    Dot::new

    fn Dot::new(replica : String, counter : Int) -> Result[Dot, DotError]

    Construct a validated causal dot.

    DotError

    pub(all) enum DotError {
    EmptyDotReplica
    NonPositiveDotCounter(Int)
    } derive(Eq,
    Debug
    )

    Validation errors for dots and dot collections.

    DotSet

    pub struct DotSet {
    dots : Array[Dot]
    } derive(Eq,
    Debug
    )

    depend on message arrival order.

    DotSet::add

    fn DotSet::add(self : DotSet, candidate : Dot) -> DotSet

    Add one dot, retaining deterministic order.

    DotSet::after

    fn DotSet::after(self : DotSet, context : VersionVector) -> DotSet

    Keep only dots not already covered by a version vector.

    DotSet::contains

    fn DotSet::contains(self : DotSet, candidate : Dot) -> Bool

    Test exact dot membership.

    DotSet::covered

    fn DotSet::covered(self : DotSet, context : VersionVector) -> DotSet

    Keep only dots covered by a version vector.

    DotSet::difference

    fn DotSet::difference(self : DotSet, other : DotSet) -> DotSet

    Set difference.

    DotSet::dots

    fn DotSet::dots(self : DotSet) -> Array[Dot]

    Return normalized dots for inspection or host serialization.

    DotSet::from_array

    fn DotSet::from_array(dots : Array[Dot]) -> Result[DotSet, DotError]

    Validate, deduplicate, and sort a collection of dots.

    DotSet::frontier

    fn DotSet::frontier(self : DotSet) -> VersionVector

    Build the component-wise maximum context represented by these dots.

    DotSet::intersection

    fn DotSet::intersection(self : DotSet, other : DotSet) -> DotSet

    Set intersection.

    DotSet::is_subset_of

    fn DotSet::is_subset_of(self : DotSet, other : DotSet) -> Bool

    Return true when every dot in this set occurs in the other set.

    DotSet::length

    fn DotSet::length(self : DotSet) -> Int

    Number of distinct dots.

    DotSet::new

    fn DotSet::new() -> DotSet

    Create an empty dot set.

    DotSet::next_counter

    fn DotSet::next_counter(self : DotSet, replica : String) -> Int

    Return the next counter after the greatest dot for a replica.

    DotSet::remove

    fn DotSet::remove(self : DotSet, candidate : Dot) -> DotSet

    Remove one exact dot.

    DotSet::union

    fn DotSet::union(self : DotSet, other : DotSet) -> DotSet

    Set union.

    EdgeRow

    pub(all) struct EdgeRow {
    from_sequence : Int
    to_sequence : Int
    } derive(Eq,
    Debug
    )

    A serialization-friendly direct edge.

    HlcClock

    pub(all) struct HlcClock {
    node : String
    last : HlcTimestamp
    } derive(
    Debug
    )

    Mutable Hybrid Logical Clock state for one replica.

    HlcClock::last

    fn HlcClock::last(self : HlcClock) -> HlcTimestamp

    Return the last generated timestamp without advancing the clock.

    HlcClock::new

    fn HlcClock::new(node : String, initial_physical : Int) -> Result[HlcClock, TimestampError]

    the same physical time receives logical counter one.

    HlcClock::receive

    fn HlcClock::receive(self : HlcClock, remote : HlcTimestamp, physical_now : Int) -> HlcTimestamp

    both the local state and the received timestamp.

    HlcClock::restore

    fn HlcClock::restore(node : String, last : HlcTimestamp) -> Result[HlcClock, ClockError]

    sequence under a new identity.

    HlcClock::tick

    fn HlcClock::tick(self : HlcClock, physical_now : Int) -> HlcTimestamp

    clock keeps the known physical component and advances its logical counter.

    HlcTimestamp

    pub(all) struct HlcTimestamp {
    physical : Int
    logical : Int
    node : String
    } derive(Eq,
    Debug
    )

    algorithm remains deterministic in tests, simulations, and WASM runtimes.

    HlcTimestamp::compare

    fn HlcTimestamp::compare(self : HlcTimestamp, other : HlcTimestamp) -> Int

    A negative value means self comes before other.

    HlcTimestamp::new

    fn HlcTimestamp::new(physical : Int, logical : Int, node : String) -> Result[HlcTimestamp, TimestampError]

    malformed decoded data.

    HlcTimestamp::precedes_or_equals

    fn HlcTimestamp::precedes_or_equals(self : HlcTimestamp, other : HlcTimestamp) -> Bool

    True when self is no later than other in HLC total order.

    HlcTimestamp::to_string

    fn HlcTimestamp::to_string(self : HlcTimestamp) -> String

    format and validate it at the boundary.

    LastWriterWinsError

    pub(all) enum LastWriterWinsError {
    EmptyLastWriter
    } derive(Eq,
    Debug
    )

    LWW register validation errors.

    LastWriterWinsRegister

    pub(all) struct LastWriterWinsRegister {
    value : String
    writer : String
    timestamp : HlcTimestamp
    } derive(Eq,
    Debug
    )

    preserving conflicts with MultiValueRegister.

    LastWriterWinsRegister::dominates

    Whether this state would win or tie during merge.

    LastWriterWinsRegister::merge

    Deterministic state merge.

    LastWriterWinsRegister::new

    fn LastWriterWinsRegister::new(value : String, writer : String, timestamp : HlcTimestamp) -> Result[LastWriterWinsRegister, LastWriterWinsError]

    Construct a validated register state.

    LastWriterWinsRegister::timestamp

    Timestamp of the current value.

    LastWriterWinsRegister::value

    Current value.

    LastWriterWinsRegister::write

    fn LastWriterWinsRegister::write(self : LastWriterWinsRegister, value : String, writer : String, timestamp : HlcTimestamp) -> Result[LastWriterWinsRegister, LastWriterWinsError]

    after corrupted or manually restored clocks produce a collision.

    LastWriterWinsRegister::writer

    fn LastWriterWinsRegister::writer(self : LastWriterWinsRegister) -> String

    Writer of the current value.

    LoggedOperation

    pub(all) struct LoggedOperation {
    operation : CausalOperation
    applied_at : Int
    } derive(
    Debug
    )

    An append-only record of operations released by a causal buffer.

    MemberStatus

    pub(all) enum MemberStatus {
    Active
    Retired
    } derive(Eq,
    Debug
    )

    Lifecycle state for one replica in a membership view.

    MembershipError

    pub(all) enum MembershipError {
    EmptyMemberReplica
    NonPositiveGeneration(String, Int)
    DuplicateMember(String)
    UnknownMember(String)
    } derive(Eq,
    Debug
    )

    Membership validation failures.

    MembershipView

    pub struct MembershipView {
    members : Array[ReplicaMember]
    } derive(Eq,
    Debug
    )

    membership changes and when a view becomes authoritative.

    MembershipView::active_replicas

    fn MembershipView::active_replicas(self : MembershipView) -> Array[String]

    Active replica identifiers required by a new StabilityTracker.

    MembershipView::from_members

    fn MembershipView::from_members(members : Array[ReplicaMember]) -> Result[MembershipView, MembershipError]

    Restore a validated view.

    MembershipView::is_active

    fn MembershipView::is_active(self : MembershipView, replica : String) -> Bool

    Whether a replica is active in this view.

    MembershipView::join

    fn MembershipView::join(self : MembershipView, replica : String) -> Result[MembershipView, MembershipError]

    Join a previously unseen replica at generation one.

    MembershipView::members

    Inspect all members, including retired identities.

    MembershipView::merge

    generation conflicts deterministically prefer Retired for safety.

    MembershipView::new

    Create an empty view.

    MembershipView::reactivate

    fn MembershipView::reactivate(self : MembershipView, replica : String) -> Result[MembershipView, MembershipError]

    Reactivate a retired replica identity with a new generation.

    MembershipView::record

    fn MembershipView::record(self : MembershipView, replica : String) -> ReplicaMember?

    Find one record.

    MembershipView::retire

    fn MembershipView::retire(self : MembershipView, replica : String) -> Result[MembershipView, MembershipError]

    Retire an active replica by advancing its generation.

    MembershipView::retired_replicas

    fn MembershipView::retired_replicas(self : MembershipView) -> Array[String]

    Retired identifiers retained to reject stale membership records.

    MembershipView::stability_tracker

    fn MembershipView::stability_tracker(self : MembershipView) -> Result[StabilityTracker, StabilityError]

    Build a stability tracker for the active membership.

    MultiValueRegister

    pub struct MultiValueRegister {
    values : Array[VersionedValue]
    } derive(
    Debug
    )

    a write that has observed them causally replaces them all.

    MultiValueRegister::apply

    value is causally equal or after it; concurrent values are both retained.

    MultiValueRegister::context

    write based on this context will dominate all values it has observed.

    MultiValueRegister::merge

    equal causal contexts do not create duplicates.

    MultiValueRegister::new

    Create an empty register.

    MultiValueRegister::resolved

    Return the only value when the register has converged to one write.

    MultiValueRegister::state

    application to inspect array lengths itself.

    MultiValueRegister::values

    concurrent update, not an arbitrary last-writer-wins decision.

    MultiValueRegister::write

    fn MultiValueRegister::write(self : MultiValueRegister, writer : String, value : String) -> Result[MultiValueRegister, RegisterError]

    and replica transport remain responsibilities of the caller.

    ObservedRemoveError

    pub(all) enum ObservedRemoveError {
    EmptySetReplica
    } derive(Eq,
    Debug
    )

    Mutation errors at the OR-Set boundary.

    ObservedRemoveSet

    pub struct ObservedRemoveSet {
    values : Array[ObservedValue]
    removals : DotSet
    context : VersionVector
    } derive(Eq,
    Debug
    )

    observe it; a remove records only dots visible in its local state.

    ObservedRemoveSet::add

    fn ObservedRemoveSet::add(self : ObservedRemoveSet, replica : String, value : String) -> Result[ObservedRemoveSet, ObservedRemoveError]

    Add a value with a fresh local dot.

    ObservedRemoveSet::compact

    fn ObservedRemoveSet::compact(self : ObservedRemoveSet, stable_frontier : VersionVector) -> ObservedRemoveSet

    stable frontier from StabilityTracker; an arbitrary vector is unsafe.

    ObservedRemoveSet::contains

    fn ObservedRemoveSet::contains(self : ObservedRemoveSet, value : String) -> Bool

    Test visible membership.

    ObservedRemoveSet::context

    Current causal context.

    ObservedRemoveSet::entries

    Visible value records and their live add dots.

    ObservedRemoveSet::merge

    unseen concurrent additions remain visible.

    ObservedRemoveSet::new

    Create an empty OR-Set.

    ObservedRemoveSet::removals

    Tombstones retained for state-based merge safety.

    ObservedRemoveSet::remove

    fn ObservedRemoveSet::remove(self : ObservedRemoveSet, value : String) -> ObservedRemoveSet

    Remove all add dots for a value that this replica has observed.

    ObservedRemoveSet::values

    fn ObservedRemoveSet::values(self : ObservedRemoveSet) -> Array[String]

    Render the set as distinct values.

    ObservedValue

    pub(all) struct ObservedValue {
    value : String
    additions : DotSet
    } derive(Eq,
    Debug
    )

    One visible value and the add dots that currently support it.

    OperationLog

    pub struct OperationLog {
    entries : Array[LoggedOperation]
    } derive(
    Debug
    )

    host application and reproducible in tests.

    OperationLog::append

    fn OperationLog::append(self : OperationLog, operations : Array[CausalOperation], applied_at : Int) -> OperationLog

    Append operations in their already-validated causal release order.

    OperationLog::compact

    that still need replay. The original log is unchanged.

    OperationLog::entries

    OperationLog::length

    fn OperationLog::length(self : OperationLog) -> Int

    OperationLog::new

    OperationLog::stable_prefix

    fn OperationLog::stable_prefix(self : OperationLog, frontier : VersionVector) -> Array[LoggedOperation]

    Return a checkpointable prefix whose operations are covered by frontier.

    PendingMessage

    pub(all) struct PendingMessage {
    source : String
    target : String
    payload : String
    sent_at : Int
    deliver_at : Int
    stamp : HlcTimestamp
    context : VersionVector
    } derive(
    Debug
    )

    A message that has been sent but not necessarily delivered.

    PnCounter

    pub struct PnCounter {
    components : Array[CounterComponent]
    } derive(Eq,
    Debug
    )

    component-wise maximum and therefore associative, commutative, idempotent.

    PnCounter::components

    fn PnCounter::components(self : PnCounter) -> Array[CounterComponent]

    Inspect normalized components.

    PnCounter::decrement

    fn PnCounter::decrement(self : PnCounter, replica : String) -> Result[PnCounter, CounterError]

    Decrement by one.

    PnCounter::decrement_by

    fn PnCounter::decrement_by(self : PnCounter, replica : String, amount : Int) -> Result[PnCounter, CounterError]

    Subtract a non-negative amount at one replica.

    PnCounter::delta_since

    fn PnCounter::delta_since(self : PnCounter, peer : PnCounter) -> PnCounter

    Components that contain information newer than a peer's state.

    PnCounter::from_components

    fn PnCounter::from_components(components : Array[CounterComponent]) -> Result[PnCounter, CounterError]

    Restore validated components, merging duplicates by component-wise max.

    PnCounter::increment

    fn PnCounter::increment(self : PnCounter, replica : String) -> Result[PnCounter, CounterError]

    Increment by one.

    PnCounter::increment_by

    fn PnCounter::increment_by(self : PnCounter, replica : String, amount : Int) -> Result[PnCounter, CounterError]

    Add a non-negative amount at one replica.

    PnCounter::is_included_in

    fn PnCounter::is_included_in(self : PnCounter, other : PnCounter) -> Bool

    True when every local component is less than or equal to the other state.

    PnCounter::merge

    fn PnCounter::merge(self : PnCounter, other : PnCounter) -> PnCounter

    Merge state using a component-wise maximum.

    PnCounter::negative_of

    fn PnCounter::negative_of(self : PnCounter, replica : String) -> Int

    Negative contribution made by one replica.

    PnCounter::new

    fn PnCounter::new() -> PnCounter

    Create a zero counter.

    PnCounter::positive_of

    fn PnCounter::positive_of(self : PnCounter, replica : String) -> Int

    Positive contribution made by one replica.

    PnCounter::value

    fn PnCounter::value(self : PnCounter) -> Int

    Current signed value.

    RegisterError

    pub(all) enum RegisterError {
    EmptyWriter
    } derive(Eq,
    Debug
    )

    Validation errors for register writes.

    RegisterState

    pub(all) enum RegisterState {
    Empty
    Resolved(VersionedValue)
    Conflict(Array[VersionedValue])
    } derive(
    Debug
    )

    conflict resolution.

    ReplicaAcknowledgement

    pub(all) struct ReplicaAcknowledgement {
    replica : String
    context : VersionVector
    } derive(
    Debug
    )

    One replica's acknowledgement of the causal history it has durably seen.

    ReplicaDigest

    pub(all) struct ReplicaDigest {
    replica : String
    frontier : VersionVector
    } derive(Eq,
    Debug
    )

    Summary exchanged before anti-entropy transfer.

    ReplicaDigest::new

    fn ReplicaDigest::new(replica : String, frontier : VersionVector) -> Result[ReplicaDigest, SyncError]

    Construct a digest for one replica.

    ReplicaMember

    pub(all) struct ReplicaMember {
    replica : String
    generation : Int
    status : MemberStatus
    } derive(Eq,
    Debug
    )

    One record record. Generations increase on each accepted state change.

    ReplicaState

    pub(all) struct ReplicaState {
    id : String
    clock : HlcClock
    vector : VersionVector
    online : Bool
    } derive(
    Debug
    )

    single-threaded and deterministic: callers control time with advance_to.

    ReplicationBatch

    pub(all) struct ReplicationBatch {
    source : String
    batch_id : String
    operations : Array[CausalOperation]
    advertised_frontier : VersionVector
    } derive(
    Debug
    )

    A transport-neutral batch of causal operations.

    ReplicationBatch::after

    Restrict the batch to operations not covered by a receiver frontier.

    ReplicationBatch::contains_id

    fn ReplicationBatch::contains_id(self : ReplicationBatch, operation_id : String) -> Bool

    Whether the batch contains a given operation identity.

    ReplicationBatch::deliver

    released order is always causally valid.

    ReplicationBatch::length

    fn ReplicationBatch::length(self : ReplicationBatch) -> Int

    Number of operations carried by the batch.

    ReplicationBatch::new

    fn ReplicationBatch::new(source : String, batch_id : String, operations : Array[CausalOperation], advertised_frontier : VersionVector) -> Result[ReplicationBatch, BatchError]

    Construct and validate a replication batch.

    ReplicationBatch::operations

    Return operations in transport order.

    Simulator

    pub(all) struct Simulator {
    time : Int
    replicas : Array[ReplicaState]
    pending : Array[PendingMessage]
    trace : Array[TraceEvent]
    } derive(
    Debug
    )

    teaching tool, not a production network stack.

    Simulator::advance_to

    fn Simulator::advance_to(self : Simulator, next_time : Int) -> Result[Array[TraceEvent], SimulatorError]

    recoverable network partition without inventing a separate transport API.

    Simulator::local_event

    fn Simulator::local_event(self : Simulator, replica_id : String, label : String) -> Result[TraceEvent, SimulatorError]

    accepting writes which could make a partition test misleading.

    Simulator::new

    fn Simulator::new(replica_ids : Array[String], start_time : Int) -> Result[Simulator, SimulatorError]

    Create a network of replica IDs. IDs must be nonempty and unique.

    Simulator::pending

    fn Simulator::pending(self : Simulator) -> Array[PendingMessage]

    or for the controlled clock to reach their delivery time.

    Simulator::replicas

    fn Simulator::replicas(self : Simulator) -> Array[ReplicaState]

    Return a snapshot of replica state for display or assertions.

    Simulator::send

    fn Simulator::send(self : Simulator, source : String, target : String, payload : String, delay : Int) -> Result[TraceEvent, SimulatorError]

    delayed until advance_to reaches deliver_at.

    Simulator::set_online

    fn Simulator::set_online(self : Simulator, replica_id : String, online : Bool) -> Result[TraceEvent, SimulatorError]

    transition itself is traced so a replay explains why a message was held.

    Simulator::time

    fn Simulator::time(self : Simulator) -> Int

    Return the simulator's caller-controlled physical time.

    Simulator::trace

    fn Simulator::trace(self : Simulator) -> Array[TraceEvent]

    Return the append-only event trace.

    Simulator::vector_of

    fn Simulator::vector_of(self : Simulator, replica_id : String) -> Result[VersionVector, SimulatorError]

    Look up a replica's current causal vector.

    SimulatorError

    pub(all) enum SimulatorError {
    EmptyReplicaId
    DuplicateReplica(String)
    UnknownReplica(String)
    ReplicaOffline(String)
    NegativeSimulationTime(Int)
    NegativeDelay(Int)
    TimeWentBackwards(current~ : Int, requested~ : Int)
    } derive(Eq,
    Debug
    )

    Errors exposed by simulator operations.

    StabilityError

    pub(all) enum StabilityError {
    EmptyReplicaId
    DuplicateReplica(String)
    UnknownReplica(String)
    } derive(Eq,
    Debug
    )

    Construction and update errors for acknowledgement tracking.

    StabilityTracker

    pub(all) struct StabilityTracker {
    replicas : Array[String]
    acknowledgements : Array[ReplicaAcknowledgement]
    } derive(
    Debug
    )

    A counter is stable only after every configured replica has acknowledged it.

    StabilityTracker::acknowledgements

    Return acknowledgements received so far.

    StabilityTracker::is_stable

    fn StabilityTracker::is_stable(self : StabilityTracker, context : VersionVector) -> Bool

    Check whether an event context is acknowledged by every member.

    StabilityTracker::new

    fn StabilityTracker::new(replicas : Array[String]) -> Result[StabilityTracker, StabilityError]

    Define the members whose acknowledgement is required for stability.

    StabilityTracker::observe

    fn StabilityTracker::observe(self : StabilityTracker, replica : String, context : VersionVector) -> Result[StabilityTracker, StabilityError]

    Record or replace one replica's latest acknowledgement.

    StabilityTracker::stable_frontier

    fn StabilityTracker::stable_frontier(self : StabilityTracker) -> VersionVector?

    unsafe. Missing counters are treated as zero.

    SyncError

    pub(all) enum SyncError {
    EmptyDigestReplica
    InvalidSyncRange(String, Int, Int)
    } derive(Eq,
    Debug
    )

    Validation failures for anti-entropy metadata.

    SyncRange

    pub(all) struct SyncRange {
    replica : String
    from_counter : Int
    to_counter : Int
    } derive(Eq,
    Debug
    )

    ends. Replica logs naturally map this range to dots.

    SyncRange::contains

    fn SyncRange::contains(self : SyncRange, dot : Dot) -> Bool

    Test whether a dot belongs to a requested range.

    SyncRange::length

    fn SyncRange::length(self : SyncRange) -> Int

    Number of dots represented by a range.

    SyncRange::new

    fn SyncRange::new(replica : String, from_counter : Int, to_counter : Int) -> Result[SyncRange, SyncError]

    Validate a range received from an untrusted peer.

    TimestampError

    pub(all) enum TimestampError {
    NegativePhysicalTime(Int)
    NegativeLogicalCounter(Int)
    EmptyNodeId
    } derive(Eq,
    Debug
    )

    Timestamp construction and decoding errors.

    TraceAnalysis

    pub struct TraceAnalysis {
    events : Array[TraceEvent]
    } derive(
    Debug
    )

    Validated, queryable causal trace analysis.

    TraceAnalysis::concurrent_pairs

    fn TraceAnalysis::concurrent_pairs(self : TraceAnalysis) -> Array[ConcurrentPair]

    sorting. Each pair appears once with the earlier trace position first.

    TraceAnalysis::direct_edges

    fn TraceAnalysis::direct_edges(self : TraceAnalysis) -> Array[CausalEdge]

    Return every directly inferred edge in deterministic trace order.

    TraceAnalysis::direct_predecessors

    fn TraceAnalysis::direct_predecessors(self : TraceAnalysis, sequence : Int) -> Array[CausalEdge]

    is omitted when another event b already proves a -> b -> c.

    TraceAnalysis::events

    Return the source events used to build this analysis.

    TraceAnalysis::layers

    after their actual send even if a physical clock is skewed.

    TraceAnalysis::new

    fn TraceAnalysis::new(events : Array[TraceEvent]) -> Result[TraceAnalysis, TraceError]

    from version vectors, not assumed from their wall-clock representation.

    TraceAnalysis::relation

    fn TraceAnalysis::relation(self : TraceAnalysis, first_sequence : Int, second_sequence : Int) -> CausalOrder?

    Read the causal relation between two event sequence numbers.

    TraceError

    pub(all) enum TraceError {
    DuplicateSequence(Int)
    NonPositiveSequence(Int)
    } derive(Eq,
    Debug
    )

    Trace construction errors.

    TraceEvent

    pub(all) struct TraceEvent {
    sequence : Int
    time : Int
    replica : String
    stamp : HlcTimestamp
    context : VersionVector
    kind : TraceKind
    } derive(
    Debug
    )

    event, while stamp is the HLC value used for stable total ordering.

    TraceKind

    pub(all) enum TraceKind {
    Local(label~ : String)
    Sent(target~ : String, payload~ : String)
    Received(source~ : String, payload~ : String)
    AvailabilityChanged(online~ : Bool)
    } derive(Eq,
    Debug
    )

    The kind of a trace event emitted by the deterministic simulator.

    TraceQuery

    pub(all) struct TraceQuery {
    analysis : TraceAnalysis
    } derive(
    Debug
    )

    Query facade for navigating a validated TraceAnalysis.

    TraceQuery::ancestors

    fn TraceQuery::ancestors(self : TraceQuery, sequence : Int) -> Array[TraceEvent]

    All strict causal ancestors of one event.

    TraceQuery::between_physical_times

    fn TraceQuery::between_physical_times(self : TraceQuery, from_time : Int, to_time : Int) -> Array[TraceEvent]

    Events whose HLC physical component lies in an inclusive interval.

    TraceQuery::by_replica

    fn TraceQuery::by_replica(self : TraceQuery, replica : String) -> Array[TraceEvent]

    Events produced by one replica, preserving trace order.

    TraceQuery::causal_slice

    fn TraceQuery::causal_slice(self : TraceQuery, sequence : Int) -> Array[TraceEvent]

    descendants. Concurrent events outside that cone are omitted.

    TraceQuery::concurrent_with

    fn TraceQuery::concurrent_with(self : TraceQuery, sequence : Int) -> Array[TraceEvent]

    Events concurrent with one selected event.

    TraceQuery::critical_path

    fn TraceQuery::critical_path(self : TraceQuery) -> CausalPath

    Longest causal path anywhere in the trace.

    TraceQuery::descendants

    fn TraceQuery::descendants(self : TraceQuery, sequence : Int) -> Array[TraceEvent]

    All strict causal descendants of one event.

    TraceQuery::leaves

    fn TraceQuery::leaves(self : TraceQuery) -> Array[TraceEvent]

    Events with no causal successors.

    TraceQuery::longest_path_to

    fn TraceQuery::longest_path_to(self : TraceQuery, sequence : Int) -> CausalPath

    Longest direct-edge path ending at a selected event.

    TraceQuery::new

    fn TraceQuery::new(analysis : TraceAnalysis) -> TraceQuery

    Create queries from an already validated analysis.

    TraceQuery::roots

    fn TraceQuery::roots(self : TraceQuery) -> Array[TraceEvent]

    Events with no causal predecessors.

    TraceQuery::summary

    fn TraceQuery::summary(self : TraceQuery) -> TraceSummary

    Aggregate metrics used by diagnostics and visualizers.

    TraceRow

    pub(all) struct TraceRow {
    sequence : Int
    replica : String
    physical : Int
    logical : Int
    kind : String
    detail : String
    } derive(Eq,
    Debug
    )

    A dependency-free, serialization-friendly trace row.

    TraceSummary

    pub(all) struct TraceSummary {
    event_count : Int
    direct_edge_count : Int
    concurrent_pair_count : Int
    layer_count : Int
    maximum_width : Int
    critical_path_length : Int
    } derive(Eq,
    Debug
    )

    Summary metrics for a causal trace.

    VectorDifference

    pub(all) struct VectorDifference {
    replica : String
    left_counter : Int
    right_counter : Int
    } derive(Eq,
    Debug
    )

    Per-replica difference between two causal frontiers.

    VectorEntry

    pub(all) struct VectorEntry {
    replica : String
    counter : Int
    } derive(Eq,
    Debug
    )

    One replica counter in a version vector.

    VectorError

    pub(all) enum VectorError {
    EmptyReplicaId
    NegativeCounter(String, Int)
    } derive(Eq,
    Debug
    )

    Errors at the version-vector trust boundary.

    VersionVector

    pub struct VersionVector {
    entries : Array[VectorEntry]
    } derive(Eq,
    Debug
    )

    Entries are kept in first-observed order to make traces deterministic.

    VersionVector::compare

    fn VersionVector::compare(self : VersionVector, other : VersionVector) -> CausalOrder

    other, so an application needs a merge policy instead of arbitrary ordering.

    VersionVector::counter

    fn VersionVector::counter(self : VersionVector, replica : String) -> Int

    Read a replica counter. Missing replicas have counter zero.

    VersionVector::entries

    Return a copy of the normalized entries for inspection or serialization.

    VersionVector::from_entries

    fn VersionVector::from_entries(entries : Array[VectorEntry]) -> Result[VersionVector, VectorError]

    duplicate entries by keeping their greatest counter.

    VersionVector::happens_before

    fn VersionVector::happens_before(self : VersionVector, other : VersionVector) -> Bool

    True when this vector is less than or equal to the other vector.

    VersionVector::increment

    fn VersionVector::increment(self : VersionVector, replica : String) -> Result[VersionVector, VectorError]

    Return a successor vector for one local event at replica.

    VersionVector::merge

    callers that receive a message should merge and then increment locally.

    VersionVector::new

    Create an empty vector.

    VersionedValue

    pub(all) struct VersionedValue {
    value : String
    writer : String
    context : VersionVector
    } derive(Eq,
    Debug
    )

    can encode domain records before passing them to the register.

    advance_checkpoint

    fn advance_checkpoint(previous : CausalCheckpoint, plan : CheckpointPlan) -> CausalCheckpoint

    Combine a previous checkpoint with an additional stable plan.

    common_frontier

    fn common_frontier(left : VersionVector, right : VersionVector) -> VersionVector

    Component-wise minimum, representing history known by both sides.

    concurrency_report_lines

    fn concurrency_report_lines(analysis : TraceAnalysis) -> Array[String]

    rendering dependency.

    edge_rows

    fn edge_rows(analysis : TraceAnalysis) -> Array[EdgeRow]

    Flatten direct causal edges for host serializers.

    events_missing_on_right

    fn events_missing_on_right(left : VersionVector, right : VersionVector) -> Int

    Number of events present on the left but absent on the right.

    layer_report_lines

    fn layer_report_lines(analysis : TraceAnalysis) -> Array[String]

    One line per topological layer.

    missing_sync_dots

    fn missing_sync_dots(entries : Array[LoggedOperation], ranges : Array[SyncRange]) -> DotSet

    Report gaps in a transferred batch relative to the requested ranges.

    operation_log_frontier

    fn operation_log_frontier(log : OperationLog) -> VersionVector

    Compute the greatest counters represented in a log.

    plan_checkpoint

    fn plan_checkpoint(log : OperationLog, stable_frontier : VersionVector, state : String, created_at : Int) -> Result[CheckpointPlan, CheckpointError]

    Build a checkpoint plan from a frontier already proven stable.

    plan_sync

    fn plan_sync(sender : VersionVector, receiver : VersionVector) -> Array[SyncRange]

    Compute ranges present at the sender and missing at the receiver.

    replay_after

    fn replay_after(checkpoint : CausalCheckpoint, log : OperationLog) -> Array[LoggedOperation]

    Select entries strictly after a checkpoint frontier.

    replicas_ahead

    fn replicas_ahead(left : VersionVector, right : VersionVector) -> Array[String]

    Replicas on which the left frontier is ahead.

    same_frontier

    fn same_frontier(left : VersionVector, right : VersionVector) -> Bool

    Whether two frontiers have exactly the same replica counters.

    select_sync_entries

    fn select_sync_entries(log : OperationLog, ranges : Array[SyncRange]) -> Array[LoggedOperation]

    original causal release order.

    sync_batch_frontier

    fn sync_batch_frontier(entries : Array[LoggedOperation]) -> VersionVector

    Summarize a batch as a frontier. Useful after applying a complete response.

    sync_operation_count

    fn sync_operation_count(ranges : Array[SyncRange]) -> Int

    Estimate transfer size as number of operations, without reading the log.

    trace_dot_lines

    fn trace_dot_lines(analysis : TraceAnalysis) -> Array[String]

    filesystem API on browser, native, and Wasm callers.

    trace_kind_detail

    fn trace_kind_detail(kind : TraceKind) -> String

    Human-readable payload carried by a trace kind.

    trace_kind_name

    fn trace_kind_name(kind : TraceKind) -> String

    Stable name for a trace event kind.

    trace_mermaid_lines

    fn trace_mermaid_lines(analysis : TraceAnalysis) -> Array[String]

    Mermaid flowchart lines for Markdown documentation and issue reports.

    trace_rows

    fn trace_rows(events : Array[TraceEvent]) -> Array[TraceRow]

    Convert trace events into flat rows suitable for CSV/JSON adapters.

    validate_checkpoint_against

    fn validate_checkpoint_against(checkpoint : CausalCheckpoint, log : OperationLog) -> Result[Unit, CheckpointError]

    Check that a checkpoint does not claim counters beyond the combined log.

    validate_replay

    fn validate_replay(checkpoint : CausalCheckpoint, entries : Array[LoggedOperation]) -> Result[VersionVector, CheckpointError]

    Validate that replay contains no per-replica gaps after the checkpoint.

    vector_differences

    fn vector_differences(left : VersionVector, right : VersionVector) -> Array[VectorDifference]

    Component differences, including replicas present on only one side.

    vector_distance

    fn vector_distance(left : VersionVector, right : VersionVector) -> Int

    Symmetric Manhattan distance between causal frontiers.