Files
werkator/docs/prs/2026-10-04-PR#116-health-and-system-view.md
miandmhoennig d4376f3eb8
werkator build succeeded after 02:00
werkator/deploy build succeeded after 00:07
werkator/mutation build succeeded after 48:37
Disk health verdict judges budget and volume separately, System page assembled from its sections, history peaks per metric (v1.35.2) (#116)
## The Problem

The health verdict and the System page view held three methods above the Mutation-CRAP limit of 15:

| Method                                | Mutation-CRAP | Complexity | What it did in one body                                                                    |
| ------------------------------------- | ------------- | ---------- | ------------------------------------------------------------------------------------------ |
| `SystemHealth.assess$diskUtilization` | 31.28         | 15         | judged a disk's budget, softened a full quota, and judged the volume behind it             |
| `SystemMetricsView.from`              | 25.28         | 24         | built the verdict panel, the gauges, the disk notes, the tiles, and the totals of the page |
| `HistoryPeaks.of`                     | 16.38         | 9          | collected the totals, found each peak, and judged it                                       |

`assess` sorted its findings into two lists by three local functions that each repeated the same `when` over the level.
The rule "a quota can be raised by asking" stood twice, in `SystemHealth` and in `CapacitySizing`, and the load thresholds twice, in `SystemHealth.loadLevel` and `HistoryPeaks.loadLevel`.

This is the second of seven groups the methods above 15 fall into; each group gets its own PR.

## Non-Goals

- No change in the verdict, its reasons and their order, the peaks, or what the System page shows.

## The Scenarios

No scenario changes: the verdict, the peaks and the page keep their tests, unchanged.

##### Verified by

- [SystemHealthUnitTest](../../src/test/kotlin/de/hoennig/werkator/metrics/SystemHealthUnitTest.kt)
- [CapacitySizingUnitTest](../../src/test/kotlin/de/hoennig/werkator/metrics/CapacitySizingUnitTest.kt)
- [UiViewsUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt)

## The Solution

- `SystemHealth.assess` names its findings one after the other into `Findings`, which sorts them into overload and pressure and gives the verdict.
  `judgeDisk` judges a disk twice: its budget (`budgetLevel`, a full quota only presses) and the volume behind a quota.
- `DiskMetrics.budgetIsAskable` is the one rule whether a budget is raised by asking, used by the verdict and the sizing advice.
  It is an extension, so the JSON of a disk does not grow a field.
- `SystemMetricsView.from` assembles the page from its sections: `healthOf`, `gaugesOf` with `diskGauge` and `diskNote`, and `tilesOf` with `loadOf` and `swapOf`.
- `HistoryPeaks.of` reads as `totalsOf` and `peakOf`; the load of a peak is judged by `SystemHealth.loadLevel`, and `HistoryPeaks.loadLevel` is gone.

Measured with PIT as the nightly build runs it:

| Method                                | Before | After |
| ------------------------------------- | ------ | ----- |
| `SystemHealth.assess$diskUtilization` | 31.28  | gone  |
| `SystemMetricsView.from`              | 25.28  | 5     |
| `HistoryPeaks.of`                     | 16.38  | 2     |
| `SystemHealth.assess`                 | —      | 3     |
| `SystemHealth.judgeDisk`              | —      | 3.58  |
| `SystemHealth$Findings.verdict`       | —      | 5     |
| `DiskMetrics.budgetIsAskable`         | —      | 4     |
| `SystemMetricsView.diskGauge`         | —      | 10.86 |
| `SystemMetricsView.tilesOf`           | —      | 5     |
| `SystemMetricsView.diskNote`          | —      | 4     |
| `HistoryPeaks.peakOf`                 | —      | 6.14  |
| `HistoryPeaks.columnOf`               | —      | 6.6   |

No method of the group scores above 11, and none is `INCONCLUSIVE`.

The gate `maxMutationCrap` falls from 32 to 31: the highest score left is `GitService.authenticated` at 30.12.

## Additional Changes

- Version 1.35.2 with its release note.

## Follow-up PRs

The five groups left above 15, one PR each: Git and Gitea access, sizing advice, installation, the watcher's triggering and retention, build lists and the repository line.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: mhoennig <michael@hoennig.de>
Reviewed-on: #116
2026-10-04 22:13:00 +02:00

71 lines
4.2 KiB
Markdown

> **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 health verdict and the System page view held three methods above the Mutation-CRAP limit of 15:
| Method | Mutation-CRAP | Complexity | What it did in one body |
| ------------------------------------- | ------------- | ---------- | ------------------------------------------------------------------------------------------ |
| `SystemHealth.assess$diskUtilization` | 31.28 | 15 | judged a disk's budget, softened a full quota, and judged the volume behind it |
| `SystemMetricsView.from` | 25.28 | 24 | built the verdict panel, the gauges, the disk notes, the tiles, and the totals of the page |
| `HistoryPeaks.of` | 16.38 | 9 | collected the totals, found each peak, and judged it |
`assess` sorted its findings into two lists by three local functions that each repeated the same `when` over the level.
The rule "a quota can be raised by asking" stood twice, in `SystemHealth` and in `CapacitySizing`, and the load thresholds twice, in `SystemHealth.loadLevel` and `HistoryPeaks.loadLevel`.
This is the second of seven groups the methods above 15 fall into; each group gets its own PR.
## Non-Goals
- No change in the verdict, its reasons and their order, the peaks, or what the System page shows.
## The Scenarios
No scenario changes: the verdict, the peaks and the page keep their tests, unchanged.
##### Verified by
- [SystemHealthUnitTest](../../src/test/kotlin/de/hoennig/werkator/metrics/SystemHealthUnitTest.kt)
- [CapacitySizingUnitTest](../../src/test/kotlin/de/hoennig/werkator/metrics/CapacitySizingUnitTest.kt)
- [UiViewsUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt)
## The Solution
- `SystemHealth.assess` names its findings one after the other into `Findings`, which sorts them into overload and pressure and gives the verdict.
`judgeDisk` judges a disk twice: its budget (`budgetLevel`, a full quota only presses) and the volume behind a quota.
- `DiskMetrics.budgetIsAskable` is the one rule whether a budget is raised by asking, used by the verdict and the sizing advice.
It is an extension, so the JSON of a disk does not grow a field.
- `SystemMetricsView.from` assembles the page from its sections: `healthOf`, `gaugesOf` with `diskGauge` and `diskNote`, and `tilesOf` with `loadOf` and `swapOf`.
- `HistoryPeaks.of` reads as `totalsOf` and `peakOf`; the load of a peak is judged by `SystemHealth.loadLevel`, and `HistoryPeaks.loadLevel` is gone.
Measured with PIT as the nightly build runs it:
| Method | Before | After |
| ------------------------------------- | ------ | ----- |
| `SystemHealth.assess$diskUtilization` | 31.28 | gone |
| `SystemMetricsView.from` | 25.28 | 5 |
| `HistoryPeaks.of` | 16.38 | 2 |
| `SystemHealth.assess` | — | 3 |
| `SystemHealth.judgeDisk` | — | 3.58 |
| `SystemHealth$Findings.verdict` | — | 5 |
| `DiskMetrics.budgetIsAskable` | — | 4 |
| `SystemMetricsView.diskGauge` | — | 10.86 |
| `SystemMetricsView.tilesOf` | — | 5 |
| `SystemMetricsView.diskNote` | — | 4 |
| `HistoryPeaks.peakOf` | — | 6.14 |
| `HistoryPeaks.columnOf` | — | 6.6 |
No method of the group scores above 11, and none is `INCONCLUSIVE`.
The gate `maxMutationCrap` falls from 32 to 31: the highest score left is `GitService.authenticated` at 30.12.
## Additional Changes
- Version 1.35.2 with its release note.
## Follow-up PRs
The five groups left above 15, one PR each: Git and Gitea access, sizing advice, installation, the watcher's triggering and retention, build lists and the repository line.