- Target: Mutation-CRAP at most 15 for Kotlin, code city red from 12 (score never below complexity; JaCoCo counts compiler-generated Kotlin branches). - Gate `maxMutationCrap = 650` as a ratchet (today max 647.55), lowered with every refactoring PR down to 15. - werkcrappit 0.15.0 -> 0.16.4 for `codeCharta.colorRedFrom`. - AGENTS.md: rule, ratchet, split along domain steps. PR-doc: `docs/prs/2026-10-04-PR#104-mutation-crap-limits.md` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: mhoennig <michael@hoennig.de> Reviewed-on: #104
3.7 KiB
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
The Problem
The nightly build mutation reports every method's Mutation-CRAP, but it judged nothing: no limit, and the code city coloured by werkcrappit's defaults.
The first full report has 108 methods at 10 or above, the limit used for Java projects.
The score is C² × (1 − MS)³ + C, so it never falls below the method's complexity: a limit of 10 is also a complexity limit of 9, however well a method is tested.
JaCoCo counts the branches of the bytecode, and the Kotlin compiler adds branches nobody wrote: the implicit else of an exhaustive when, the branches of inlined let and takeIf.
Java's 10 would therefore ask for smaller methods than the same code needs in Java.
Non-Goals
- No method is changed here; the refactorings follow, one PR per domain area.
- No limit for Java projects: they keep 10.
?.and?:stay real branches: a surviving mutant there is a missing test, and the mutation part of the score still says so.
The Scenarios
Feature: Werkator's methods aim at a Mutation-CRAP of at most 15
Scenario#104.01: The code city shows red from 12
So that the methods to look at next stand out before they reach the limit.
- Given the nightly build
mutation - When werkcrappit writes the code city and its viewer link
- Then a method from 12 on is red, from 6 on yellow
Verified by
- The build definition
mutationon werkator.javagil.de, whose code city link carries the colour range.
Scenario#104.02: The gate is a ratchet towards 15
So that nothing gets worse while the 45 methods above 15 are refactored, and the nightly build keeps its meaning.
- Given today's highest score of 647.55
- When the nightly build runs with
maxMutationCrap = 650 - Then it passes today and fails as soon as a method scores above 650
- And every refactoring PR lowers the limit to just above the new highest score, until it reaches 15
Verified by
- The build definition
mutationon werkator.javagil.de (mutationCrapCheck).
The Solution
- werkcrappit 0.15.0 → 0.16.4, for
codeCharta.colorRedFrom. maxMutationCrap = 650andcolorRedFrom = 12inbuild.gradle.kts, with the reasoning as a comment.AGENTS.mdstates the target, the ratchet, and that a method above 15 is split along its domain steps.
Why 15 and 12:
| Score | Methods at or above | of which by complexity alone | of which by weak tests |
|---|---|---|---|
| 10 | 108 | 58 | 50 |
| 12 | 84 | 34 | 50 |
| 15 | 45 | 15 | 30 |
At 15 the complexity cases left are the genuine ones (BuildExecutor.execute 40, SystemMetricsCollector.sample 35, BuildDefinition.applyTo 34); the test gaps stay almost all visible.
NIST SP 500-235 names 10 as the complexity limit and up to 15 as acceptable for experienced teams with well-tested code.
Additional Changes
- Version 1.34.1 with its release note.
Follow-up PRs
- The home page's repository card (
HomeCardView.from,HomeTexts.meta), thenBuildExecutor.execute,ConfigLoader, metrics and sizing, the Forgejo export, and the environment probes; each lowers the ratchet.
