Alpha. Vary is under active development and not ready for production use. Syntax, APIs, performance, and behaviour may change between releases.

Fast mode

vary mutate --fast-mode narrows the per-mutant test filter on top of the existing coverage-guided selection. It trades a controlled amount of accuracy for speed, and runs a continuous validation pass every run so that accuracy stays within a threshold you set. When the measured miss rate exceeds the threshold, every non-sampled mutant is re-run with the broader filter and the report is rewritten with the conservative result.

For the basics, see Introduction. For how fast mode composes with other strict-mode optimisations, see Strict mode.

Why "validated"

Fast mode is heuristic. Without continuous validation it would be a silently-lossy classification engine, turning a survivor the conservative filter would have killed into "test gap" noise in the report even though the test exists and works. Continuous validation is the contract that lets Vary ship a faster mode and still defend the per-mutant killed / survived classification.

The validation compares (fast-mode classification, broad classification) on a sample of mutants. A "miss" is a sampled mutant where the two classifications disagree in either direction.

DisagreementMeaning
fast=survived, broad=killedFast mode missed a kill
fast=killed, broad=survivedFast mode reported a phantom kill

If miss rate > threshold, fast mode auto-falls back: every remaining survivor is re-run with the conservative filter and the result list is rewritten. Every mutant in the final report is then labeled by the conservative truth.

Narrowing rule

For each mutant, the conservative test filter is the set of tests that exercise the mutated method (from the stats-phase coverage map). Fast mode takes the first max(1, ceil(N * narrowFactor)) tests in deterministic sort order.

narrowFactorEffect
0.5 (default)Keeps half the conservative filter
0.25Keeps a quarter
1.0No-op

When a mutant has no coverage filter (stats phase did not run, or the method has no covering tests), fast mode does not narrow. Conservative behaviour applies.

CLI flags

FlagDefaultRangePurpose
--fast-modeoffflagEnable narrowing + validation
--fast-mode-narrow-factor0.5[0.0, 1.0]Fraction of conservative filter kept
--fast-mode-sample-size10>= 0Mutants re-run with the broader filter
--fast-mode-miss-threshold0.10[0.0, 1.0]Miss rate above which auto-fallback fires

The threshold rule is strictly greater than: a miss rate that equals the threshold does not trigger fallback. This makes the boundary deterministic so a workload sitting exactly on the line stays in fast mode.

Artifact shape

mutation.json per-file block:

{
  "file": "src/util.vary",
  "fastMode": {
    "enabled": true,
    "narrowFactor": 0.5000,
    "sampleSize": 10,
    "sampledMutants": 10,
    "missCount": 3,
    "missRate": 0.3000,
    "missRateThreshold": 0.1000,
    "fallbackTriggered": true
  },
  "mutants": [...]
}

The same six fields are surfaced as columns in telemetry.json and telemetry.csv (fastModeEnabled, fastModeNarrowFactor, fastModeSampledMutants, fastModeMissRate, fastModeMissRateThreshold, fastModeFallbackTriggered). These columns are emitted unconditionally so downstream consumers can read the same shape every run.

Interaction with other features

FeatureInteraction
Incremental inference (--incremental-infer)Fast mode narrows the test filter that is stored as each entry's testsFingerprint. Switching between fast mode and conservative invalidates prior entries, which is correct because the stored result was produced under a different test filter.
Mutant groupingThe grouping plan is computed from the conservative covering-tests map. Fast mode's narrowing applies on top of the group's selectedTests, so members of a group still share the same narrowed filter.
Survivor tailThe post-loop flake-detection rerun runs before the fast-mode validation pass and uses the same (narrowed) filter the main loop used. The validation pass is a separate, accounted-for cost and adds to executionTimeMs but is not part of the survivor tail.
Bytecode backendsFast mode is wired into the AST-level runner only. The bytecode backends (fresh-loader, hot-swap, redefine) do not apply fast-mode narrowing.

Non-goals

Non-goalDetail
Automatic per-workload narrow-factor selectionStart with a hand-tuned value, watch the miss rate, adjust
Persisting fast-mode validation history across runsEach run re-validates
Replacing strict mode as the truth sourceFast mode is an opt-in; strict mode (the no-narrowing path) remains the default