Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Contributing to Crucible Simulator

Thanks for contributing! Crucible is a deterministic testing foundation, so its quality bar is exactness: every behavior change must come with tests that pin it down.

Getting started

cargo build --workspace
cargo test  --workspace
cargo clippy --workspace --all-targets   # must be warning-free
cargo fmt    --check

The workspace must stay clippy- and fmt-clean; CI enforces it.

Where things live

AreaCrateNotes
Domain modelcrates/coreNo engine dependencies
State enginecrates/stateStore, commitments, nullifiers, transitions, rollback, snapshots
Flowscrates/flowsFive lifecycle flows + validation + ProofProvider
High-level APIcrates/simulatorConfiguration / Environment / Simulator
Fixtures & suitescrates/fixturesVersioned fixtures + the integration/determinism/invariant/regression suites

Dependency direction is strictly core → state → flows → simulator → fixtures.

Ground rules

  1. Determinism is sacred. Never introduce system entropy, wall-clock reads, Hash* state collections, or float math into simulation logic. Randomness flows only through DeterministicRng.
  2. Never silently mutate state. Every applied change goes through the flow pipeline and ends in a recorded, audited StateTransition.
  3. Failed operations must leave no trace. Apply inside TransactionScope; on error, state (including sequence counters) must be bit-identical.
  4. Privacy boundary. Observable output (events, published records) never contains amounts or commitment values. Private values are only reachable through explicitly labeled inspection APIs.
  5. One behavior change, one focused commit, with a message explaining the why. Do not bundle unrelated improvements.
  6. Every bug becomes a fixture. Found a bug? Write the failing test first (crates/fixtures/tests/regression.rs), fix, and — when the bug is reproducible from outside the code — add a failure fixture under fixtures/scenarios/failures/ so it can never return silently.

Scoping your change

This repository is the root of a three-repository system: crucible-prover and crucible-scenarios both compile it, each at a revision pinned in their own manifests. Two consequences follow, and they point in opposite directions.

  • A change here cannot break a consumer. They build the pinned revision, not your branch, so their CI stays green while your change lands. You do not need to coordinate a release to land work in this repository.
  • A change to a published contract blocks the next pin bump. If you alter a signature, a serialized shape, or a state/event semantic that a consumer depends on, that consumer cannot move to your revision until it adapts. Scope such work as two issues — the change here, and a separate follow-up to bump the pin and adapt — never as one PR spanning repositories. A pull request that requires edits in two repositories cannot be reviewed, tested, or reverted as a unit.

See docs/cross-repo-pinning.md for the pinned set and the bump procedure.

Testing

cargo test --workspace                        # everything
cargo test -p crucible-fixtures --test full_lifecycle   # the MVP flow
cargo test -p crucible-fixtures --test determinism      # the defining property
cargo test -p crucible-fixtures --test invariants       # conservation & friends
cargo test -p crucible-fixtures --test regression       # pinned bugs

Fixture corpus changes must keep loader::tests::repository_fixtures_load_and_all_scenarios_replay green — every checked-in scenario must replay.

Review checklist

  • Determinism preserved (see docs/deterministic-execution.md)
  • Atomicity preserved (rollback on failure)
  • Observable output stays value-free
  • Tests added or updated; full workspace green
  • cargo clippy --workspace --all-targets warning-free
  • cargo fmt clean
  • No unrelated changes bundled