# Lockstep v0.1.0 - Table of Contents

Coyote-style controlled concurrency testing for the BEAM. PCT/POS scheduling, schedule shrinking, trace replay, Elixir + Erlang AST rewriters, and ETS / atomics / persistent_term sync points -- so message-passing AND shared-state races surface deterministically.

## Pages

- [Lockstep](readme.md)
- [Changelog](changelog.md)
- [Contributing to Lockstep](contributing.md)
- [Using Lockstep from AI agents](agents.md)
- [Lockstep testing methodology — the playbook](methodology.md)
- [Skill (Anthropic)](skill.md)
- [MCP Server](mcp_server.md)

## Modules

- [Lockstep.CausalSlice](Lockstep.CausalSlice.md): Backward-slice a trace to the events causally relevant to a given
failing step.
- [Lockstep.Checker.Causal](Lockstep.Checker.Causal.md): Per-process causal consistency check for register-shaped models.
- [Lockstep.Checker.Linearizable](Lockstep.Checker.Linearizable.md): Decide whether a `Lockstep.History` is linearizable with respect
to a given `Lockstep.Model`.
- [Lockstep.Checker.Linearizable.Op](Lockstep.Checker.Linearizable.Op.md): A paired (`:invoke`, `:complete`) operation. `complete` is `nil`
if the operation is still pending.

- [Lockstep.Checker.SequentialConsistency](Lockstep.Checker.SequentialConsistency.md): Decide whether a `Lockstep.History` is **sequentially consistent**
with respect to a `Lockstep.Model`.
- [Lockstep.Cluster](Lockstep.Cluster.md): Multi-node simulation under Lockstep's controller.
- [Lockstep.Generator](Lockstep.Generator.md): Deterministic, seeded streams of operations for Jepsen-style
workloads.
- [Lockstep.Global](Lockstep.Global.md): Cluster-wide name registry, mirror of Erlang's `:global`.
- [Lockstep.History](Lockstep.History.md): Jepsen-style operation history recorder.
- [Lockstep.History.Event](Lockstep.History.Event.md): One event in the history. Multiple events combine to describe an
operation: an `:invoke` plus a matching `:ok` / `:fail` / `:info`
on the same process.

- [Lockstep.LLMExplainer](Lockstep.LLMExplainer.md): Optional Anthropic Claude integration: explains a Lockstep
concurrency bug in plain English and suggests a fix.
- [Lockstep.MixCompiler.Preprocessors](Lockstep.MixCompiler.Preprocessors.md): Built-in source-string preprocessors for `Lockstep.MixCompiler.compile/1`.
- [Lockstep.Model](Lockstep.Model.md): A specification of correct sequential behavior for a system under
test. Consistency checkers (`Lockstep.Checker.Linearizable`,
`Lockstep.Checker.SequentialConsistency`) consult a Model to
decide whether a candidate serial order of operations is valid.
- [Lockstep.Model.Register](Lockstep.Model.Register.md): Single-cell register model: read, write, and compare-and-swap.
- [Lockstep.NativeRunner](Lockstep.NativeRunner.md): **Experimental, observational only.** Drive *unmodified* OTP code
under a Lockstep-style runner using `:erlang.trace/3` and
`:erlang.suspend_process/1`. The intent was full PCT-style
scheduling control over arbitrary OTP code; in practice
`:erlang.trace` is observational, not interventional, and this
module *does not* reliably force interesting interleavings.
- [Lockstep.Process](Lockstep.Process.md): Controller-aware wrappers for `Process.whereis/1`, `Process.register/2`,
`Process.unregister/1`, and `Process.registered/0`.
- [Lockstep.RFF](Lockstep.RFF.md): **Reads-From Fuzzing** — coverage-guided concurrency exploration.
- [Lockstep.RPC](Lockstep.RPC.md): Mirror of Erlang's `:rpc` module under Lockstep's controlled
scheduling. Cross-node `apply/4`-style calls are modeled by
spawning a process on the target node, having it execute the
function, and shipping the result back to the caller via a
Lockstep-controlled message.
- [Lockstep.Strategy.IDPCT](Lockstep.Strategy.IDPCT.md): Iterative-Deepening PCT.

- Runtime API
  - [Lockstep](Lockstep.md): Coyote-style controlled concurrency testing for BEAM.

- OTP wrappers
  - [Lockstep.Agent](Lockstep.Agent.md): Controller-aware `Agent` -- mirrors the OTP `Agent` API but every
`get`/`update`/`cast`/`get_and_update` is a `Lockstep.GenServer.call`
(or `cast`) and therefore a sync point.
  - [Lockstep.GenServer](Lockstep.GenServer.md): GenServer-shaped wrapper that runs under Lockstep's controller.
  - [Lockstep.GenStatem](Lockstep.GenStatem.md): Minimal `:gen_statem`-shaped wrapper that runs under Lockstep's
controller. Supports the `handle_event_function` callback mode -- one
`handle_event/4` clause per `(event_type, event_content, state, data)`
combination -- which is the pattern most modern Elixir code uses.
  - [Lockstep.Registry](Lockstep.Registry.md): Lockstep-aware process registry. Models the most common subset of
OTP `Registry` under Lockstep's controller, so libraries that depend
on key-based process lookup work under controlled scheduling.
  - [Lockstep.Supervisor](Lockstep.Supervisor.md): A `:one_for_one` supervisor that runs under Lockstep's controller.
