Skip to content

fix(notifications): address code-review P2s (NS fallback cfg-gate + SAFETY docs) - #33

Merged
AzimovS merged 1 commit into
mainfrom
fix/notifications-p2-safety-and-cfg-gate
Apr 20, 2026
Merged

fix(notifications): address code-review P2s (NS fallback cfg-gate + SAFETY docs)#33
AzimovS merged 1 commit into
mainfrom
fix/notifications-p2-safety-and-cfg-gate

Conversation

@AzimovS

@AzimovS AzimovS commented Apr 20, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to PR #32. Addresses two P2 findings from the post-merge code review that were committed locally but didn't make it into the merged squash. Re-applying as a standalone PR for clean traceability.

No runtime behavior change for the macOS banner happy path — this is hardening + rot prevention.

Changes

1. Cfg-gate the tauri-plugin-notification NS fallback branches on macOS

File: frontend/src-tauri/src/notifications/commands.rs

The fallback blocks in show_recording_started_notification and show_recording_stopped_notification directly call app_handle.notification().builder().title(...).body(...).show() when the notification manager fails to initialize. On macOS this routes through the deprecated NSUserNotification path — which is exactly the broken path PR #32 set out to avoid. Worse, if a future version of tauri-plugin-notification installs its own UNUserNotificationCenterDelegate, it would race with our BannerDelegate via last-writer-wins setDelegate:, silently unwiring the willPresent → Banner|List|Sound hook.

Fix: wrap the fallback blocks with #[cfg(not(target_os = "macos"))]. On macOS, if the manager fails to init, log a warn! and drop the notification rather than deliver via the broken path. Also cfg-gate the NotificationExt import.

2. Expand SAFETY comments on unsafe boundaries in macos_un.rs

File: frontend/src-tauri/src/notifications/macos_un.rs

Add // SAFETY: comments or /// # Safety docs to every unsafe site:

  • define_class! block: super-class, NSObjectProtocol conformance, UNUserNotificationCenterDelegate conformance, and #[unsafe(method(...))] selector ABI
  • msg_send![super(this), init] in BannerDelegate::new
  • Both call sites of error_message(error) inside the RcBlock closures
  • unsafe fn error_message itself (added /// # Safety doc)

Testing

  • cargo check clean on macOS (same preexisting warnings, no new ones)
  • Manual: all 8 Debug Notifications variants still fire banners (not expected to change — regression check only)
  • Windows CI (cfg-gated, paths untouched)
  • Linux CI (cfg-gated, paths untouched)

Post-Deploy Monitoring & Validation

No additional operational monitoring required: comments-only changes on macOS behavioral paths, and cfg-gated fallback branches on Windows/Linux (no change from pre-merge behavior). The only observable difference is a new warn! log line on macOS when the notification manager fails to init — which has always been a degraded edge case path, previously silently failing via NS.

Related

🤖 Generated with Claude Code

… docs)

- Cfg-gate the `tauri-plugin-notification` fallback blocks in
  show_recording_started_notification and show_recording_stopped_notification to
  #[cfg(not(target_os = "macos"))]. On macOS those paths would route through the
  deprecated NSUserNotification API (which doesn't deliver banners) and could race
  with our UNUserNotificationCenterDelegate via last-writer-wins setDelegate:.
  On macOS, if the manager fails to initialize, log a warn and drop the
  notification rather than silently deliver via the broken path.

- Add per-unsafe-block SAFETY comments throughout macos_un.rs: the define_class!
  attributes (super = NSObject, NSObjectProtocol, UNUserNotificationCenterDelegate,
  method selector), the msg_send![super, init] in BannerDelegate::new, and the
  error_message helper (including a /// # Safety doc).

Closes todos/001, todos/002 from the review of PR #32.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AzimovS
AzimovS merged commit 1e08fbb into main Apr 20, 2026
AzimovS added a commit that referenced this pull request Apr 21, 2026
`UNUserNotificationCenter` dereferences `NSBundle.mainBundle` and throws
`NSInternalInconsistencyException: bundleProxyForCurrentProcess is nil`
when the executable is launched directly (e.g. `pnpm run tauri dev`,
which runs `target/debug/meetily` rather than the bundled `.app`). Since
commits #32/#33 migrated macOS notifications from the legacy
`NSUserNotification` path to UN, every `tauri dev` run crashes at
startup.

Skip the UN calls when `current_exe()` has no `.app` ancestor.
`request_authorization` returns `Err` (not `Ok(false)`) so
`manager.rs` falls into its existing `Err` arm and does not persist
`system_permission_granted = false` — the dev run and the bundled `.app`
share `~/Library/Application Support/com.meetily.ai/`, so persisting
`false` would silently suppress every real notification until the user
re-granted consent. `show()` returns `Ok(())`; callers do not store
state on success.

Bundled `.app` behavior is unchanged.
@AzimovS AzimovS mentioned this pull request Apr 24, 2026
6 tasks
AzimovS added a commit that referenced this pull request Apr 24, 2026
Prepares a release containing the work merged since v0.1.15:
- feat(detection): mic-activity meeting auto-detection on macOS (#35)
- feat(transcription): retry with backoff + in-transcript failure
  placeholder (#39)
- feat(summary): TownHall template (#30), current template name in
  dropdown (#31), specificity prompt tweak (#37)
- feat(remote): test-connection button + model selection surface
  improvements (#28, #29)
- fix(notifications): migrate to UNUserNotificationCenter (#32),
  SAFETY + fallback race fixes (#33), unbundled-dev crash guard (#38),
  drop OS recording banners and flip auto_save default to false (#36)
- chore(about): drop Zackriya services CTA (#40)

Behavior change to call out in release notes: fresh installs (and
users with no stored recording_preferences.json) now default
auto_save to false — audio files are not written to disk unless the
user opts in via Recording Settings. Existing users with saved
preferences are unaffected.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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