Charlist-sigil mutations: replace a ~c"…" (or ~C"…") charlist with both the empty charlist ~c"" and a non-empty sentinel (~c"mutare"), dropping whichever already equals the original and preserving the sigil head (~C stays ~C). The charlist counterpart of Mutare.Mutators.StringLiteral.
Interpolated charlists are mutated as a whole too, and both replacements always apply (their runtime value can never statically be either); the expressions inside the interpolation stay eligible for their own mutations. That covers the sigil form ~c"a#{x}b" and the legacy single-quoted form 'a#{x}b' — the latter parses as a List.to_charlist/1 call, and its replacements are rendered in the modern ~c syntax.
The non-interpolated legacy form '…' parses as an ordinary list literal ({:__block__, _, [charlist]} carrying the ' delimiter), so its mutations are split by ownership: Mutare.Mutators.List owns the empty collapse (the node is a list literal to it; emitting ~c"" here too would duplicate that mutant), while this family owns the sentinel — 'abc' → ~c"mutare" — so legacy charlist content is challenged exactly like ~c content. An already-sentinel 'mutare' is skipped.
Not mutated: on the RHS of a guard in (when x in ~c"ab") the empty variant ~c"" is dropped — it is x in [] ≡ false, which Mutare.Mutators.Conditional already produces — but the non-empty sentinel ~c"mutare" is kept. Body in expressions keep the empty variant because left-side evaluation is observable.
Filterable variants — qualify a # mutare:ignore filter with :label to suppress just one half (Mutare.Mutator.variants/0): empty (the ~c"") or sentinel (the ~c"mutare").