# `Mutare.Extension`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.5.1/lib/mutare/extension.ex#L1)

Non-mutating extensions for call routing, `use` expansion, and coverage attribution.

An extension implements one or more of these behaviours:

  * `Mutare.CallRouting` — static or shape-aware macro-argument routing;
  * `Mutare.UseExpansion` — an override for a `use` that cannot be expanded normally;
  * `Mutare.CoverageAttribution` — hooks, installed in the coverage probe's test VM,
    that tell Mutare which test a process with no lineage link to one is working for.

Extensions do not produce mutations or appear in reports. Add them to `:extensions` as modules or `{module, opts}` pairs:

    [extensions: [Mutare.Gettext]]

Entries may be bare modules or `{module, opts}` pairs. Options are delivered to `c:Mutare.UseExpansion.expand_use/3` and `c:Mutare.CoverageAttribution.attach_attribution/1`; `c:Mutare.CallRouting.call_routes/0` declarations and `c:Mutare.CallRouting.route_arguments/1` classification are intentionally options-independent. The probe's test VM receives `attach_attribution/1`'s options as written-out source, so an extension exporting it must be given plain data (atoms, numbers, strings, and lists, tuples and maps of them); anything else is refused here.

Mutators may implement `Mutare.CallRouting` too, but belong under `:mutators`. They are rejected from `:extensions` so their mutation producers cannot be enabled accidentally as routing-only modules.

An extension that routes a library's DSL may declare that library's modules by exporting `required_modules/0` (the same optional callback mutators declare — see `c:Mutare.Mutator.required_modules/0`); `validate!/1` checks each is loadable and aborts with a `Mutare.EnvironmentError` otherwise, so an external-source run fails loudly at startup instead of silently registering routes against nothing.

# `extension?`

```elixir
@spec extension?(term()) :: boolean()
```

Returns whether `module` is loaded and implements at least one extension
capability.

# `validate!`

```elixir
@spec validate!(term()) :: [Mutare.Extension.Spec.t()]
```

Validates and resolves an `:extensions` list.

Entries may be modules, `{module, options}` pairs, or resolved
`Mutare.Extension.Spec` structs. Raises `ArgumentError` for invalid entries.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
