Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
The Problem
The nightly mutation build has been red since the gate reached the target of 15 (PR#126).
Five methods are above 15; three of them belong to the build lists and are above 15 in every run:
Method
Mutation-CRAP
Complexity
Killed / eligible
RepoSummaryView.from
17.44
13
26 / 37
BuildRowView.from
16.40
10
6 / 10
UiController.baseModel
15.69
10
8 / 13
PR#126 missed them: the method list came from the build log, which shows only the five highest scores.
RepoSummaryView.from counted with the inline count three times, so three loops and their overflow checks were compiled into one method.
BuildRowView.from(BuildResult, …) was a second copy of the row mapping, used by the artifact page only.
Every other page builds its row from the API's BuildResultDto since PR#43, and only those were tested well.
UiController.baseModel also assembled the forge name and the footer.
Non-Goals
The other two methods above 15, RepositoryPrivacy.isPrivate and ConfigLoader.renameLegacySandbox, follow in their own pull requests.
No change of what any page shows.
The Solution
RepoSummaryView.from names each part through one phrase step: the count of matching repositories, or null when none matches.
The artifact page builds its row like every other page, through BuildResultDto.from and BuildRowView.from(BuildResultDto, …).
The copy BuildRowView.from(BuildResult, …) is gone, so a field can no longer be mapped one way on the artifact page and another way in the lists.
UiController.baseModel takes the forge name from forgeName and fills the footer with addFooter.
The test of the summary line also checks that every part is left out when no repository matches.
Measured locally with PIT on the changed classes:
Method
Mutation-CRAP before
after
RepoSummaryView.from
17.44
no mutants
RepoSummaryView.phrase
new
2.00
BuildRowView.from(BuildResult, …)
16.40
gone
UiController.baseModel
15.69
8.81
BuildRowView.from(BuildResultDto, …)
< 13.7
11.19
highest of the three classes
17.44
13.08
The gate stays at 15.
Follow-up PRs
RepositoryPrivacy.isPrivate (16.40) gets tests for its surviving mutants.
ConfigLoader.renameLegacySandbox (15.93) is split, and ConfigLoader.checkRestartsInstance (exactly 15.00) gets room below the target.
> Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
## The Problem
The nightly mutation build has been red since the gate reached the target of 15 (PR#126).
Five methods are above 15; three of them belong to the build lists and are above 15 in every run:
| Method | Mutation-CRAP | Complexity | Killed / eligible |
|--------------------------|--------------:|-----------:|------------------:|
| `RepoSummaryView.from` | 17.44 | 13 | 26 / 37 |
| `BuildRowView.from` | 16.40 | 10 | 6 / 10 |
| `UiController.baseModel` | 15.69 | 10 | 8 / 13 |
PR#126 missed them: the method list came from the build log, which shows only the five highest scores.
- `RepoSummaryView.from` counted with the inline `count` three times, so three loops and their overflow checks were compiled into one method.
- `BuildRowView.from(BuildResult, …)` was a second copy of the row mapping, used by the artifact page only.
Every other page builds its row from the API's `BuildResultDto` since PR#43, and only those were tested well.
- `UiController.baseModel` also assembled the forge name and the footer.
## Non-Goals
- The other two methods above 15, `RepositoryPrivacy.isPrivate` and `ConfigLoader.renameLegacySandbox`, follow in their own pull requests.
- No change of what any page shows.
## The Solution
- `RepoSummaryView.from` names each part through one `phrase` step: the count of matching repositories, or null when none matches.
- The artifact page builds its row like every other page, through `BuildResultDto.from` and `BuildRowView.from(BuildResultDto, …)`.
The copy `BuildRowView.from(BuildResult, …)` is gone, so a field can no longer be mapped one way on the artifact page and another way in the lists.
- `UiController.baseModel` takes the forge name from `forgeName` and fills the footer with `addFooter`.
- The test of the summary line also checks that every part is left out when no repository matches.
Measured locally with PIT on the changed classes:
| Method | Mutation-CRAP before | after |
|----------------------------------------|---------------------:|-----------:|
| `RepoSummaryView.from` | 17.44 | no mutants |
| `RepoSummaryView.phrase` | new | 2.00 |
| `BuildRowView.from(BuildResult, …)` | 16.40 | gone |
| `UiController.baseModel` | 15.69 | 8.81 |
| `BuildRowView.from(BuildResultDto, …)` | < 13.7 | 11.19 |
| highest of the three classes | 17.44 | 13.08 |
The gate stays at 15.
## Follow-up PRs
- `RepositoryPrivacy.isPrivate` (16.40) gets tests for its surviving mutants.
- `ConfigLoader.renameLegacySandbox` (15.93) is split, and `ConfigLoader.checkRestartsInstance` (exactly 15.00) gets room below the target.
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The artifact page builds its row through BuildResultDto like every other
page, so the second row mapping from BuildResult is gone. RepoSummaryView
names its parts through one phrase step, and baseModel takes the forge
name and the footer from their own steps. Three of the five methods above
the Mutation-CRAP target of 15 are below it now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-code
changed title from WIP: Build rows, repository summary and page model split into steps to Build rows, repository summary and page model split into steps (v1.37.10)2026-10-09 12:48:20 +02:00
mi
merged commit 01b55120d4 into main2026-10-09 12:49:45 +02:00
mi
deleted branch mihoe/build-row-views2026-10-09 12:49:45 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The Problem
The nightly mutation build has been red since the gate reached the target of 15 (PR#126).
Five methods are above 15; three of them belong to the build lists and are above 15 in every run:
RepoSummaryView.fromBuildRowView.fromUiController.baseModelPR#126 missed them: the method list came from the build log, which shows only the five highest scores.
RepoSummaryView.fromcounted with the inlinecountthree times, so three loops and their overflow checks were compiled into one method.BuildRowView.from(BuildResult, …)was a second copy of the row mapping, used by the artifact page only.Every other page builds its row from the API's
BuildResultDtosince PR#43, and only those were tested well.UiController.baseModelalso assembled the forge name and the footer.Non-Goals
RepositoryPrivacy.isPrivateandConfigLoader.renameLegacySandbox, follow in their own pull requests.The Solution
RepoSummaryView.fromnames each part through onephrasestep: the count of matching repositories, or null when none matches.BuildResultDto.fromandBuildRowView.from(BuildResultDto, …).The copy
BuildRowView.from(BuildResult, …)is gone, so a field can no longer be mapped one way on the artifact page and another way in the lists.UiController.baseModeltakes the forge name fromforgeNameand fills the footer withaddFooter.Measured locally with PIT on the changed classes:
RepoSummaryView.fromRepoSummaryView.phraseBuildRowView.from(BuildResult, …)UiController.baseModelBuildRowView.from(BuildResultDto, …)The gate stays at 15.
Follow-up PRs
RepositoryPrivacy.isPrivate(16.40) gets tests for its surviving mutants.ConfigLoader.renameLegacySandbox(15.93) is split, andConfigLoader.checkRestartsInstance(exactly 15.00) gets room below the target.🤖 Generated with Claude Code
WIP: Build rows, repository summary and page model split into stepsto Build rows, repository summary and page model split into steps (v1.37.10)