mutation-audit

mutation-audit is an agent for Claude Code from NickZaitsev/ru-normalizr. It costs 0 tokens per session (4,525 once invoked), scanned A, original, MIT.

A one-time mutation audit using mutmut, a tool that changes source code to test whether the test suite detects those changes.

In plain words
What is it for?
Use it to find missing tests and judge whether surviving code mutations represent real behaviors worth testing.
Why use it?
It shows which behavior tests actually protect, while keeping the unsafe audit away from the main working copy in a separate Git worktree.

Agent for Claude Code

Written for Claude Code: a Claude Code subagent (agents/*.md).

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add agents/nickzaitsev/ru-normalizr/mutation-audit
Clone the repo
git clone --depth 1 https://github.com/NickZaitsev/ru-normalizr

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for mutation-audit

README.md
[![agentmods](https://agentmods.dev/badge/agents/nickzaitsev/ru-normalizr/mutation-audit.svg)](https://agentmods.dev/agents/nickzaitsev/ru-normalizr/mutation-audit)
Your own site
<a href="https://agentmods.dev/agents/nickzaitsev/ru-normalizr/mutation-audit"><img src="https://agentmods.dev/badge/agents/nickzaitsev/ru-normalizr/mutation-audit.svg" alt="Measured on agentmods" height="20"></a>
Per session 0 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 4,525 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00000 $0.04525
Opus 5 $0.00000 $0.02263
Sonnet 5 $0.00000 $0.00905
Haiku 4.5 $0.00000 $0.00453

Measured 6d ago against content hash 4b155db60edc, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-05, from the pricing page.

Security

Grade A, and why

mutation-audit scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 6d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

docs/agents/mutation-audit.md · 277 lines

How it starts

The opening of the file, as written. The whole thing — 277 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Мутационный аудит: что закрывать тестом, а что нет

Разовый аудит через mutmut (версия <3 — третья требует POSIX: os.fork, os.wait, resource). Инструмента в репозитории нет и не должно быть: он переписывает исходники на месте и меняет переводы строк на CRLF, поэтому любой прогон делается в отдельном git worktree, никогда в рабочей копии.

Итог по модулям (подтверждённые выжившие — те, что уцелели против полного набора тестов, а не только против узкого):

Модуль Мутантов Выживших Убито
dictionary.py 219 20 91%
abbreviations.py 444 116 74%
years.py 870 252 71%
ordinals.py 498 155 69%
numerals/_helpers.py 905 310 66%

Критерий: убивать мутанта только реальным предложением

Мутант считается убитым, если настоящее русское предложение даёт другой результат. Тест, который подгоняет вход под мутанта или закрепляет заведомо неверный вывод, хуже отсутствия теста: он мешает починить дефект.

Практическое следствие — часть выживших закрывать нечем, и это нормально. Ниже перечислены классы, на которые не стоит тратить время повторно.

Неубиваемые по построению

Мутации строк в проверках принадлежности. mutmut оборачивает литерал как "XX…XX", то есть добавляет символы, а не убирает. Для char in "набор" мутант расширяет набор, и поведение не меняется. Замены элементов кортежа (startswith((".", "!", …))) убиваются нормально, а множества-литералы — нет.

Значения по умолчанию, сравниваемые только с противоположным. vowel_mode="single" и pause_mode="preserve" в expand_person_initials сравниваются лишь с "double" и "comma", поэтому подстановка в значение по умолчанию ничего не меняет.

Винительный падеж, совпадающий с именительным. Ключи "за", "на", "по" в PREPOSITIONS_TO_CASE (years.py): у год/годы и у порядкового числительного неодушевлённого рода винительный совпадает с именительным, поэтому промах по ключу не виден. Мутанты их значений при этом убиваются — неизвестная строка падежа ломает рендеринг.

Read the full file on GitHub · 277 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 6d ago First seen · 277 lines · 0 tokens per session scan A 4b155db60edc

Subscribe to this mod's changes

mutation-audit is an agent published in the GitHub repository NickZaitsev/ru-normalizr (22 stars, last pushed 29d ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 4,525 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.