Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Mutation Cleanup

ASecurity

Works through the surviving mutants that cargo-mutants reports for packages/engine — classify each one as a real test gap, a mutant not worth killing, or dead code, then fix it and verify with `just mutants-diff`. Use when picking up the weekly "Mutatietesten" issue, when asked to improve engine test coverage, or when a pull request fails the Mutation Testing (diff) gate.

23 stars
0 votes
0 copies
0 views
Added 9/24/2026
testingrustgobashtestinggit

Security Analysis

A100/100

Scanned 9/24/2026

$npx -y skills add MinBZK/regelrecht --skill mutation-cleanup --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mutation Cleanup?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Mutation Cleanup
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/minbzk-mutation-cleanup/badge)](https://www.skillsdirectory.com/skills/minbzk-mutation-cleanup)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: mutation-cleanup
description: Works through the surviving mutants that cargo-mutants reports for packages/engine — classify each one as a real test gap, a mutant not worth killing, or dead code, then fix it and verify with `just mutants-diff`. Use when picking up the weekly "Mutatietesten" issue, when asked to improve engine test coverage, or when a pull request fails the Mutation Testing (diff) gate.
allowed-tools: Read, Grep, Glob, Edit, Write, Bash
---

# Mutation cleanup

Surviving mutants are the engine's untested behaviour, listed. This skill is the
method for working them down, so that every round is worked the same way and the
weekly count means the same thing from week to week.

## What a surviving mutant is

`cargo-mutants` applies one small change to the engine at a time (flip a
comparison, delete a match arm, return `Default::default()` from a function) and
runs the test suite. A mutant that survives is a change no test noticed. That is
either a gap in the tests or code nothing depends on.

It is not a bug report. The mutated code is not in the repository, and the count
on its own says nothing about correctness. It says how much of the engine's
behaviour the tests actually pin down.

Two workflows produce them:

- `.github/workflows/mutation-testing.yml` runs the full set every Monday and
  opens an issue labelled `mbot:survivors` with the counts and a report.
- `.github/workflows/mutation-diff.yml` runs on every pull request that touches
  `packages/engine/**`, over the changed lines only. That gate is why new gaps
  should not reach this backlog.

## Step 1: Get the list

From the weekly issue, take the run id and download the report:

```bash
gh run download <RUN_ID> -n mutation-report
```

`missed.txt` has one line per surviving mutant: file, line, column, and the
change that was applied. `caught.txt`, `timeout.txt` and `unviable.txt` hold the
rest. `README.md` in the same artifact has the counts and the per-file
distribution.

Working from a failing pull-request gate instead? The gate splits its mutants
over shards, and each shard leaves its files in its own artifact,
`mutation-report-diff-shard-N`. Only a red shard has something to fix; the
list is short by construction.

## Step 2: Work one file at a time

Not one line at a time. Mutants cluster in a handful of files, and the context
built reading a file pays off across all of its mutants. Take the files in
descending order of surviving count; the distribution is in the report.

## Step 3: Classify before touching anything

Every mutant is one of three things. Decide which before writing code.

### A real gap in the tests

Write a test that fails on the mutated code and passes on the real code. Verify
it in that order: apply the mutation by hand, watch the test go red, revert the
mutation, watch it go green. A test you did not see fail proves nothing.

Put the test where the behaviour lives. Unit tests for a single function, a BDD
scenario when the gap is about how a law evaluates end to end. A mutant in
`operations.rs` that changes a comparison usually wants a unit test; one in
`service.rs` that changes resolution order usually wants a scenario.

Before writing a new test, check whether one already claims to cover this. Often
a mutant survives next to a test that reads as though it pins the behaviour. Then
the gap is that test, and the fix is to make its fixture construct the premise
its own doc-comment describes. A survey of this repository found fourteen such
tests: a longest-prefix test with no shorter competing article, a retain test
whose only candidate was filtered out upstream, an assertion about a variable
nothing references. Each one was a mutation survivor, and each read as coverage.

Rewriting the existing test beats adding a second one beside it. A second test
leaves the first as a decoy for the next reader.

### A mutant that says nothing

Debug helpers, `Display` implementations, `bin/` targets such as
`validate_annotations.rs`, WASM binding shims. Pinning these down with
assertions adds maintenance and no safety.

Record the decision so it stays recorded:

```rust
#[mutants::skip]  // Debug-only; asserting on the format pins nothing that matters.
fn render_internal(&self) -> String { … }
```

or, for a whole area, an `exclude_re` entry in `packages/.cargo/mutants.toml`
with a comment saying why. This is a valid outcome, not a way out. The count
drops because the question was answered, and the next reader inherits the
answer instead of the question.

### Dead code

Delete it. Do not write a test around code that nothing calls. Check first that
it is genuinely unreachable and not merely unused by tests.

## Limits

The engine decides legal outcomes: benefit entitlements, allowances, tax
calculations. These limits follow from that.

- Never write an assertion that pins an arbitrary implementation detail just to
  kill a mutant. A test describes behaviour that is wanted. If you cannot say
  which behaviour a test protects, it is the wrong test.
- If killing a mutant means changing behaviour rather than coverage, stop and
  raise it. A surviving mutant can be the first sign that the code is wrong, and
  that is a decision for a human, not a cleanup.
- Never weaken or delete an existing test to make something pass.
- `REVIEW.md` in the repository root holds the project's review dimensions and
  applies here too.

## Step 4: Verify

```bash
just mutants-diff        # mutates only your own changed lines, minutes not hours
just mutants             # the full set, over five hours; CI shards it instead
```

`just mutants-diff` must be clean before committing. It runs the same check as
the pull-request gate, so a clean result here means a green gate there.

Exit code 2 means a mutant survived in your own changed lines, which is the
gate doing its job. Exit code 3 means a test ran out of time under mutation.

Commit per file, in small commits, conventional-commit subjects in Dutch.

## What the numbers do next

The weekly run compares against the previous week and reports what is new, what
was solved, and what moved between `caught` and `timeout`. As long as more than
25 mutants survive, the timeout multiplier stays fixed so the weeks stay
comparable. Below that it starts rotating over 3, 2 and 5, which exposes mutants
that only die because a test ran out of time rather than because an assertion
caught them. Those are the next layer of the same question, and the same three
classifications apply to them.

Attribution

MinBZKMinBZK
View sourceSee grades on GitHubMore from MinBZK →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Screen Reader Testing

Practical guide to testing web applications with screen readers for comprehensive accessibility validation.

401991 votes

Tdd Workflow

在编写新功能、修复错误或重构代码时使用此技能。强制执行测试驱动开发,包含单元测试、集成测试和端到端测试,覆盖率超过80%。

2456590 votes

Eval Harness

克劳德代码会话的正式评估框架,实施评估驱动开发(EDD)原则

2456590 votes

Python Testing

使用pytest、TDD方法、夹具、模拟、参数化和覆盖率要求的Python测试策略。

2456590 votes

Django Tdd

Django测试策略,包括pytest-django、TDD方法论、factory_boy、模拟、覆盖率以及测试Django REST Framework API。

2456590 votes
View all in testing →