Source: Security review for v0.2.0.
`src-tauri/src/audio/state.rs` — `cpal::Stream` is `!Send + !Sync` by design (CoreAudio expects same-thread teardown). The current code stores it in a `Mutex<Option>` inside Tauri's `State`. Dropping the stream from a worker thread (e.g. in `RunEvent::ExitRequested`) is technically UB on macOS.
Recommendation:
- Move stream ownership into a dedicated audio thread.
- The Tauri `State` holds a control channel sender; commands send `Start`/`Stop`/`Pause` messages.
- Stream is created and dropped on the same OS thread.
Touched files: `src-tauri/src/audio/state.rs`, `src-tauri/src/audio/capture.rs`, `src-tauri/src/commands/recording.rs`, `src-tauri/src/commands/dictation.rs`, `src-tauri/src/lib.rs` (exit handler)
Source: Security review for v0.2.0.
`src-tauri/src/audio/state.rs` — `cpal::Stream` is `!Send + !Sync` by design (CoreAudio expects same-thread teardown). The current code stores it in a `Mutex<Option>` inside Tauri's `State`. Dropping the stream from a worker thread (e.g. in `RunEvent::ExitRequested`) is technically UB on macOS.
Recommendation:
Touched files: `src-tauri/src/audio/state.rs`, `src-tauri/src/audio/capture.rs`, `src-tauri/src/commands/recording.rs`, `src-tauri/src/commands/dictation.rs`, `src-tauri/src/lib.rs` (exit handler)