Skip to content

Development Workflow

This page is the practical loop: build, run, test, and the conventions your PR has to satisfy before it merges. Commands here are the same ones CI runs (see .github/workflows/ci-checks.yml).

The toolchain is pinned in rust-toolchain.toml (stable Rust). To build and run example apps you also need the WASM target:

Terminal window
rustup target add wasm32-unknown-unknown
Terminal window
# Build the whole workspace (debug)
cargo build
# Release build
cargo build --release
# Typecheck without producing artifacts
cargo check --workspace

Building the example WASM apps is a separate step (apps compile to wasm32-unknown-unknown):

Terminal window
# Build one app; `cargo mero` embeds the ABI a bare `cargo build` leaves out
PATH="$(scripts/setup-cargo-mero.sh):$PATH"
cargo mero build --manifest-path apps/kv-store/Cargo.toml
# Build all example apps
./scripts/build-all-apps.sh

merod is the node daemon; each node is initialized once, then run. To bring up two nodes that talk to each other:

  1. Initialize and run the first node. init defaults to --auth-mode proxy, which authenticates no caller, so any page served from localhost can reach the admin API. Use it only on a development machine:

    Terminal window
    merod --node node1 init --server-port 2428 --swarm-port 2528 --mdns
    merod --node node1 run
  2. Initialize the second node so it can find the first:

    Terminal window
    merod --node node2 init --server-port 2429 --swarm-port 2529 --mdns
    merod --node node2 run

    --mdns is on both, and it is load-bearing rather than tidy-up. mDNS is off by default, and two nodes with no bootstrap peer and no rendezvous have no other way to find each other. Leaving it off does not fail cleanly: the nodes start, the join is accepted locally, and it then times out waiting for a group key — so it reads as a broken join rather than as two nodes that never met.

    To point the second node at the first explicitly instead, you need node1’s peer id — a bare /ip4/…/tcp/… is rejected at startup with “Failed to parse peer id from addr”:

    Terminal window
    # with node1 running
    curl -s localhost:2428/admin-api/network/status | jq -r .localPeerId
    merod --node node2 init --server-port 2429 --swarm-port 2529 \
    --boot-nodes /ip4/127.0.0.1/tcp/2528/p2p/<node1-peer-id>
    merod --node node2 run
  3. Drive nodes from the CLI with meroctl, or turn up logging with RUST_LOG:

    Terminal window
    RUST_LOG=debug merod --node node1 run
Terminal window
# Run the full workspace test suite
cargo test
# CI runs with output shown
cargo test -- --nocapture

Run every check CI’s required Rust status waits on, read straight from .github/workflows/ci-checks.yml so the list cannot drift:

Terminal window
./scripts/check-like-ci.py # all of it
./scripts/check-like-ci.py --list # what it runs, in order
./scripts/check-like-ci.py --only clippy # a subset, by name

The rest of the Definition of Done (proof for a bug fix, docs, review) is in the root AGENTS.md.

Commit subjects and PR titles follow the commit rule in the coding standards.

For pull requests:

  • The project uses a fork-and-pull workflow; base your PR on the master branch.
  • A PR should focus on either functionality or style, not both.
  • PRs must follow the template, with Description, Test plan, and Documentation update sections, and link any related issue.
  • Maintainers squash-and-merge approved PRs; resolve each review conversation as you address it.

The imports, module layout, error handling, dead-code and trust-boundary rules are in CODING_STANDARDS.md.

Location What’s there
docs/ The Astro Starlight documentation site (this site) — all authored docs.
AGENTS.md (root + per-package) Quick orientation for each area of the tree; a good first read for any crate.
CODING_STANDARDS.md How code in the repository is written.