Skip to content

fix(sync): skip Unset local prefs so remote drives the write#72

Merged
fullstackjam merged 2 commits into
mainfrom
fix/sync-skip-unset-local-prefs
May 16, 2026
Merged

fix(sync): skip Unset local prefs so remote drives the write#72
fullstackjam merged 2 commits into
mainfrom
fix/sync-skip-unset-local-prefs

Conversation

@fullstackjam
Copy link
Copy Markdown
Collaborator

Summary

  • diffMacOSPrefs was including locally-captured Unset prefs in the lookup map. Their Value is the catalog default placeholder, not what defaults read actually returned — so when a remote pref had the same value (the common case after feat(macos): capture "unset" state instead of silently dropping prefs #67/fix(macos): publish Unset prefs too — they carry the catalog default #68), the diff falsely matched and no defaults write was issued. Result: the key stayed absent on disk and macOS kept showing the default behaviour (e.g. menu bar Sound/Bluetooth/WiFi/Battery stuck on "Show When Active" after installing a config that explicitly sets them to "Always Show").
  • Skip Unset prefs from the local lookup map so they count as "missing" and surface in MacOSChanged. Matches the existing semantics in internal/diff/compare.go:diffMacOS ("Unset prefs on either side mean 'no opinion'").
  • Extract the comparison core into computeMacOSPrefDiff so the regression is unit-testable without going through real defaults read.

Repro that motivated this

Installing fullstackjam/jam-s-packages on a machine where Bluetooth/WiFi/Battery were never explicitly set:

  • Remote config: com.apple.controlcenter Bluetooth=18 (Always Show in Menu Bar), same for WiFi/Battery
  • Local capture: Bluetooth recorded as Unset with placeholder value 18 (catalog default)
  • Pre-fix diff: 18 == 18 → no diff → no write → defaults read com.apple.controlcenter Bluetooth still says "does not exist" after install
  • Post-fix: Bluetooth surfaces as needing a write; install runs the defaults write

Test plan

  • New unit tests in internal/sync/diff_extra_test.go exercising the three meaningful cases (Unset local → missing, explicit match → no diff, explicit differ → diff)
  • go test ./internal/... (L1 incl. archtest) — green
  • go vet ./... — clean

`diffMacOSPrefs` was treating locally-captured Unset prefs as if their
placeholder value (catalog default) were the actual machine state. When
a remote pref had the same value, the diff falsely matched and no
`defaults write` was issued — so the key remained absent on disk and
macOS kept showing the default behaviour.

Concretely: `fullstackjam`'s published config includes
`com.apple.controlcenter Bluetooth=18` (Always Show in Menu Bar). On a
fresh consumer machine, `CaptureMacOSPrefs` records `Bluetooth` with
Unset=true and the catalog's "18" placeholder. The diff matched 18==18
and skipped the write, so Bluetooth never appeared in the menu bar.

Filter Unset prefs out of the local lookup map so they count as
"missing" and surface in MacOSChanged. This matches the semantics
already used in `internal/diff/compare.go:diffMacOS` ("Unset prefs on
either side mean 'no opinion'").

Refactor the comparison core out into `computeMacOSPrefDiff` so the
fix is unit-testable without going through real `defaults read`.
@github-actions github-actions Bot added the tests Tests only label May 16, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullstackjam fullstackjam merged commit 8fbc330 into main May 16, 2026
13 checks passed
@fullstackjam fullstackjam deleted the fix/sync-skip-unset-local-prefs branch May 16, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Tests only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant