Performance testing
Performance work splits into two honest halves: correctness at scale
(the registered performance pack) and measurable timing (the benches).
The performance pack (CT-PERF-001..003)
A configurable high-volume scenario family that proves the orchestration
stack stays correct as workloads grow — repeated deposits, repeated
transfers, and the full register→deposit→transfer→withdraw lifecycle over
many operations. Each scenario computes expected balances independently
(deposit count × unit amount against the fixture ledger) and attaches the
full invariant registry, so “fast but wrong” is still a failure. Scale
is configurable (performance::all_with(PerformanceParams{..})) so CI runs
a bounded scale while an operator can push higher locally.
The benches
cargo bench runs six stable-Rust benches (no external benchmarking
dependency) under benches/:
- scenario-execution — end-to-end scenario runs through the mock harness (ns/run),
- assertion-evaluation — assertion-engine evaluation over a populated observation log (ns/eval),
- fixture-loading — catalog construction and per-run clone cost (ns/clone),
- proof-flow — prove / verify / reject-tampered through the prover double,
- concurrency — serial vs parallel wall-clock speedup with a byte-identical-outcome assertion,
- reporting — suite-report rendering in JSON / JUnit XML / Markdown with a determinism assertion.
Timings are labeled as mock-harness costs — they bound the scenario layer, never the real prover or simulator.
Phase-decomposed timing
Scenario outcomes carry per-phase timings (setup, simulation, assert, invariants, classify, report, cleanup — spec §67). The reporting crate renders them as a per-phase table in Markdown and JSON so a run’s time is never collapsed into one number. Under the fixed mock clock these are deterministic (zero); with a wall clock they become real and still structured.