# Changelog

All notable changes to Lockstep are recorded here.
Format follows [Keep a Changelog](https://keepachangelog.com/),
[SemVer](https://semver.org/) applies starting at 1.0.

## [0.1.0] — 2026-05-07

Initial public release.

### Engine

- User-level scheduler (`Lockstep.Controller`) that intercepts every
  sync point and decides which actor runs next.
- Four strategies: `:random`, `:pct`, `:fair_pct`, `:pos`. PCT is
  Burckhardt et al. ASPLOS'10. Fair-PCT is Coyote's hybrid. POS is
  Probabilistic Operating System scheduling — best for tight
  read-modify-write races.
- Iterative-deepening PCT (`:idpct`) for hard-to-find deep races.
- Reads-From Fuzzing (RFF) — coverage-guided exploration variant.

### Test surface

- `Lockstep.Test` — ExUnit case template with a `ctest/3` macro
  that runs the body N times under different schedules.
- `Lockstep.Runner.run/2` — programmatic API for non-ExUnit callers.
- `Lockstep.Linter` — flags bare `send`/`spawn`/`Process.send_after`
  in test bodies that should use `Lockstep.*` equivalents.

### OTP wrappers

Wrappers that route OTP traffic through the controller:

- `Lockstep.GenServer` — drop-in replacement for `GenServer`.
- `Lockstep.GenStatem` — drop-in for `:gen_statem`.
- `Lockstep.Agent`, `Lockstep.Task`, `Lockstep.Task.Supervisor`.
- `Lockstep.Registry`, `Lockstep.Supervisor`.
- `Lockstep.spawn/1`, `Lockstep.send/2`, `Lockstep.recv_first/1`,
  `Lockstep.send_after/3`, `Lockstep.cancel_timer/1`,
  `Lockstep.monitor/1`, `Lockstep.demonitor/2`.

### NIF / shared-state wrappers

Sync points so read-modify-write composition is interleavable:

- `Lockstep.ETS` — wraps `:ets.{insert, lookup, update_counter, ...}`.
- `Lockstep.Atomics` — wraps `:atomics`.
- `Lockstep.PersistentTerm` — wraps `:persistent_term`.

### Compile-time rewriters

- `Lockstep.Rewriter` — AST rewriter swapping `GenServer` →
  `Lockstep.GenServer` etc.
- `Lockstep.ErlangRewriter` — same, for `.erl` source.
- `Lockstep.MixCompiler` — drives `Path.wildcard` → preprocess →
  AST parse → rewrite → write. Use for testing third-party
  libraries.
- `Lockstep.MixCompiler.Preprocessors` — built-in source-string
  preprocessors:
  - `strip_compile_time_external_reads/2` — removes
    `@moduledoc File.read!(...)` blocks.
  - `strip_code_ensure_loaded/2` — comments out module-level
    `Code.ensure_loaded!`.
  - `unwrap_optional_dep_guards/2`,
    `inline_json_dispatch/2`,
    `inline_optional_module_list/2`,
    `preserve_aliased_module_names/2` — for handling common
    optional-dep gating patterns when rewriting third-party deps.

### Trace, replay, shrink

- `Lockstep.Trace` — recorded schedule format with a `LOCKSTEP\0`
  magic header and binary serialization.
- `Lockstep.Replay` — re-execute a saved trace deterministically.
- `Lockstep.Shrink` — minimize a counterexample via delta
  debugging.
- `mix lockstep.replay --trace <path>` — CLI helper.

### Property checking

- `Lockstep.Checker.Linearizable` — Knossos-style linearizability
  checker.
- `Lockstep.Checker.SequentialConsistency`.
- `Lockstep.Checker.Causal` — causal consistency.

### Cluster simulation

- `Lockstep.Cluster.start_nodes/1` — spawn N simulated nodes.
- `Lockstep.Cluster.partition/3` and `heal/0` — network
  partition / heal cycles.
- `Lockstep.Cluster.stop_node/1` and `start_node/1` — node
  crash / recovery.
- Cross-node `{name, node}` send routing through the controller.

### Causal slice + LLM explainer

- `Lockstep.CausalSlice` — backward-slice traces from the failing
  step using a happens-before graph.
- `Lockstep.LLMExplainer` — optional Anthropic Claude integration
  for explaining counterexamples.

### What's NOT shipped (yet)

- Hot code reloading (no plans).
- Distributed-Erlang test cluster scaffolding (use the in-process
  `Lockstep.Cluster` instead).
- True formal verification — Lockstep is bug-finding +
  reproducibility, not proof.
- Stable wire protocol for trace files — format may change in
  0.x.

[0.1.0]: https://github.com/b-erdem/lockstep/releases/tag/v0.1.0