Builds on `Lockstep.spawn_link/1` + `Lockstep.flag(:trap_exit, true)`
so child crashes are observed via `{:EXIT, child, reason}` and
restarts can be issued in-band with the rest of the test schedule.
  - [Lockstep.Task](Lockstep.Task.md): Lockstep-controlled `Task.async` / `Task.await` / `async_stream` style helper.
  - [Lockstep.Task.Supervisor](Lockstep.Task.Supervisor.md): Lockstep-aware `Task.Supervisor` shim. Each `async/start_child`
call spawns a managed Lockstep process; supervisor restart
semantics aren't modeled (use `Lockstep.Supervisor` for that).

- NIF wrappers
  - [Lockstep.Atomics](Lockstep.Atomics.md): Controller-aware wrappers around `:atomics`.
  - [Lockstep.ETS](Lockstep.ETS.md): Controller-aware wrappers around the most-used `:ets` operations.
  - [Lockstep.PersistentTerm](Lockstep.PersistentTerm.md): Controller-aware wrappers around `:persistent_term`.

- Test ergonomics
  - [Lockstep.Linter](Lockstep.Linter.md): Compile-time AST scanner that warns when a `ctest` body uses operations
that aren't routed through Lockstep's controller. Bare `send`, bare
`receive`, `Process.send_after`, `GenServer.call`, `Task.async`, and
similar will silently break the controlled schedule -- better to warn
at compile time than have the user wonder why nothing reproduces.
  - [Lockstep.Test](Lockstep.Test.md): ExUnit case template for controlled concurrency tests.

- Compile-time rewriters
  - [Lockstep.ErlangRewriter](Lockstep.ErlangRewriter.md): Rewrites Erlang source (`.erl`) so that vanilla OTP calls
(`gen_server:call`, `erlang:spawn`, `Pid ! Msg`, bare `receive`)
go through Lockstep's controller. Mirrors `Lockstep.Rewriter` but
on Erlang's abstract format instead of Elixir's macro AST.
  - [Lockstep.MixCompiler](Lockstep.MixCompiler.md): Core file-rewriting logic for the `:lockstep_rewrite` Mix compiler.
Reads source files, runs them through `Lockstep.Rewriter`, and writes
the rewritten output to a build directory.
  - [Lockstep.Rewriter](Lockstep.Rewriter.md): Compile-time AST rewriter that converts vanilla OTP calls into their
`Lockstep.*` equivalents inside a `ctest` body. Lets test bodies
read like ordinary Elixir without sacrificing controlled scheduling.

- Engine internals
  - [Lockstep.Controller](Lockstep.Controller.md): The scheduler. A `GenServer` that intercepts every Lockstep sync point
and picks the next process to run per the configured strategy.
  - [Lockstep.Runner](Lockstep.Runner.md): Runs a controlled test body N times. On bug: saves the trace and
raises `Lockstep.BugFound` with a formatted schedule.

  - [Lockstep.Strategy](Lockstep.Strategy.md): Behaviour for scheduling strategies.

- Strategies
  - [Lockstep.Strategy.FairPCT](Lockstep.Strategy.FairPCT.md): PCT for the first `K` steps, then uniform random walk.
  - [Lockstep.Strategy.PCT](Lockstep.Strategy.PCT.md): Probabilistic Concurrency Testing.
  - [Lockstep.Strategy.POS](Lockstep.Strategy.POS.md): POS (Partial-Order Sampling). On every step, with probability
`:resample_prob`, re-randomize the priorities of all currently-ready
processes; otherwise keep the current priorities. Then run the
highest-priority enabled process.
  - [Lockstep.Strategy.Random](Lockstep.Strategy.Random.md): Uniform random over the ready set. Cheap, fair, the default baseline.

  - [Lockstep.Strategy.Replay](Lockstep.Strategy.Replay.md): Re-runs the schedule recorded in a saved trace.

- Trace + replay + shrink
  - [Lockstep.Replay](Lockstep.Replay.md): Re-run a test body deterministically from a saved Lockstep trace.
  - [Lockstep.Shrink](Lockstep.Shrink.md): Reduce a failing schedule to a minimal one that still triggers the
same bug, deterministically.
  - [Lockstep.Trace](Lockstep.Trace.md): Recorded schedule. A trace is the sequence of decisions the controller
made during a test iteration.

- Errors
  - [Lockstep.BugFound](Lockstep.BugFound.md): Raised when a controlled-concurrency iteration finds a bug. The
message includes the iteration number, seed, formatted schedule, and a
command for replaying the bug.

  - [Lockstep.ReplayDivergence](Lockstep.ReplayDivergence.md): Raised by `Lockstep.Replay.run/2` when the replayed schedule cannot be
faithfully reproduced from the recorded trace. Almost always means the
user code under test depends on uncontrolled nondeterminism — raw RNG,
system time, ETS interleavings inside non-yielding handlers, NIFs, or
real I/O.

## Mix Tasks

- [mix compile.lockstep_rewrite](Mix.Tasks.Compile.LockstepRewrite.md): Mix compiler that rewrites source files via `Lockstep.Rewriter`
before the standard Elixir compiler runs.
- [mix lockstep.dump_trace](Mix.Tasks.Lockstep.DumpTrace.md): Dump a saved Lockstep trace as a raw Elixir term. Useful for grepping or
feeding into another tool.
- [mix lockstep.replay](Mix.Tasks.Lockstep.Replay.md): Print a saved Lockstep trace as a human-readable schedule, or re-run
a specific test function under the recorded schedule.
- [mix lockstep.shrink](Mix.Tasks.Lockstep.Shrink.md): Reduce a failing Lockstep trace to a minimal schedule that still
triggers the same bug.

