Scope: AI-agent-agnostic playbook for building applications with the Stoffel framework. This is not a maintainer guide for compiler, VM, protocol, or release engineering work. Dependency assumption: app dependencies come from current public crates.io releases by default. Use a full pinned revision of the official GitHub repository only as fallback; reserve local paths for explicit nonportable framework development.
Use when
Use this playbook when an app needs local MPC smoke testing, ClientStore input runs, hot reload, or SDK local coordinator-backed execution.Goal
Give developers a repeatable local loop for testing private/MPC apps before any real network deployment. Local MPC is a verification gate, not the production topology.Current source of truth
crates/stoffel-cli/src/main.rscrates/stoffel-rust-sdk/README.mdcrates/stoffel-rust-sdk/src/runtime.rscrates/stoffel-lang/examples/README.mdcrates/stoffel-lang/examples/**/*.stfl
CLI local run
--network or --config is set.
Hot reload
--once for CI/smoke checks and default watch mode during interactive development.
Input paths
Named function args:--input-file and --client-input-file for .json, .csv, and .txt inputs. See Stoffel CLI App Workflow.
Use example run-args headers
Many secret examples include the exact local flags in the first source line:
--client-input 0=50 --client-input 0=20 maps to ClientStore.take_share(0, 0) then ClientStore.take_share(0, 1).
SDK local run
For a Rust app, use the version from the current SDK installation docs and commitCargo.lock:
git = "https://github.com/Stoffel-Labs/stoffel.git" with rev = "<full-40-character-commit-sha>". Do not substitute branch = "main". A path = "../stoffel/crates/stoffel-rust-sdk" dependency is nonportable and is valid only when deliberately testing framework source.
Recommended local loop
- Resolve the app root from an explicit argument, manifest, or the script’s own location; do not assume the caller’s CWD.
- Run
stoffel status --verbose "$APP_ROOT". - Run
stoffel check "$APP_ROOT"to catch syntax/config/type errors. - Run
stoffel build "$APP_ROOT" --program-infoto inspect bytecode and client IO metadata. - Run
stoffel run "$APP_ROOT" --timeout-secs 180with named inputs or documented# run-args:flags. - If using Rust, run
cargo check --lockedandcargo run --lockedwith an explicit--manifest-pathagainst the same bytecode/source. - Inspect
cargo metadata --lockedand prove the app in a clean external checkout. - Record the exact command/output in the app handoff.
- Only then move to network/off-chain config with Stoffel Deployment Runbook.
registry+... source or a pinned official git+...#<full-sha> source. source: null exposes a local path/workspace dependency.
Validation / done criteria
For app local-MPC work:Cargo.lock, then clone the app into a temporary directory outside the framework checkout (with no sibling ../stoffel) and rerun the locked check and local smoke. A pass inside the framework repository alone is insufficient portability proof.
For framework example validation:
Common pitfalls
- Compile-only success is not a local MPC smoke test.
- A local MPC pass backed by an adjacent path dependency is not a portable app proof.
- Do not let
cargo runupdate the graph implicitly; commit the lockfile and use--locked. - Do not encode framework checkout locations or assume commands start at the repository root.
- Local MPC success is not production deployment; it only proves the program and app boundary work on the local test network.
- Increase
--timeout-secsbefore assuming protocol failure. - Avoid port/process collisions by serializing tests that spawn local party meshes.
- Keep
ClientStoreinputs separate from named function inputs. - Do not omit
--expected-output-clientsfor examples/programs that send client outputs. - AVSS support is backend/curve/input dependent; verify the current SDK boundary.