# Contributing to Lockstep
Thanks for your interest. Lockstep is at v0.1.0 and looking for
real-world feedback. Here's how to contribute.
## Quick links
- **Bug reports**: open an issue with a minimal Lockstep test that
demonstrates the problem and the strategy + seed it was found with.
- **Feature requests**: open an issue describing the use case before
writing code.
- **Pull requests**: small + focused beats large + sweeping. Tests
required.
## Development setup
```sh
git clone https://github.com/b-erdem/lockstep
cd lockstep
mix deps.get
mix test
```
Core tests run on a fresh clone with no external setup. Some
integration tests against external libraries (HyParView, DeltaCrdt,
Phoenix.PubSub, Horde, GenStage, etc.) require those libraries to
be cloned to specific paths — those tests skip cleanly if the paths
don't exist. See `test/erlang_pg_test.exs` for an example of the
skip pattern.
## Filing a bug
Lockstep test that reproduces the issue is the gold standard:
```elixir
defmodule MyBugTest do
use Lockstep.Test
ctest "minimal repro" do
# ...
end
end
```
Run it with:
```sh
mix test path/to/test.exs --seed 1
```
Include in your issue:
- Full Lockstep version (`mix deps`)
- Strategy + seed that triggers the bug
- The trace file (in `traces/`) if Lockstep saved one
- The Erlang/Elixir version
## Adding a strategy
Lockstep's strategies live in `lib/lockstep/strategy/`. Each
implements the `Lockstep.Strategy` behaviour. See
`lib/lockstep/strategy/random.ex` as the simplest example. Tests go
in `test/strategy_*_test.exs`.
## Adding an OTP wrapper
If you find an OTP primitive that Lockstep doesn't intercept yet,
the wrapper pattern is:
1. Add a module under `lib/lockstep/<primitive>.ex`.
2. Each public function calls `Lockstep.Controller.nif_sync/3` (or
the appropriate sync-point function) before doing the actual
work.
3. Add a clause to `Lockstep.Rewriter` so source code using the
primitive is rewritten.
4. Tests in `test/<primitive>_*_test.exs`.
## Running the full test suite
Lockstep uses external libraries to validate its rewriter against
real-world code. To run the full integration suite:
```sh
# Clone the libraries Lockstep tests against:
mkdir -p /tmp && cd /tmp
git clone https://github.com/derekkraan/delta_crdt_ex
git clone https://github.com/derekkraan/merkle_map
git clone https://github.com/derekkraan/horde horde_src
git clone https://github.com/bitwalker/libring
git clone https://github.com/keathley/groot
git clone https://github.com/sasa1977/con_cache concache_src
git clone https://github.com/phoenixframework/phoenix_pubsub phoenix_pubsub_src
git clone https://github.com/dashbitco/nimble_pool
git clone https://github.com/beam-telemetry/telemetry
git clone https://github.com/toniqsystems/hlclock
# Then back to the lockstep repo:
cd /path/to/lockstep
mix test
```
Tests skip cleanly when their target source isn't on disk, so you
can run a partial set.
## Code style
- `mix format` before commit.
- Clear module-level `@moduledoc` explaining what + why.
- Function-level `@doc` for public API.
- Tests describe the bug shape they're hunting for (see existing
tests' moduledocs).
## Hands-on engagement
If you want to apply Lockstep to a production BEAM system —
concurrency audit, custom test scaffolding, multi-node race-hunting
harness, or hardening on retainer — that's something I do directly.
Reach out: **[baris@erdem.dev](mailto:baris@erdem.dev)**.
## License
Apache 2.0. By contributing, you agree your contributions will be
licensed under the same.