v122-alpha.1 is out. It is a release with one new top-level command, a rewritten mutation engine, a native parser library, and a handful of smaller features that had been waiting for a home. The full table of changes lives on the v122-alpha.1 release page. This article walks through the parts most worth knowing about.
The headline change is vary var. It runs check, test, mutation, and review stages under a cost budget. The point is to give Vary a single answer for what to run before trusting a change, instead of a sequence of subcommands stitched together by hand.
A typical invocation is just:
vary var
That covers most cases. To see what vary var would do without paying for it, ask:
vary var --dry-run --explain
The output describes the policy choices: which files are in scope, which stages will run, and why. Other useful modes are --json and --compact for tools and dashboards, --since-ref main to scope to files changed since a git ref, and --include-mutation to force the mutation stage on.
Agent loops are the obvious target. How AI tools should use vary var covers that case in detail.
The other big story in v122 is mutation testing. The engine went through an overhaul that touched test selection, scheduling, worker management, and the bytecode patching path.
The short version:
| Change | What it does |
|---|---|
| Reachability tracing | Builds a persisted relevance graph during the baseline run, so each mutant only re-runs the tests that actually cover its method. |
| Kill-first scheduling | Sorts those tests so the most likely killers run first. The mutant is dropped as soon as one of them fails. |
| Warm workers | Reuses JVM processes across mutants and across runs, which removes most of the startup overhead. |
| Pluggable backend | Adds method-body hot-swap for small mutations, with a fresh-loader fallback when a mutation is too large for the fast path. |
The numbers are in Vary mutation testing speed: comparing to AST and PIT. On the checked-in Frugal benchmark, the compiled run finishes in a stable 27 seconds over 1,857 mutants. Against the PIT-style comparison fixture, Vary measures at 0.92x of PIT's wall time.
Speed only matters if the answer is right. v122 also adds a parity benchmark that runs every execution mode in parallel. If the optimized run classifies any mutant differently from the safer baseline, the benchmark fails. Run it with vary benchmark.
Frugal is a native Vary grammar and parser library, ported from Parsimonious. It is written entirely in Vary, with enum-typed grammars, match-based dispatch, and contract-checked parser combinators.
Two reasons Frugal matters. First, parser code is a notoriously hard workload. A real parser library tends to surface type-system, codegen, and runtime edge cases faster than synthetic test programs do. Several v122 codegen fixes (enum lowering, variable shadowing in nested scopes, and module-level var initialization order) came out of porting Parsimonious. Second, Frugal gives Vary a native way to define grammars and parse structured text without dropping into JVM interop.
The transpilation framework that ships alongside Frugal can port Python tests to Vary using Frugal itself, which is how the upstream Parsimonious test suite was used for parity validation.
Three codegen features land together.
Dict[K, V] lowers through the same generic codegen path as List[T]. Generic functions over Dict work without boxing or type-erasure surprises.
Operator overloading lets user-defined types implement +, -, ==, and similar operators through standard methods. Vary calls them by their normal names so the dispatch is visible to readers and tools, but you write a + b and the compiler routes it through the operator method.
Interface-typed collections work end-to-end. List[Drawable] can hold any concrete type that implements Drawable, and methods dispatch through the interface table without requiring an explicit cast.
vary check gained fourteen new rules in v122. Four are structural project-level rules (VCL001 through VCL004) that look at the whole project at once: inappropriate generated-code placement, fixture leakage across module boundaries, and bypasses of the network-effect boundary. Six are architecture-smell rules. Four more catch parallel collections, hand-rolled tagged unions, stale workarounds, and mixed-concern functions.
vary explain <rule> is a new sibling command. It prints a plain-language description of the rule, an example of the smell, and the canonical fix. The same description appears in vary check output when you pass --explain. The intent is the same as vary var --explain: make Vary's policy decisions inspectable instead of opaque.
If varyup is already installed, this is the whole upgrade:
varyup install latest
That installs v122-alpha.1, verifies the Sigstore signature on the release archive, and pins the active toolchain. There is a longer write-up on how that verification step works.
Anyone coming from before v117 should upgrade varyup first. Older varyup binaries do not understand the Sigstore bundle format and will skip signature verification silently.
Most of the new surface area in v122 is about trust loops rather than syntax. vary var, vary explain, and vary benchmark all answer related questions: what to run, why a finding is there, and whether the fast path can be trusted. Expect more in that direction in the next release.
The full change list is on the v122-alpha.1 release page.