Skip to content

SuperInstance/simulation-ledger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Simulation Ledger

crates.io docs.rs License: MIT

Behavioral simulation with append-only ledger capture — simulate first, compile later, never break a verified behavior.


Inspired by Simulation-Driven Synthesis [2602.14690v4].

The Problem

When refining a specification or implementation, how do you know you haven't broken anything? Tests are post-hoc — they check after the change. But what if you could capture the entire behavioral history of your system as an immutable ledger, then replay it against any proposed change?

Why This Exists

Simulation Ledger provides:

  • Append-only behavioral ledger that captures every input/output pair
  • State mutations tracked atomically with each transaction
  • Ledger diffs that detect output drift and state divergence
  • Simulation runtime for step-by-step capture
  • Regression checking against historical baselines
  • Truncation with state rebuild for undoing mistakes

Architecture

  ┌───────────────┐     ┌───────────────┐
  │  Simulation   │────→│    Ledger     │
  │  Runtime      │     │  (append-only)│
  └───────────────┘     └───────┬───────┘
                                │
                    ┌───────────▼───────────┐
                    │    Ledger Diff        │
                    │  • output drifts      │
                    │  • state drifts       │
                    │  • matching count     │
                    └───────────┬───────────┘
                                │
                    ┌───────────▼───────────┐
                    │  Regression Check     │
                    │  historical vs proposed│
                    └───────────────────────┘

Installation

[dependencies]
simulation-ledger = { version = "0.1", features = ["serde"] }

API Reference

SimTransaction

An irreducible unit of behavioral capture:

use simulation_ledger::SimTransaction;
use std::collections::HashMap;

let tx = SimTransaction::new("GET /api/test", r#"{"status": 200}"#);
let tx_with_state = SimTransaction::with_mutations(
    "GET /api", "ok",
    HashMap::from([("counter".into(), "42".into())])
);

Ledger

Append-only behavioral ledger with state tracking:

use simulation_ledger::*;

let mut ledger = Ledger::new();
ledger.append(SimTransaction::new("event1", "output1"));
ledger.append(SimTransaction::new("event2", "output2"));

assert_eq!(ledger.len(), 2);
let state = ledger.state(); // current accumulated state

LedgerDiff

Compare two ledgers for behavioral drift:

use simulation_ledger::*;

let diff = LedgerDiff::compute(&original, &proposed);
if diff.is_clean() {
    println!("No drift detected");
} else {
    for drift in &diff.output_drifts {
        println!("Step {}: expected '{}', got '{}'",
            drift.index, drift.expected, drift.actual);
    }
}

SimulationRuntime

Step-by-step simulation capture:

use simulation_ledger::*;

let mut rt = SimulationRuntime::new("my_spec");
rt.simulate_step("GET /api/v1/test", r#"{"ok": true}"#);
rt.simulate_step("POST /api/v1/action", r#"{"done": true}"#);
assert_eq!(rt.step_count(), 2);

run_regression

Validate a proposed spec against historical behavior:

use simulation_ledger::*;

let report = run_regression(&historical, &proposed);
if report.passed() {
    println!("All {} assertions passed", report.passed);
} else {
    for failure in &report.failures {
        println!("FAIL at step {}: expected '{}', got '{}'",
            failure.index, failure.expected_output, failure.actual_output);
    }
}

Usage Examples

Example 1: Capture and Replay

use simulation_ledger::*;

let mut ledger = Ledger::new();
let mut m = HashMap::new();
m.insert("users".into(), "1".into());
ledger.append(SimTransaction::with_mutations("create_user", "ok", m));

let state = ledger.replay();
assert_eq!(state.get("users"), Some(&"1".into()));

Example 2: Detect Behavioral Drift

use simulation_ledger::*;

let mut original = Ledger::new();
original.append(SimTransaction::new("e1", "expected_output"));

let mut proposed = Ledger::new();
proposed.append(SimTransaction::new("e1", "drifted_output"));

let diff = LedgerDiff::compute(&original, &proposed);
assert!(!diff.is_clean());

Example 3: Truncation with State Rebuild

use simulation_ledger::*;

let mut ledger = Ledger::new();
// Add 5 transactions...
for i in 0..5 {
    ledger.append(SimTransaction::new(&format!("e{}", i), &format!("o{}", i)));
}

// Undo last 2 transactions
let invalidated = ledger.truncate_at(2);
assert_eq!(invalidated, 2);
assert_eq!(ledger.len(), 3);
// State is automatically rebuilt from remaining entries

Performance

Operation Complexity
Append O(M) where M = mutations
Replay O(N × M)
Diff O(min(N₁, N₂))
Truncate O(N) + state rebuild
Regression O(N)

License

Licensed under the MIT License.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Write tests
  4. Push and open a Pull Request

About

Append-only behavioral simulation ledger with replay and differential comparison

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages