
Vary's mutation engine goes beyond kill/survive counting. Six pillars work together to tell you *why* mutants survive, *what* to fix, and *how strong* your test suite actually is.

For the basics, see [Introduction](/docs/mutation/testing/). For a worked example, see [Golden path](/docs/mutation/workflow/).

## The six pillars

| Pillar | What it does | Deep dive |
|--------|-------------|-----------|
| **1. Contracts** | Runtime oracles that kill mutants automatically; contract clauses are also mutated to measure specification adequacy | [Contracts](/docs/mutation/contracts/) |
| **2. Observability** | Records reads, writes, assertions, and branches per test to classify *why* survivors escaped | [Observability](/docs/mutation/observability/) |
| **3. Oracle analysis** | Builds a graph of observe statements → values → identifiers; validates oracle quality per test | [Oracle analysis](/docs/mutation/oracle-analysis/) |
| **4. Effect classification** | Tags functions with side-effect categories; skips nondeterministic mutants; seals randomness at test time | [Effects](/docs/mutation/effects/) |
| **5. Signatures & manifest** | Gives every mutant a stable, refactor-proof identity; emits a machine-readable manifest for CI and tooling | [Signatures](/docs/mutation/signatures/) |
| **6. Semantic mutation** | Operators that understand program meaning (field access, nullability, loop boundaries, constructor bindings) and catch bugs that classic syntax-level mutation misses | [Operators: Semantic](/docs/mutation/operators/#semantic-operators) |

## End-to-end flow

When you run `vary mutate`, the engine performs these steps in order:

| Step | Phase | What happens |
|------|-------|-------------|
| 1 | **Discovery** | Scans source for mutation sites, assigns expression IDs and stable signatures |
| 2 | **Effect analysis** | Classifies each function's effects, skips nondeterministic mutants (unless `--unstable`) |
| 3 | **Mutation** | Applies operators to generate mutants at AST and bytecode levels |
| 4 | **Execution** | Runs tests against each mutant; contract violations count as kills |
| 5 | **Observation** | If `--observe` is enabled, records trace data per test |
| 6 | **Oracle validation** | Classifies each test's oracle strength (STRONG / CONSTANT / NONE) |
| 7 | **Scoring** | Computes mutation score, contract adequacy, oracle coverage, effect stability |
| 8 | **Integrity** | Combines the four scores into a weighted composite grade (A to F) |

## Language features that strengthen mutation testing

### Contracts serve two roles

[Contracts](/docs/contracts/) (`in {}`, `out (r) {}`, `post {}`) serve two roles in mutation testing:

| Role | How it works |
|------|-------------|
| **Runtime oracle** | A contract violation during a mutant run counts as a kill, without a specific test for it |
| **Specification adequacy** | Contract clauses are mutated with dedicated operators (`contract_precondition`, `contract_postcondition`, `contract_remove`) to measure whether tests exercise the boundaries contracts define |

### Pure functions simplify diagnosis

A `pure def` function has no side effects. When a mutant survives in a pure function, the cause is always a missing assertion, never hidden state. The `--why` output skips side-effect explanations and points directly at what to test.

### Invariants catch construction mutations

Classes with `invariant {}` blocks kill mutants that corrupt construction arguments, without any test asserting on fields directly.

## Symptom → feature guide

| You notice... | Use this |
|---------------|----------|
| Mutants survive but you don't know why | `--why` + `--observe` ([Observability](/docs/mutation/observability/)) |
| Tests pass but assertions are tautological | [Lie detection](/docs/mutation/lie-detector/) |
| Contract exists but nothing tests its boundary | Contract adequacy score ([Contracts](/docs/mutation/contracts/)) |
| Flaky mutation results | Effect classification ([Effects](/docs/mutation/effects/)) |
| Score changes after a refactor | Stable signatures ([Signatures](/docs/mutation/signatures/)) |
| No `observe` in a test | Oracle validation ([Oracle analysis](/docs/mutation/oracle-analysis/)) |
| Need a CI quality gate | Integrity score + `min_integrity` in `vary.toml` ([Signatures](/docs/mutation/signatures/)) |
| Want to know which survivors are worth investigating | Observability score (see below) |

## Integrity score

The integrity score combines four metrics into a single grade:

| Component | Weight | Source |
|-----------|--------|--------|
| Mutation score | 40% | Fraction of mutants killed |
| Contract adequacy | 20% | Fraction of contract obligations defended |
| Oracle coverage | 20% | Fraction of tests with strong oracles |
| Effect stability | 20% | Fraction of functions with stable effects |

Grades: **A** (90 to 100), **B** (75 to 89), **C** (60 to 74), **D** (40 to 59), **F** (0 to 39). Set a minimum with `min_integrity` in `vary.toml`.

## Observability score

The observability score tracks whether behavioural changes reach an oracle, not just whether the oracle catches them. It reports three metrics:

| Metric | Definition |
|--------|-----------|
| Kill rate | killed / total |
| Observability | (killed + weak-oracle survivors) / total |
| Actionable survivor rate | (all survivors − equivalent-likely) / total |

Observability is always greater than or equal to kill rate. The gap between them shows how many survivors were seen by a test but not caught. These are the easiest to fix (strengthen the assertion). Survivors classified as equivalent-likely reduce the actionable count but do not affect observability.

Set CI gates in `vary.toml`:

```toml
[mutation]
min_observability = 70.0       # Minimum observability percentage
max_unobserved_survivors = 5   # Maximum unobserved survivors allowed
```

## Next steps

| Page | Topic |
|------|-------|
| [Contracts](/docs/mutation/contracts/) | How contracts kill mutants and how contract adequacy works |
| [Observability](/docs/mutation/observability/) | Runtime tracing, differential detection, assertion groups |
| [Oracle analysis](/docs/mutation/oracle-analysis/) | Oracle graph structure, determinism tags, oracle validation |
| [Effects](/docs/mutation/effects/) | Effect tags, nondeterministic filtering, runtime sealing |
| [Signatures](/docs/mutation/signatures/) | Stable identities, expression IDs, mutation manifest |
| [Infrastructure](/docs/mutation/infrastructure/) | Caching, quarantine, policy gates, certificates, CLI reference |
