fix: silent-apply popup + race-write + notification header#26
Merged
carterscode merged 1 commit intoJun 3, 2026
Merged
Conversation
…ion header
Three bugs surfaced by a user report on the v0.1.39 dev build:
1. The "Search box AI suggestions + taskbar companion" toggle had
Auto-apply silently ticked, yet the drift popup kept firing every
tick. Root cause: SettingsSearchAiMonitor.ReadCurrent used strict
AND on (DisableSearchBoxSuggestions == 1 AND TaskbarCompanion == 0),
but verifying on the user's machine showed:
HKCU\...\Policies\...\Explorer\DisableSearchBoxSuggestions = 1
HKCU\...\Advanced\TaskbarCompanion = VALUE MISSING
Explorer apparently ignores the non-standard TaskbarCompanion value
name and never persists it. ReadCurrent kept reporting "on" because
`companion == 0` was false (companion was null). Verify failed every
tick -> 15-min backoff -> drift item promoted to the notification
queue every cycle. Fix: treat companion as off when null OR 0; only
companion == 1 counts as "still on". The primary DisableSearchBox-
Suggestions value remains the authoritative signal.
2. The notification window's header was hard-coded "Display settings
have drifted" -- a holdover from when only HDR/Refresh were
monitored. With Windows AI, services, and global gaming all in the
monitor list, the message was actively wrong for most drifts.
Replaced with NotificationHeader.For(report) that picks a category-
appropriate header based on the drift items' DisplayKey (global
gaming / Windows AI / Windows service / Display / mixed-count
fallback). Extracted into Services/NotificationHeader.cs so it can
be unit-tested without standing up a WPF window.
3. MonitorService.TickAsync had a spurious `_store.Save(config)` after
the CheckDrift loop. Nothing in the tick mutates config, so the save
was a no-op -- except it raced with the user clicking Apply in
Settings: if the user's save landed between MonitorService's Load
and Save, MonitorService's save overwrote the user's prefs (silently
dropping any newly-added AppConfig properties, e.g. the v0.1.39
Windows AI prefs that don't exist in stale snapshots). This is why
the user's config.json showed zero AI prefs even after they clicked
Apply Recommended + Apply. Removed the save with a comment.
Tests: 10 new NotificationHeader tests cover empty/null report, single
category labeling (AI, service, display, global), pluralization, mixed-
category fallback, unknown-category graceful fallback. The fix to
SettingsSearchAi.ReadCurrent is verified manually against the user's
known-broken state -- a unit test would need registry mocking we don't
currently have. 153/153 passing (was 143). Release + Debug builds clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three bug fixes from user feedback on the dev build, stacked on top of PR #25.
1. Search box AI suggestions popup keeps firing despite Auto-apply silently being ticked
Repro: Click Apply Recommended -> Apply. The popup keeps reappearing every ~30 s for "Search box AI suggestions + taskbar companion -- disable" even though the row shows Auto-apply silently checked.
Root cause: Verified on the user's machine:
```
HKCU...\Policies...\Explorer\DisableSearchBoxSuggestions = 1
HKCU...\Advanced\TaskbarCompanion = VALUE MISSING
```
`SettingsSearchAiMonitor.ReadCurrent` used strict AND: `disable == 1 && companion == 0`. With companion null (Explorer apparently ignores that non-standard value name and never persists it), the AND was always false -> ReadCurrent reported "on" -> verify failed every cycle -> 15-minute auto-apply backoff -> drift item promoted to the notification queue every cycle.
Fix: Treat companion as off when null OR 0; only `companion == 1` counts as "still on." The primary `DisableSearchBoxSuggestions` value remains the authoritative signal. Apply still writes both values for belt-and-suspenders coverage.
2. Notification header hard-coded "Display settings have drifted"
Wrong for almost every drift today (the notification in the user's screenshot was a Windows AI policy). Replaced with category-aware `NotificationHeader.For(report)`:
Extracted into `Services/NotificationHeader.cs` so it's unit-testable without standing up a WPF window.
3. MonitorService race-write that silently drops user prefs
`MonitorService.TickAsync` ended with `_store.Save(config);`. Nothing in the tick mutates config -- the save was a no-op except for racing with the user's Settings-window Apply: if the user's save landed between MonitorService's Load and Save, MonitorService's stale save overwrote the user's prefs.
This is why the user's `config.json` showed zero AI prefs even after they clicked Apply Recommended + Apply. MonitorService had loaded a snapshot before those properties existed and silently dropped them on save.
Removed the save with a comment explaining why.
Test plan
🤖 Generated with Claude Code