fix: harden update, notification, and dialog reliability#702
Merged
Conversation
The production update path (Help menu + auto-update) called download_update() without passing the GitHub release dict, so the checksum-verification block guarded by `if release is not None` was skipped entirely — downloaded artifacts were installed with no integrity check at all. - Attach the originating release to UpdateInfo (non-compared field) so download_update() can locate the checksum asset itself. - Make verification fail-closed: when a checksum asset exists, any failure to download/parse/match it raises ChecksumVerificationError and the artifact is deleted. Refuse to install when no release metadata is available at all. - Harden config load: a non-numeric precipitation_likelihood_threshold no longer raises and wipes the entire config to defaults (use _as_float). - macOS update script: shell-quote interpolated paths and mount the specific hdiutil mountpoint instead of globbing /Volumes/*. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- system_tray.show_main_window: declare Win32 signatures via WinDLL so the 64-bit HWND isn't truncated to c_int (the sibling of fix #698 that was missed at this call site). - NOAA radio dialog: guard the background-thread completion handlers against a closed dialog (the old `_station_choice is None` check could never fire), and warm the per-call-sign WeatherIndex cache for displayed stations in the existing background prewarm worker so the Play lookup doesn't block the UI thread on first play. - weather_notifier: normalize alert `sent` timestamps to tz-aware before sorting so a mix of naive/aware values can't raise TypeError and drop all notifications for that cycle. - Add guard_destroyed decorator and apply it to wx.CallAfter completion handlers in discussion, forecast-product, weather-assistant, and advanced text-product dialogs, so closing a dialog mid-fetch can't crash the app. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- cache_serialization: persist discussion_issuance_time (it was read back
on load but never serialized, so it was always None after a round-trip).
- openmeteo_forecast_mapper: treat the daily "time" as a local calendar
date instead of converting to UTC, so the weekday label and 6am/6pm
period boundaries are correct (the UTC round-trip shifted the day for
locations east of UTC and placed boundaries in UTC, not local).
- Unify update channel vocabulary on "stable"/"nightly": the settings UI
now writes "nightly" (not "dev"), config validation accepts "nightly"
and migrates legacy "dev"/"beta" to it instead of resetting to stable
(which silently downgraded nightly users), and the release filter accepts
"nightly". Prevents nightly users from being dropped to the stable channel.
- toast_notifier_windows: start the watchdog so a dead toast worker thread
is detected and restarted instead of silently going dark.
- alert_manager_state: compare ignored alert categories case-insensitively
so a muted category like "Tornado Warning" actually suppresses.
- taskbar {wind} placeholder: format speed through the unit-aware helper
instead of hardcoding "mph" for metric-only sources.
- forecast_confidence: compare each source's first daytime-high period
rather than periods[0], so a high isn't compared against an overnight low.
- soundpack wizard: bind EVT_CLOSE so the title-bar X cleans up the staging
temp dir, and wrap pack creation in error handling that removes a
partially written pack and reports failures.
- api_client core_client: buffer the response body before the httpx client
context closes (defensive against future streaming changes).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- config/locations: reject out-of-range/non-numeric coordinates in add_location and add_location_with_enrichment (CLAUDE.md requirement). - config/settings: redact github_app_id and github_app_installation_id in logs (they're stored as secrets but were logged in cleartext). - community_soundpack_service: guard repo-pack downloads against path traversal / zip-slip by ensuring each tree path stays inside staging. - impact_summary: guard against NaN reference temperature (next() over the temperature bands would raise StopIteration and crash the summary). - taskbar tooltip: only blank on the parser's "Error:" prefix, not any occurrence of "Error", so legitimate text isn't discarded. - alert_manager: actually call _reset_hourly_counter so notifications_this_hour is a per-hour count rather than a lifetime total. - discussion_dialog: shut the screen-reader announcer down on close to match the weather assistant dialog and avoid leaking its backend. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
Test Plan