leanguard-testgen
Coverage-guided test generation on top of leanguard-run (fuzz, minimize, campaign).
leanguard-testgen drives the coverage-guided test generation pipeline described in the Days research notes.
Source: days/src/bin/leanguard-testgen.rs
Top-level options
--corpus-root <dir>(default:leanguard_corpus)--checker-dir <dir>(default:lean/.lake/build/bin)--leanguard-run <path>(optional)- If omitted,
leanguard-testgenwill try to executeleanguard-run(either as a sibling binary or via$PATH).
- If omitted,
--allow-nondeterministic(default: false)
Subcommands
seed-index
cargo run --bin leanguard-testgen -- seed-index <seeds_src>Build an index of seed configs.
fuzz
cargo run --bin leanguard-testgen -- fuzz --budget <N> [--rng-seed <u64>]Run random mutations for a fixed budget.
replay
cargo run --bin leanguard-testgen -- replay <case_dir>Re-run a saved failing (or interesting) case directory.
minimize
cargo run --bin leanguard-testgen -- minimize <case_dir> [--max-iters 25]Attempt to shrink a failing case while preserving the failure (delta debugging over scenario mutations).
campaign
cargo run --bin leanguard-testgen -- campaign \
--protocol <name> \
--budget <N> \
[--rng-seed <u64>] \
[--goal <string>] \
[--max-calibration-iters <N>] \
[--seed-filter <string>] \
[--dry-run] \
[--use-trace-signature]Run a full generation campaign for a protocol.
The command prints JSON summaries to stdout (or errors to stderr with a non-zero exit code).
Corpus layout and artifacts
By default, leanguard-testgen writes a persistent corpus under --corpus-root (default: leanguard_corpus/).
Typical directory layout:
leanguard_corpus/
seeds/ # seed *.toml copied in by seed-index
accepted/<case_id>/ # per-case artifacts (accepted)
rejected/<case_id>/ # per-case artifacts (rejected)
metadata/
seeds_index.json # seed inventory
global_coverage.json # persistent union for novelty tracking
<case_id>.json # per-case metadata record
_work/ # temporary scratch space (best-effort cleaned)Each case directory (accepted/<case_id>/ or rejected/<case_id>/) contains:
config.toml: the final scenario config (withlog_pathrewritten to the case’slogs/dir)logs/: the Days log directory (including any*_events.csvtraces)run_summary.json: the JSON summary produced byleanguard-runmutations.json: the list of scenario mutations applied
metadata/global_coverage.json
The current implementation stores a minimal global-union structure:
{
"version": 1,
"observed": ["<item>", "..."]
}Where each "observed" item is either:
- a checker-emitted semantic coverpoint (when coverage is enabled and available), or
- a trace signature entry like
trace_kind_hash:<trace_file>:<hash>when--use-trace-signatureis enabled.
This file is used to classify newly accepted cases as new vs redundant in the per-case metadata.
metadata/<case_id>.json
Each case also produces a metadata record with:
- the seed parent
- file paths for the case
- the applied mutations
- accept/reject status and discovered traces
- coverage mode + observed items + novelty classification
- (for campaigns) protocol/goal/corpus options