Skip to content

fix: harden Settings Watchdog against malformed baseline + surface admin requirement#1152

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/settings-watchdog-robustness
Jun 29, 2026
Merged

fix: harden Settings Watchdog against malformed baseline + surface admin requirement#1152
laurentiu021 merged 1 commit into
mainfrom
fix/settings-watchdog-robustness

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

What

Three robustness fixes for the Settings Watchdog tab (#335), all surfaced by an exhaustive multi-agent audit of the recently-shipped features.

Fixes

  1. Crash on malformed baseline (the only user-visible defect found). A settings-baseline.json that's valid JSON but omits the Values property deserialized to a BaselineSnapshot with Values == null; DetectChanges then NRE'd, and the catch in LoadBaseline only covers JsonException/IOException, so it escaped and crashed the Check-now/Refresh command. Fix: LoadBaseline normalizes a null Values to an empty map, and DetectChanges null-guards its baseline argument (defense in depth at the pure trust boundary).
  2. No admin affordance (HIGH UX). The view never bound IsElevated, although the VM already computed it and exposed RelaunchAsAdminCommand. Restoring a machine-wide (HKLM) setting needs admin, so a non-elevated user only learned it failed after the restore. Fix: added the standard not-elevated admin banner (matching CleanupView/TweaksHubView) with a Run-as-administrator button.
  3. Testability seam. Extracted ISettingsWatchdogService so the VM's confirm-gate logic is unit-testable with a substituted service (no real registry/baseline file) — the established IAppBlockerService/IPowerShellRunner pattern.

Tests

  • DetectChanges_NullBaseline_ReturnsEmpty_DoesNotThrow — the crash regression.
  • VM confirm-gate (new SettingsWatchdogViewModelTests): SaveBaseline declined → no write; first-time save skips overwrite-confirm; RestoreSelected declined → no write; RestoreSelected restores each restorable drift; CanExecute false with no restorable drift.

Docs

CHANGELOG 1.51.1, version bump to 1.51.1. README/ARCHITECTURE unchanged (feature behavior is the same; this is internal robustness + an admin affordance).

Part of the post-feature audit remediation (Batch 1 of 6).

…min requirement

- A settings-baseline.json that parses as JSON but omits its Values map
  deserialized to a null map, which then threw a NullReferenceException in
  DetectChanges (escaping LoadBaseline's JsonException/IOException catch) and
  crashed the Check-now/Refresh command. LoadBaseline now normalizes a null
  Values to an empty map, and DetectChanges null-guards its baseline argument
  (defense in depth at the pure trust boundary).
- The view never bound IsElevated, so a non-elevated user restoring a
  machine-wide (HKLM) setting only learned it failed after the fact. Added the
  standard not-elevated admin banner with a Run-as-administrator button bound to
  the VM's existing RelaunchAsAdminCommand.
- Extracted ISettingsWatchdogService so the ViewModel's confirm-gate logic is
  unit-testable with a substituted service (no real registry/baseline file).

Tests: DetectChanges null-baseline regression; VM SaveBaseline/RestoreSelected
confirm-gate (declined -> no write), first-time save skips overwrite-confirm,
RestoreSelected CanExecute false with no restorable drift.
@laurentiu021 laurentiu021 merged commit 7692cf6 into main Jun 29, 2026
4 checks passed
@laurentiu021 laurentiu021 deleted the fix/settings-watchdog-robustness branch June 29, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant