Skip to content
mutastic

Mutant ids

Every mutant has an id, m and eight hex digits, such as mb2f8ae57. It’s how you name a mutant to mutastic: mutastic verify <id> checks that one, mutastic run --only=<id> runs only it, and mutastic explain <id> shows what it is. Scripts, CI jobs, ignores and coding agents keep ids, so an id has to keep naming the same mutant while you work.

An id is the start of a SHA-256 over what the mutant is. There’s no line number and no file name in it, so code moving around a mutant doesn’t change it. The fingerprint in --format=jsonl is the same hash, longer.

  • the class, with its package;
  • the method’s name, and its parameter and return types;
  • which site of its kind in the method it is, counted in bytecode order: calls are counted apart from arithmetic, branches and returns;
  • the change, and for most operators the operator’s id.
  • Code moving. Lines added or removed above it, or the method moved within its class.
  • Line breaks, spaces and comments, which the class file doesn’t have.
  • Changes later in the method, and changes earlier in it that add or remove no site of the mutant’s kind.
  • Other operators. A new operator only adds ids, never changes the others’.
  • A different change. A mutant whose change is different is a different mutant, with a new id.
  • The method’s name or types. Renaming the method, its class or its package, or changing its parameter or return types.
  • A site of the same kind added or removed earlier in the method. The count moves: a new condition above a mutant’s moves the ids of the arithmetic, branches and returns below it, and a new call moves the calls’. Run again to see the ids as they are now.

When an id you kept names no mutant of the project, mutastic says so. An id belongs to the project its run was on, so name the project’s directory as that run did.

Terminal window
mutastic 1.1.0 · reading the Cargo package…
mutastic: m00000000 isn't a mutant of pricing: run `mutastic run fixtures/pricing` to see its mutants

Both editions make an id from what the mutant is, and the operator ids are shared: mutastic/boundary means the same change in both. The Rust edition hashes its own name in first, so a Rust id never names a Java mutant.