Aver CLI
May 29, 2026 · View on GitHub
Full toolchain reference for the aver binary. README points here for the per-command surface; deeper topics live in dedicated docs (docs/bench.md, docs/transpilation.md, docs/lean.md, docs/dafny.md, docs/wasm.md, docs/rust.md).
Main commands
Run
aver run file.av
aver run file.av --module-root .
aver run file.av -- arg1 arg2 arg3
- Aver program args are available through
Args.get() --record <dir>records effect traces for replay
Check
aver check file-or-dir --module-root . --deps
check handles static contract diagnostics:
- missing
intent = - missing
?descriptions on relevant functions - missing
verifyon pure, non-trivial, non-mainfunctions - coverage-style warnings for thin
verifyexamples - file size warnings
Warnings do not make check fail.
Verify
aver verify file-or-dir --module-root . --deps
aver verify file-or-dir --wasm-gc
verify runs only declared left => right examples.
It fails on:
- mismatched examples
- parse/type errors
- execution errors
It is not a coverage tool.
--wasm-gc (0.17.3+) executes the same cases via the wasm-gc backend instead of the VM — cross-target check that catches divergence between VM and wasm-gc codegen on equality. The host decodes a single Bool per case (wasm-gc lowers == per-type via eq_helpers natively). Failure diagnostics show the actual runtime value for primitive return types (Int/Float/Bool/Str). Trace projections (.trace.*), classified-effect Oracle stubs (given X: Time = stub), and case bodies mentioning BranchPath are rejected upfront with a pointer back to VM verify — those features depend on namespace-value dispatch and runtime override that the wasm-gc backend doesn't have yet.
Format
aver format .
aver format examples
aver format examples --check
format accepts files or directories and walks .av files recursively.
Audit
aver audit file-or-dir --module-root . --deps
audit is the single-shot CI gate that runs all three axes at once:
- static checks (same diagnostics as
check) verifyexecution (same asverify)format --check(structural compliance)
Output is a flat list of error[slug]: / warning[slug]: lines plus a
summary footer: N files | X check errors | Y verify failures | Z format.
Any non-zero count fails the command.
- warnings (e.g.
independence-hazard,non-tail-recursion) do not fail the audit — they are advisory - errors come from the same machinery as
check/verify/format, so slugs are stable and matchdocs/diagnostics-slugs.md - prefer
aver auditover chainingcheck && verify && format --check— it runs the pipeline once and reports everything in one place
Use it before showing a snippet to the user or committing docs examples;
it catches illegal ?! usages, match-arm body-on-next-line parse errors,
and effect-type mismatches that a naked aver run can miss when the VM
short-circuits on the first failure.
--hostile (0.13+) layers adversarial worlds on top of every
verify <fn> law block — typed givens get type-boundary values,
classified effects get hostile profiles. Failures use the separate
slug verify-hostile-mismatch so CI can route declared-world vs
adversarial-world regressions to different channels.
Context
aver context file.av --module-root .
Default:
--depth auto--budget 10kb
This is the preferred AI discovery workflow:
- start with a small budget
- inspect the architecture map
- look at selection metadata
- zoom in only where needed
Examples:
aver context examples/modules/app.av --budget 10kb
aver context projects/workflow_engine/main.av --module-root projects/workflow_engine --budget 24kb
aver context projects/workflow_engine/main.av --module-root projects/workflow_engine --json --budget 24kb --output projects/workflow_engine/CONTEXT.json
Notes:
--depth Nand--depth unlimitedbypass the auto-budget behavior--decisions-onlyexports onlydecisionblocks- selection metadata is printed to stdout and embedded in JSON output
Shape
aver shape file.av
aver shape file.av --summary
aver shape file.av --json
aver shape file.av --lint # opt-in lint vs aver.toml expectations
aver shape file.av --module-root .
# Corpus mode: pass a directory and `aver shape` walks every .av
# underneath, prints a per-file table + aggregate Kind / Layer /
# archetype distributions, and runs the same --lint check against
# every file in one pass.
aver shape src/
aver shape src/ --summary # aggregate only, no per-file table
aver shape src/ --json # NDJSON, one object per file
aver shape src/ --lint # exit 1 if any file mismatches its expected layer
aver.toml config:
# Per-project layer fingerprints — override the built-in v0 baseline.
[[shape.layer]]
name = "Domain"
match = 40
recursion = 25
pipeline = 0
orchestration = 5
helpers = 30
# Path → expected layer. `--lint` flags mismatches; without these
# entries, `--lint` is a silent no-op.
[[shape.expected]]
glob = "src/parse/**"
layer = "Parse"
Static module-shape analyzer — an architectural smell radar, not a classifier of truth. The histogram is the fact; Kind and Layer are interpretation. Output is auditable: every interpretation comes with the metric that drove it (confidence + margin + top-3 candidates for Layer; the rule that mapped the vector to Kind), so reviewers can decide whether to trust the label.
Three views in one run:
- Per-fn archetype — 14 labels (
scc-mutual,structural-recursion,match-dispatcher,pipeline-result,manual-result-adapter,renderer-formatter,match-on-value,orchestration,effectful-leaf,let-pipeline,constructor-wrapper,data-as-function,trivial-helper,pure-expression). Multi-label per fn; output lists every label that fires plus a primary pick. - ModuleShape vector + Kind — 5 dims (
purity,entry,state_shape,type_surface,api_shape). Kind is a single label projected from the vector:ServiceClient,Orchestration,SmartConstructor,DataModule,PureHelpers,Library,EffectfulLibrary,EffectfulShell.purityisPure/ClassifiedEffectful(all effects are Oracle one-shot req/resp shape) /ShellEffectful(contains shell/lifecycle effect likeHttpServer.listen— Oracle skips by design, not because the classifier doesn't recognize it). - Architectural Layer —
Domain | Parse | Command | AiStrategy | RenderUi | Infraby Euclidean distance between the per-module archetype histogram and the fingerprint table. Two metrics:confidence(absolute fit to the best fingerprint) andmargin(distance gap to runner-up). Low confidence OR low margin marks the verdictuncertain, with explicit "best: X" wording so the user doesn't read it as a hard label. Runners-up (top-3 closest layers with distances) are always printed so the user sees how decisive the call is. Confidence is penalized on tiny modules (<5 fns capped at 0.2, <10 fns softened by 0.7×).
Verification appears as an orthogonal section — what verify blocks the source carries (Cases, Laws, Trace, Mixed), how many blocks, and per-fn coverage. Static read of the source, doesn't run VM.
Use cases:
- "What is this module structurally?" — first glance before reading
- "Does the directory layer match what the histogram looks like?" — architectural lint (full
--lintmode +[[shape.expected]]config is the next iteration) - LLM context enrichment — Kind + ModuleShape are stable per-module facts worth attaching to AI prompts about that file
Notes:
--summarycollapses per-fn listing to the header + histogram; same content otherwise--jsonemits an audit-friendly structure withfacts+vector+kind+histogram+layer+fnsall side by side, so consumers can pick any layer
Compile
aver compile file.av -o /tmp/out --module-root .
aver compile file.av --target wasm-gc -o /tmp/out
aver compile file.av --target wasm-gc --optimize size -o /tmp/out
aver compile file.av --preset cloudflare --handler handler -o /tmp/out
aver compile file.av --emit-ir-after=PASS
aver compile file.av --explain-passes
- Default: Rust codegen, emits a modular Cargo project
--target wasm-gc: native WebAssembly GC + tail-call output (recommended). Self-contained binary, engine handles GC/recursion, per-instantiation helpers DCE'd to what each program calls. Modern host baseline (Chrome 119+, Firefox 120+, Safari 18.2+, wasmtime 25+, Node 22+).--target wasm: legacy fallback for pre-2024 hosts. Bundles a custom NaN-boxed runtime viawasm-merge.--optimize size|speed: post-process with binaryen-Oz(size) or-O3(speed).--preset cloudflare --handler <fn>: Cloudflare Workers pack —--target wasm-gc --pack cloudflare, dropsworker.js+wrangler.tomlnext to the wasm.<fn>must have signatureFn(HttpRequest) -> HttpResponse.--emit-ir-after=PASS: print the IR snapshot after the named pipeline stage and exit before codegen. PASS ∈ {parse,tco,typecheck,interp_lower,buffer_build,resolve,last_use,analyze}.diff -ubetween two stages shows exactly what each pass rewrote.--explain-passes: run the full pipeline (no codegen) and print a per-pass diagnostic report — tail-call conversions, interpolations lowered, fusion sites rewritten + sinks synthesized, slots resolved, last-use markers annotated, alloc/recursion facts. Drives failable-invariant CI checks ("fail if buffer_build no longer fires on the canonical shape", "fail if hot fn loses no-alloc status"). Pair with--jsonfor typed-per-stage shape:{schema_version: 1, passes: [{stage, data: {...stage-specific fields}}, ...]}— buffer_build'sdataexposesrewrites,synthesized,sinks,rewrites_by_sink; analyze's exposestotal_fns,no_alloc_fns,recursive_fns,mutual_tco_members.jq '.passes[] | select(.stage=="buffer_build") | .data.rewrites'instead of regex-parsing summary strings.
Bench
aver bench foo.av # ad-hoc, defaults (30 iter, 3 warmup)
aver bench foo.av --iterations=50 --warmup=5 # ad-hoc with overrides
aver bench bench/scenarios/fib.toml # named manifest
aver bench bench/scenarios/fib.toml --json # structured report
aver bench bench/scenarios/ # directory mode (every *.toml)
aver bench bench/scenarios/ --json # NDJSON
aver bench bench/scenarios/fib.toml --target=wasm-local # requires --features wasm
aver bench bench/scenarios/fib.toml --target=rust # native binary, subprocess per iter
aver bench bench/scenarios/fib.toml --save-baseline base.json
aver bench bench/scenarios/fib.toml --compare base.json --fail-on-regression
aver bench bench/scenarios/ --save-baseline bench/baselines/<host>-<arch>-vm.json # capture baseline (NDJSON)
aver bench bench/scenarios/ --baseline-dir bench/baselines/ --fail-on-regression # CI gate
- Three input shapes:
.av(ad-hoc, defaults +--iterations/--warmupoverrides),.toml(named manifest with per-scenario tolerance + expected shape), directory (globs*.toml). - Three targets:
vm(default, in-process),wasm-local(wasmtime in-process),rust(native binary). - Reports include
backend(aver version, build, wasmtime version) andhost(os/arch/cpus) so cross-machine runs disambiguate. --save-baselineworks in both single-scenario (pretty JSON) and directory (NDJSON) mode.--compareis single-scenario only.--baseline-dir DIRauto-picks<host.os>-<host.arch>-<backend.name>.jsonfromDIR. Silent skip when no matching baseline exists — single workflow gates wherever a baseline is pinned. CI uses this.- See docs/bench.md for the full reference.
Proof
aver proof file.av -o /tmp/proof --module-root . --verify-mode auto
Lean export modes:
autosorrytheorem-skeleton
Replay
aver replay recordings/ --test --diff
Use replay for effectful debugging and regression capture.
Recommended workflows
Logic bug
- add or tighten a
verify - run
aver verify ... - fix code
- keep the example
Effect bug
- run with
--record - inspect replay artifact
- run
aver replay ... --test --diff
Project discovery
aver context <entry> --budget 10kb- if needed, raise budget or target a specific module
- only then open raw source files
aver.toml
Project-level config (deployment guardrails + check tweaks):
[effects.Http]
hosts = ["api.example.com", "*.internal.corp"]
[effects.Disk]
paths = ["./data/**"]
[effects.Env]
keys = ["APP_*", "TOKEN"]
[[check.suppress]]
slug = "non-tail-recursion"
files = ["**/eval/**"]
reason = "Tree-walking interpreter — CPS would destroy correspondence."
Effect-host / path / key allowlists narrow which hosts, files, and env keys the runtime will admit. [[check.suppress]] lets a project waive specific lint slugs in specific paths with a reason.