vary mutate --incremental-infer reuses prior mutant outcomes when neither the mutant's code nor its relevant tests changed, turning a repeat vary mutate run into a sequence of lookups instead of fresh bytecode patching and test dispatch.
Unlike --incremental, which short-circuits an entire file when the source and test files match the prior run, --incremental-infer makes the reuse decision per mutant. New mutants still execute; prior ones are re-used only when every safety gate passes.
For the basics, see Introduction.
vary mutate src/foo.vary -t tests/test_foo.vary --incremental-infer
The inference artifact is written to .vary/inference/<12-char-source-path-hash>.inference relative to the working directory. The hash is derived from the absolute source path so two files with the same basename in different directories never collide.
Text-based, human-inspectable, schema version 1:
# Vary Mutation Inference
schema_version=1
source_hash=<sha-256 of source file>
test_hash=<sha-256 of test file>
compiler_version=<compiler version at write time>
operators=<sorted, comma-separated operator set>
timestamp=<ms since epoch>
# Entries
<mutant-id>|<outcome>|<killed-by;...>|<execution-ms>|<code-fp>|<tests-fp>
Outcomes persisted: KILLED, SURVIVED, TIMEOUT, EQUIVALENT. Non-equivalent engine ERRORs are never persisted, so a transient compilation or runtime failure cannot poison a future run.
Any gate that fails forces fresh execution for the affected mutant(s). The gates are conservative by design.
All must hold; otherwise the entire entry set is dropped.
| Gate | What must match |
|---|---|
| Schema version | Current code's SCHEMA_VERSION |
| Source hash | SHA-256 of the current source file |
| Test hash | SHA-256 of the current test file |
| Compiler version | Current ArtifactId.COMPILER_VERSION |
| Operator set | Stored operators is a non-empty subset of the current run's operator set |
The operator-set rule means widening the set (for example, adding relational) keeps prior arithmetic entries inferrable; narrowing invalidates the entire store.
Even after the store loads, each mutant is re-checked.
| Gate | What it validates |
|---|---|
| Stable id | The mutation's stable id matches a stored entry. An operator change that removes or renames the mutation simply fails to look up. |
codeFingerprint | Equals sha-256(symbolPath|type|original|mutated|line) for the current run's mutation. Catches a generator evolving to emit a different transform for the same id. |
testsFingerprint | Equals sha-256(sorted-csv of covering-test names, or "*" if no coverage). Catches changes to the covering-tests set even when source and tests are byte-identical. |
| Stored outcome | Is not ERROR. |
Each mutant in the JSON report carries two redundant fields:
{
"id": "add#ARITHMETIC#0",
"killed": true,
"inferred": false,
"resolution": "executed"
}
| Combination | Meaning |
|---|---|
inferred: true / resolution: "inferred" | Outcome reused from a prior compatible run |
inferred: false / resolution: "executed" | Freshly executed (no prior entry applied, or a gate failed) |
The survivor-tail flake-detection rerun skips inferred mutants, because re-running them would defeat the point of inference. A mutant killed in the prior run via a flake-induced rerun is persisted as KILLED with its original killedBy, so inference preserves the final classification, not the intermediate one.
| Non-goal | Detail |
|---|---|
| Per-method or per-statement invalidation granularity | Any edit to the source file invalidates all entries |
| Cross-file dependency tracking | If the mutated file depends on another module and that module changes, the gate on this file's source_hash still passes. Delete .vary/inference/ to force a fresh run. |
| Project-mode inference | Inference is wired into the single-file AST runner path used by vary mutate <file.vary>. Project-mode (vary mutate <dir>) does not pass an inference file through to the per-file runner. |
| Bytecode-backend inference | The fresh-loader, hot-swap, and redefine backends each own their own execution loop and do not yet consult the AST-level inference store. |