Make quota warning thresholds configurable

quotaNotificationLevel() and quotaWarningMarkers() hardcoded 80 and 95. macOS
exposes both in its Notifications pane, and no CLI contract is involved, so this
was the smallest real parity gap fully under Plasma control.

Add contents/ui/QuotaThresholds.js holding the whole rule set behind four
functions, plus tests/tst_quota_thresholds.qml. The logic lives in a .pragma
library rather than in main.qml because qmltestrunner cannot instantiate
main.qml, so this is the only way to get behavioural coverage instead of static
assertions alone. Same pattern as UsageDetails.js and UpdateLogic.js.

Details worth calling out:

- Number(null) is 0, not NaN, so an unset or corrupted config entry read
  naively would become a 1% threshold that fires on every provider. The library
  treats every non-number as absent and falls back to the previous defaults.
- A critical threshold below the warning threshold would make "major"
  unreachable. criticalPercent() enforces critical >= warning once, instead of
  leaving each call site to remember. The config SpinBox mirrors the invariant
  with from: quotaWarningPercentSpin.value so the UI cannot express a value the
  runtime would silently correct.
- Changing a threshold resets the notification memo. Without that the memo keeps
  the level each row was last observed at, which would suppress a warning the
  new lower threshold should raise and leave a row armed at a level the new
  higher threshold no longer reaches.
- The markers keep mirroring to 100 - threshold when the bars count down, so a
  threshold expressed on "used" still lands on the same point of the track.

limitResetArmThreshold stays at 80 and is deliberately not tied to the warning
step: it arms reset detection rather than raising a warning. Recorded in TODO.md
so it is not "fixed" later by mistake.

Static assertions in test_feature_parity.sh and test_ui_regressions.sh lock the
config entries, the delegation and the memo reset, and reject the retired
literals. Both were mutation-checked by reintroducing the hardcoded branch and
confirming the assertion fires.

make check and make package pass; the new library ships in the plasmoid.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3f6bfbbeb7Simone committed on 8/15/2026, 11:40:36 AMparentc593f63

Checks

All checks passed
13 files changedLine totals unavailable