Skip to content

fix: silent-apply popup + race-write + notification header#26

Merged
carterscode merged 1 commit into
feat/ai-parity-easy-winsfrom
fix/silent-apply-popup-and-race
Jun 3, 2026
Merged

fix: silent-apply popup + race-write + notification header#26
carterscode merged 1 commit into
feat/ai-parity-easy-winsfrom
fix/silent-apply-popup-and-race

Conversation

@carterscode

Copy link
Copy Markdown
Owner

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)`:

Drift contents Header
Single Windows AI policy "Windows AI setting has drifted"
Multiple Windows services "Windows services have drifted"
Single display "Display setting has drifted"
Mixed categories "N monitored settings have drifted"

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

  • 153/153 unit tests passing (was 143). 10 new NotificationHeader tests covering empty/null report, every category, pluralization, mixed-category fallback, unknown-category graceful fallback.
  • SettingsSearchAi ReadCurrent fix verified by inspection against the user's known-broken registry state.
  • Debug + Release builds clean.
  • Smoke test on the dev build:
    • Click Apply Recommended -> Apply.
    • Background tick: no popup for SettingsSearchAi.
    • Notification window header reflects the correct category if any other setting drifts.
    • `config.json` retains the v0.1.39 AI prefs (not overwritten by MonitorService).

🤖 Generated with Claude Code

…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>
@carterscode carterscode merged commit f4f3c93 into feat/ai-parity-easy-wins Jun 3, 2026
1 check passed
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