Development Setup¶
tiderace's engine lives in the engine/ Cargo workspace. This is where you build, test, and lint.
Prerequisites¶
- Rust toolchain (stable) —
rustup install stable. - Python 3.12+ — required for the
sys.monitoringcoverage path and the shim proofs.
No pytest or coverage.py needed: tiderace is its own runner.
Clone and build¶
Debug binaries land in engine/target/release/ (or engine/target/debug/ for cargo build): tiderace (the CLI) and tiderace-daemon (the warm server).
Run the tests¶
The engine's logic is unit- and integration-tested in pure Rust (the ShimTransport seam lets the execution path run with no Python at all via a scripted test double):
cd engine
# Core engine: collection, fixtures, scheduler, exec, coverage, impact, cache
cargo test -p engine-core
# Daemon: impact-aware run, persistence, watch, RPC server
cargo test -p engine-daemon
# Everything
cargo test
Lint & format¶
CI enforces both — PRs that fail clippy or fmt are blocked.
Live tests and the fx venv¶
The acceptance suites that assert the engine's load-bearing invariants — no-fork ≡ fork, sub-interpreter ≡ fork, purity/safety detection, the daemon end-to-end — need a real interpreter, and resolve .tiderace-fx-venv at the repo root by path. Without it they self-skip.
A skip is not visibly different from a pass. libtest has no "skipped" state, so an early return reports as ok, and the harness swallows the skip marker unless you pass --nocapture. A green cargo test can therefore mean the isolation ladder is sound or that none of it ran. (This is not theoretical: the venv symlinked into a versioned VSCode snap path, that revision was garbage-collected, and the workspace stayed green with 10 live tests skipping.)
Provision it once, at the repo root:
Point at a stable interpreter
python here must be a path that survives upgrades. A uv/snap interpreter under a revision-numbered directory will break silently when that revision is collected.
Then, to prove the live paths actually executed:
TIDERACE_REQUIRE_LIVE=1 turns every live-scenario skip into a panic (engine_core::testing). Both CI jobs that provision the venv set it, so a broken environment fails the build instead of passing as a no-op. Leave it unset if you're working without a venv — the suites will skip as before.
Coverage gate¶
CI gates line coverage of the engine workspace at ≥ 88% (cargo llvm-cov). Reproducing it needs the fx venv above — without it the exec paths look uncovered and the gate only measures pure logic:
cd engine
TIDERACE_REQUIRE_LIVE=1 cargo llvm-cov --workspace --ignore-filename-regex '(main|socket)\.rs' --fail-under-lines 88
main.rs (CLI entry) and socket.rs (the socket serve loop) are excluded — binary glue with no logic that a killed process can't flush coverage for.
The Python shim proofs¶
The shim and the native authoring package carry standalone proof scripts that demonstrate specific behaviours (isolation tiers, purity, coverage, type-DI). They run directly with python3 (3.12+) — no Rust, no test framework:
cd engine/py-tiderace
python3 proof_static_purity.py # static AST impurity pre-filter
python3 proof_snapshot_restore.py # no-fork + restore isolation
python3 proof_purity_guard.py # purity verdict recording
python3 proof_n6_coverage.py # sys.monitoring coverage capture
python3 proof_type_di.py # native @provides / @uses type resolution
# …other proof_*.py in the same directory
The shim itself is engine/py-shim/shim.py — the only code that runs inside CPython.
Repository layout¶
tiderace/
├── engine/ # the pure-Rust engine (build from here)
│ ├── Cargo.toml # workspace manifest
│ ├── crates/
│ │ ├── engine-core/ # collection · fixtures · scheduler · exec · coverage · impact · cache
│ │ ├── engine-cli/ # → tiderace (collect, run)
│ │ ├── engine-daemon/ # → tiderace-daemon (run, serve, watch, bench)
│ │ └── engine-inproc/ # → inproc-probe (experimental embedded-CPython / FFI backend)
│ ├── py-shim/ # shim.py — the execution substrate (import, invoke, isolate, coverage)
│ └── py-tiderace/ # native authoring pkg (tiderace/) + proof_*.py + migrate
├── benchmarks/ # bench_3way.sh, real_world.sh, RESULTS-*.md, fixtures/
├── docs/ # MkDocs source — user guides + whole-system design
├── planning/ # per-feature planning (PRD / ADR / design)
└── ARCHITECTURE.md # the authoritative architecture reference
Branching model¶
tiderace uses trunk-based development:
- All work lands on
mainvia short-lived branches. - No long-lived feature branches;
mainis always releasable.
Commit convention¶
Use Conventional Commits:
feat: add no-fork restore tier to the isolation ladder
fix: handle empty test directories gracefully
docs: update impact-analysis design doc
chore: bump pyo3 to 0.26
CI uses these to compute semantic version bumps automatically.
| Prefix | Version bump |
|---|---|
feat: | minor (0.x.0) |
fix:, perf:, docs: | patch (0.0.x) |
feat!: or BREAKING CHANGE: | major — CI only |