Health fixes: no freeze on Email Support, cheaper idle call detection, lighter Speakers page - #1860
Merged
Merged
Conversation
Email Support and Send Diagnostic walked the whole model cache folder (many CoreML files) and read the full reliability log (up to ~10 MB) on the main thread, so the app could stall right when someone is reporting a problem. Those two disk reads now run in a detached task; the rest of the snapshot is cheap in-memory state and stays on the main actor. A double click can't open two drafts or send two events while the first one is still gathering. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126tPTsXGHmWx6EmsR32sjX
The mic-activity backstop scans every audio process every 5 s while the app idles. It read each process's bundle ID even when the process was doing no audio, which every consumer then ignored. Now it reads the two running flags first and fetches the bundle ID only for processes that are actually using the mic or speakers. Both 5 s backstop timers (mic and camera) also get 500 ms leeway so macOS can batch their wakes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126tPTsXGHmWx6EmsR32sjX
The Speakers review queue rescans the meetings folder after every rename, merge, discard, and meeting save while Settings is open, and each rescan read up to 256 KB of every saved transcript. With 1,000 meetings that is ~250 MB per rename. Transcripts with no db_pending speaker can never produce a review row, whatever the current profiles are. The scanner now remembers those by path plus modification date and size, and skips reading them until the file changes (naming a speaker rewrites the file, so it is read again). Transcripts that do have pending speakers are still read every time. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126tPTsXGHmWx6EmsR32sjX
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126tPTsXGHmWx6EmsR32sjX
r3dbars
marked this pull request as ready for review
September 25, 2026 17:23
This was referenced Sep 25, 2026
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.
Requested by Justin · project thread
Why
Before: clicking Email Support or Send Diagnostic walked the whole model cache folder (lots of CoreML files) and read the full reliability log (up to ~10 MB) on the main thread, so the app could stall right when someone is reporting a problem. While the app sat idle, call detection's 5 s backstop read the bundle ID of every audio process on the Mac (30-60 of them), even ones doing no audio. And the Speakers page re-read up to 256 KB of every saved transcript after every rename, merge, discard, or meeting save (~250 MB per rename at 1,000 meetings).
After: the support disk reads run off the main thread. The idle scan only fetches a bundle ID for processes actually using the mic or speakers, and the mic and camera backstop timers get 500 ms leeway so macOS can batch their wakes. The Speakers scan skips transcripts it already knows have no unnamed voices until the file changes.
Three commits, one problem each, from an app health audit (thread linked above).
Product Impact
meetings(call detection, speaker review), settings support actionsmeeting reliabilityWhat changed
TranscriptedSupportActions:diagnosticsSnapshotis nowasync. The model-cache walk and reliability log read run in aTask.detached; everything else stays on the main actor.sendFeedback/sendDiagnosticEvent/feedbackEmailURL/diagnosticsTextbecameasync. An in-flight flag stops a double click from opening two drafts.TranscriptedSettingsActions.sendDiagnosticEventis now() async -> String?. The settings view awaits it in a Task and has its own in-flight guard.MicActivityMonitor.currentProcessAudioState: readsisRunningInput/isRunningOutputfirst and the bundle ID only when one is true. All three consumers already ignore bundle IDs of processes with the relevant flag false, so detection results are unchanged. Mic and camera backstop timers: 500 ms leeway.SpeakerReviewQueueScanner: newNoPendingSpeakersCache(path → modification date + size, lock-guarded, capped at 20k entries). A transcript with nodb_pendingspeaker can never produce a review row regardless of profiles, so it is skipped until its fingerprint changes. Files with pending speakers are still read every scan. NewhasPendingSpeakers(in:)helper. Two new fast-test suites.How I checked it
bash scripts/dev/linux-checks.sh(48 passed)python3 scripts/dev/check-source-pins.py --changed-only(pass)bash build.sh --no-open/bash run-tests.sh/bash run-integration-smoke.sh: via CIChecks I could not run, and why:
Mac or hardware test still needed? If yes:
Risk Review
Notes
Audio real-time code untouched. No new
AVAudioEngine/inputNodetouches.🤖 Generated with Claude Code
https://claude.ai/code/session_0126tPTsXGHmWx6EmsR32sjX