.RECIPEPREFIX := >
CARGO ?= cargo
PYTHON ?= python3
LAKE ?= lake
LEAN_SPEC_DIR ?= ../lazily-spec/formal/lean
LEAN_FORMAL_DIR ?= ../lazily-formal
.PHONY: \
check \
fmt \
clippy \
build \
build-ffi \
ffi-headers \
test \
test-thread-safe \
test-tokio \
test-async \
test-async-resolve \
test-loom \
test-distributed \
test-ffi \
test-ffi-binary \
test-ipc \
test-ipc-binary \
test-ipc-conformance \
test-reliable-sync-conformance \
test-collections-conformance \
test-collections-family-conformance \
test-queue-conformance \
test-queue-demand-driven \
test-seqcrdt-conformance \
test-lossless-tree \
test-schema-compliance \
test-statechart-conformance \
test-shm \
test-lean-formal \
test-lazily-formal \
test-signaling-client \
test-webrtc \
test-websocket \
benchmark-check \
benchmark-update \
instrumentation-profile
check: fmt clippy build test test-thread-safe test-tokio test-async test-async-resolve test-loom test-distributed test-crdt-plane test-ffi test-ffi-binary test-ipc test-ipc-binary test-ipc-conformance test-reliable-sync-conformance test-shm test-collections-conformance test-collections-family-conformance test-queue-conformance test-queue-demand-driven test-seqcrdt-conformance test-lossless-tree test-schema-compliance test-statechart-conformance test-lean-formal test-lazily-formal test-signaling-client test-webrtc test-webrtc-signaling test-websocket benchmark-check
fmt:
>$(CARGO) fmt --all --check
clippy:
>$(CARGO) clippy --locked --all-targets --all-features -- -D warnings
build:
>$(CARGO) build --locked --all-targets --all-features
build-ffi:
>$(CARGO) build --locked --features ffi
ffi-headers: build-ffi
>cbindgen --config cbindgen.toml --crate lazily -o target/lazily.h
test:
>$(CARGO) test --locked
# ThreadSafeContext + ThreadSafeStateMachine (feature-gated behind `thread-safe`
# since v0.18.0; lazily-spec requires this layer conditionally — see
# protocol.md § "Concurrency layers are required").
test-thread-safe:
>$(CARGO) test --locked --features thread-safe
# tokio_sync.rs + benches/tokio_sync.rs require BOTH tokio and thread-safe.
test-tokio:
>$(CARGO) test --locked --features "tokio thread-safe"
test-async:
>$(CARGO) test --locked --features async
# Deterministic #k03k resolve-loop window coverage needs the instrumentation
# seam (window 1) alongside the async feature; test-async alone compiles it out.
test-async-resolve:
>$(CARGO) test --locked --features "async instrumentation" --test async_resolve_loop
# Phase-0 demand-driven reader-kind + store-without-cascade acceptance
# (relaycell-backpressure-analysis.md §5/§4.0): asserts the merge cost law via
# instrumentation counters — unobserved ops derive nothing, bursts coalesce.
test-queue-demand-driven:
>$(CARGO) test --locked --features instrumentation --test queue_demand_driven
test-loom:
>$(CARGO) test --locked --features loom --test thread_safe_loom
test-distributed:
>$(CARGO) test --locked --features "distributed serde"
# Distributed CRDT plane runtime integration (#lzcrdtplane5b): the
# CrdtPlaneRuntime glue + the end-to-end two-replica-over-transport convergence
# test need BOTH the plane primitives (`distributed`) and the wire + in-memory
# DataChannel transport (`webrtc`), a combo no other target exercises.
test-crdt-plane:
>$(CARGO) test --locked --features "distributed webrtc"
test-ffi:
>$(CARGO) test --locked --features ffi --test ffi
test-ffi-binary:
>$(CARGO) test --locked --features "ffi ipc-binary" --test ffi
test-ipc:
>$(CARGO) test --locked --features ffi --test ipc
test-ipc-binary:
>$(CARGO) test --locked --features ipc-binary --test ipc
test-ipc-conformance:
>$(CARGO) test --locked --features ipc --test conformance
# Reliable sync (#lzsync): ResyncCoordinator / DurableOutbox / OR-set-LWW
# liveness + the ResyncRequest/OutboxAck control-frame codec round-trip. Replays
# ../lazily-spec/conformance/reliable-sync/ (msgpack pin needs ipc-msgpack).
test-reliable-sync-conformance:
>$(CARGO) test --locked --features ipc,ipc-msgpack --test reliable_sync_conformance
>$(CARGO) test --locked --features ipc,ipc-msgpack --lib reliable_sync::
# Cross-process zero-copy transport (#lzzcpy): BlobBackend trait +
# InProcessBackend / ArrowBackend + POSIX ShmBackend (shm feature). The lib
# unit tests cover spill/resolve/router + the shm fork() cross-process smoke.
test-shm:
>$(CARGO) test --locked --features ipc,shm --lib transport::
# Keyed cell collections conformance (#lzcellfamily / #lzkeyrecon): lazily-rs
# replays the canonical compute fixtures in lazily-spec/conformance/collections/
# — value / set-membership / order reactivity independence, atomic ordered move
# (handle_stable), and LIS move-minimized reconciliation. Required of every
# binding (see the Binding Conformance Matrix). Collections are unconditional, so
# this target needs no feature flags.
test-collections-conformance:
>$(CARGO) test --locked --test collections_conformance
# The SAME ordering contract replayed against ALL THREE flavors. It needs BOTH
# `thread-safe` and `async` (plus tokio), so no partial-feature target compiles
# it: under the default features, `--features thread-safe`, or `--features async`
# alone, `cargo test --test collections_family_conformance` reports
# "running 0 tests" and exits 0. A gate that silently runs nothing is the exact
# failure this suite exists to prevent, so it gets its own all-features target
# rather than riding on someone else's feature set.
test-collections-family-conformance:
>$(CARGO) test --locked --all-features --test collections_family_conformance
# Reactive queue conformance (#lzqueue): lazily-rs replays the canonical compute
# fixtures in lazily-spec/conformance/collections/ `queuecell_*.json` — SPSC
# total FIFO, popped-head observation (reader-kind independence), MPSC
# multi-writer inside batch(), bounded reactive backpressure (is_full), and the
# closure lifecycle. Required of every binding (see the Binding Conformance
# Matrix). The `serde` feature is enabled for the VecDequeStorage wire-shape test.
test-queue-conformance:
>$(CARGO) test --locked --features serde --test queue_conformance
# Move-aware sequence CRDT conformance (#lzseqcrdt): lazily-rs replays the
# canonical compute fixture in lazily-spec/conformance/collections/
# `seqcrdt_convergence.json` — concurrent-insert convergence, single-LWW move
# (no duplication), concurrent move + value-edit independence, tombstone
# convergence + commutative merge. SeqCrdt is feature-gated behind `distributed`
# (the CRDT plane), so this target needs that feature.
test-seqcrdt-conformance:
>$(CARGO) test --locked --features distributed --test seqcrdt_conformance
# Lossless full-document tree CRDT (#lzlosstree): M1 syntax-agnostic core. Replays
# the shared compute fixtures in lazily-spec/conformance/lossless-tree/ (exact
# round-trip, one-leaf edit delta, split/merge, concurrent insert, concurrent
# reorder + edit, non-contiguous anti-entropy, token/trivia preservation, invalid
# source round-trip, structural-conflict text preservation) plus randomized
# convergence property tests, plus schema compliance of the `TreeUpdate` /
# frontier serde output against lazily-spec's lossless-tree schemas (needs
# `serde`). Feature-gated behind `lossless-tree` (which implies `distributed`).
test-lossless-tree:
>$(CARGO) test --locked --features "lossless-tree serde" --test lossless_tree_conformance --test lossless_tree_proptest --test lossless_tree_schema
# JSON Schema compliance: lazily-rs's own serde output (Snapshot/Delta/CrdtSync,
# incl. NodeKey) validates against the sibling lazily-spec/schemas, and every IPC
# conformance fixture's `wire` is schema-valid. Closes the binding<->schema loop.
test-schema-compliance:
>$(CARGO) test --locked --features ipc --test schema_compliance
test-statechart-conformance:
>$(CARGO) test --locked --features statechart-json --test statechart_conformance
test-lean-formal:
>test -d "$(LEAN_SPEC_DIR)" || { echo "missing $(LEAN_SPEC_DIR); clone lazily-spec as a sibling or set LEAN_SPEC_DIR"; exit 1; }
>cd "$(LEAN_SPEC_DIR)" && $(LAKE) build
# Build the full Harel state-chart formal model + the new universal proofs
# (parallel_region_confluence, single_region_refines_flat_machine) in
# lazily-formal — the neutral formal-artifact home every binding depends on.
test-lazily-formal:
>test -d "$(LEAN_FORMAL_DIR)" || { echo "missing $(LEAN_FORMAL_DIR); clone lazily-formal as a sibling or set LEAN_FORMAL_DIR"; exit 1; }
>cd "$(LEAN_FORMAL_DIR)" && $(LAKE) build
test-signaling-client:
>$(CARGO) test --locked --features signaling-client
# WebRTC DataChannel transport (#webrtc2/#webrtc3) + concrete str0m backends:
# the deterministic in-memory/synthetic-clock loopback (#webrtcbackend) plus the
# networked Str0mNet backend (#lzwebrtcnet), whose test does a real two-socket
# round trip over 127.0.0.1 (real UDP/DTLS/SCTP/timers).
test-webrtc:
>$(CARGO) test --locked --features webrtc-str0m
# Full WebRTC handshake driven THROUGH SignalingClient over a loopback signaling
# relay (#lzwebrtcwire): real WebSocket offer/answer/ICE on 127.0.0.1 plus the
# real Str0mNet UDP/DTLS/SCTP transport. Needs both feature trees.
test-webrtc-signaling:
>$(CARGO) test --locked --features "signaling-client webrtc-str0m" --test webrtc_signaling
# WebSocket DataChannel backend (#akp3): in-process loopback over a real WS
# handshake, no real network.
test-websocket:
>$(CARGO) test --locked --features websocket
benchmark-check:
>$(PYTHON) scripts/update-benchmark-results.py --check
benchmark-update:
>$(PYTHON) scripts/update-benchmark-results.py
instrumentation-profile:
>$(CARGO) run --example instrumentation_profile --features "instrumentation thread-safe" --quiet