What it is
dev-tools is the convenient one-import entry point for the dev-*
verification suite. Instead of pulling in seven separate crates and
wiring them together, you add one dependency and turn on the parts
you need with feature flags.
The suite gives an AI agent (or a CI gate) machine-readable evidence about a Rust project:
- Did it compile?
- Did tests pass?
- Did performance regress?
- Did async code hang?
- Did the system collapse under load?
- Did failure recovery work?
Output flows through dev-report
— a stable, versioned JSON schema. No log parsing.
Feature flags
Pick features by what you want to verify:
| Feature | Default | What it brings in | Use case |
|---|---|---|---|
report |
always on | dev-report — JSON schema, Report/MultiReport/Diff types |
Required by everything else; never disabled. |
fixtures |
✅ | dev-fixtures — TempProject, file-tree builders, golden snapshots, mock data |
Repeatable test environments and inputs. |
bench |
✅ | dev-bench — Benchmark, percentile stats, regression thresholds, baseline storage |
Performance verification. |
async |
— | dev-async — run_with_timeout, deadlock detection, task tracking, shutdown probes |
Hung futures, task leaks, shutdown verification. |
stress |
— | dev-stress — StressRun, SoakRun, latency percentiles |
High-load and sustained-load testing. |
chaos |
— | dev-chaos — failure injection, latency injection, crash points, IO wrappers |
Failure-recovery testing. |
full |
— | All of the above | Kitchen-sink verification rigs. |
Default = fixtures + bench + report. Sensible for most projects.
Quick start
Defaults (most common)
[]
= "0.9.2"
You get: report (always), fixtures, bench.
Just the schema (lightest)
[]
= { = "0.9.2", = false }
You get: report only. No fixtures, no bench. Ideal when you
just need to consume reports produced elsewhere.
Specific features
Pick exactly what you need. Examples:
# Async-heavy service: schema + async helpers, no fixtures/bench.
= { = "0.9.2", = false, = ["async"] }
# Defaults plus async (additive).
= { = "0.9.2", = ["async"] }
# Defaults plus chaos and stress.
= { = "0.9.2", = ["chaos", "stress"] }
# Everything (CI verification rigs, AI agents that drive the whole suite).
= { = "0.9.2", = ["full"] }
Toggle features off
fixtures and bench are on by default. Disable them with
default-features = false and re-add only what you want:
# Async + chaos, NO fixtures/bench.
= { = "0.9.2", = false, = ["async", "chaos"] }
API map
Each feature exposes the underlying sub-crate at a fixed path:
| Feature | Module path | Top-level types |
|---|---|---|
| always | dev_tools::report |
Report, CheckResult, Verdict, Severity, Evidence, Producer, MultiReport, Diff, DiffOptions |
fixtures |
dev_tools::fixtures |
TempProject, FixtureProducer, Golden, BinaryGolden, tree::*, adversarial::*, mock::* |
bench |
dev_tools::bench |
Benchmark, BenchmarkResult, BenchProducer, Threshold, CompareOptions, Baseline, BaselineStore, JsonFileBaselineStore |
async |
dev_tools::r#async |
run_with_timeout, join_all_with_timeout, AsyncProducer, BlockingAsyncProducer, deadlock::*, tasks::*, shutdown::* |
stress |
dev_tools::stress |
StressRun, StressResult, SoakRun, Workload, LatencyTracker, LatencyStats, StressProducer |
chaos |
dev_tools::chaos |
FailureSchedule, FailureMode, assert_recovered, ChaosProducer, io::*, latency::*, crash::* |
Prelude
use dev_tools::prelude::*; pulls in the schema types in one line:
use *;
let mut r = new;
r.push;
r.finish;
assert!;
The prelude includes: Report, CheckResult, Verdict, Severity,
Evidence, EvidenceData, EvidenceKind, FileRef, MultiReport,
Diff, DiffOptions, DurationRegression, SeverityChange,
Producer.
When the async feature is on, dev_tools::prelude::async_prelude::*
additionally includes run_with_timeout, join_all_with_timeout,
AsyncCheck, AsyncProducer, and BlockingAsyncProducer.
Putting it together
Build a report by hand
use *;
let mut r = new.with_producer;
r.push;
r.push;
r.finish;
println!;
Compose multiple producers — sync
The full_run! macro takes any number of Producer values and emits
one MultiReport
sharing one subject/version:
use ;
let fixture = new;
let benchmark = new;
let multi = full_run!;
println!;
Compose multiple producers — async
With the async feature, the [async_full_run!] macro does the same
for async producers (futures returning Report):
use async_full_run;
use ;
async
async
# async
full_run! expects sync Producer values; async_full_run! expects
futures. Mix and match — use BlockingAsyncProducer to wrap an async
producer into a sync Producer if you need to combine them in
full_run!.
Compute a diff between runs
Report::diff(&baseline) -> Diff and Report::diff_with(&baseline, &opts) -> Diff
report regressions:
use *;
let prev: Report = from_str.unwrap;
let curr: Report = produce_current_report;
let diff = curr.diff;
if !diff.is_clean
#
Why a verification suite
AI can generate code quickly. Without verification, AI-generated code can:
- Compile but behave incorrectly
- Pass simple tests but fail under load
- Introduce performance regressions
- Break async shutdown
- Leak memory
- Hide race conditions
- Look clean while being fragile
The dev-* suite gives an AI agent a structured way to validate its
own work before a human has to trust it.
Status
v0.9.x is the pre-1.0 stabilization line across all sub-crates.
APIs are expected to be near-final; minor adjustments may still
happen ahead of 1.0. The schema (dev-report) stays at
schema_version = 1 through this line.
Sub-crate dependency constraints are pinned at ^0.9 (any 0.9.x).
The umbrella crate does not require a coordinated patch release of
the sibling crates; you can safely use dev-tools 0.9.2 alongside
sibling crates at any 0.9.x version.
Minimum supported Rust version
1.85 — pinned in Cargo.toml via rust-version and verified by
the MSRV job in CI. (Bumped from 1.75 to match sibling sub-crate
MSRVs after their transitive deps required Rust 1.81+ and
edition2024.)
License
Apache-2.0. See LICENSE.