Add a mutation
A mutation must be semantically preserving: it changes syntax without changing behavior. The framework handles backup, compilation checks, ground-truth tracking, and rollback, so a new mutation only has to perform the transformation. See the Mutations overview for how the pipeline works.
There are two ways to add one, depending on what the transformation needs.
Option 1: a Python mutation
Most mutations (formatting, comment and block insertion, renames) are implemented in the CLI. They subclass BaseMutation and implement a single apply method.
The interface is a single method:
class BaseMutation(ABC):
@abstractmethod
def apply(self, base_dir: str) -> bool:
...
Steps:
- Add a class under
mizan-cli/src/mizan_cli/commands/mutate/mutations/that subclassesBaseMutationand implementsapply(self, base_dir) -> bool. ReturnTrueon success.base_diris the checkout directory (it containssamples/andmizan.json). - Register it in
MUTATION_REGISTRYinmutations/__init__.py, keyed by the identifier users pass tomizan mutate -m. - If your mutation removes comments or otherwise breaks the line markers, follow the content-based tracking approach used by the AST mutations (see the Mutations overview). For most insertions, the default marker tracking is sufficient.
The orchestrator validates that each mutated sample still compiles and that the ground truth is preserved, rolling back any sample that fails. You do not need to handle backup or validation yourself.
Option 2: an AST mutation in mizan-mut
Structural transformations that need real Rust AST manipulation belong in mizan-mut.
Steps:
- Add the mutation under
mizan-mut/src/mutations/usingsynandquote, and wire it into the mutation dispatch inmizan-mut/src/mutate.rs. - Add it to the
MUTATIONSarray indocker/Dockerfile.mutations-testso it is covered by the test suite (see Testing below). - To expose it through the CLI, add a thin
MizanMutMutationsubclass inmizan_mut.pyand register it inMUTATION_REGISTRYwith amizan-mut-prefix, exactly like the existing AST mutations.
Testing
A mutation should preserve program behavior. The mizan-mut repository ships a Docker-based test suite that applies each mutation to real-world crates and checks that their test suites still pass. Use it to test and iterate:
docker build -f docker/Dockerfile.mutations-test -t mizan-mut-test .
docker run mizan-mut-test
Add your mutation to the MUTATIONS array in docker/Dockerfile.mutations-test so it is included in the run, then iterate until the report is clean. For CLI mutations, the orchestrator also compiles each mutated sample and verifies the ground truth before saving, rolling back anything that fails.