Skip to content

Reliability: stop-timeout routing + I/O proc real-time safety - #520

Merged
r3dbars merged 2 commits into
mainfrom
claude/angry-panini-c41639
Apr 25, 2026
Merged

r3dbars merged 2 commits into
mainfrom
claude/angry-panini-c41639

Conversation

@r3dbars

@r3dbars r3dbars commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Summary

Two independent reliability fixes uncovered in a focused audit of the meeting capture path.

1. Route stop-timeout meetings to the failed queue (8fde23a)

MeetingCaptureBridge.stopAndAwaitFiles resolves with whatever URLs Audio exposes when meetingStopTimeout (30s) fires, regardless of whether onRecordingComplete ever ran. The controller was feeding those URLs directly into transcription, risking a corrupt transcript from a half-finalized WAV. The bridge now returns a CaptureStopResult carrying didTimeOut; on timeout the controller writes the audio into the failed queue (with retry available from Settings) and surfaces a clear error instead of attempting to transcribe.

Adds a new MeetingFailureKind.stopTimeout + matching MeetingFailureCopy so retry messaging is user-friendly. Also adds stop_timed_out to the existing meeting_recording_stopped diagnostics event for visibility.

2. Drop logging from the system audio I/O proc (32fa75b)

SystemAudioProcessTap.startAudioDevice was running debug/warning/error logs from the CoreAudio I/O block — even with callbackCount-based throttling, that's logging on the real-time audio callback thread. Strip the logs, remove the now-dead callbackCount capture, and document the RT-safety contract. Stats counters still capture the same data (success rate, dropped buffers); cleanup() logs them off-thread.

Test plan

  • bash build.sh — clean
  • bash run-tests.sh — 848/848 (added 2 new cases for stopTimeout classification + copy)
  • bash run-integration-smoke.sh — clean
  • Manual verification of the timeout path is hard without forcing a 30s+ stall on onRecordingComplete. The branch is logically verified but not empirically reproduced.

Follow-ups deliberately not in this PR

  • Protocol seam for MeetingCaptureBridge so the controller's timeout branch can be unit-tested with a mock
  • Larger Fix refactor(ui): Split FloatingPanel.swift into 10 organized files #2 phases (consolidate the per-scalar NSLocks in Audio.swift, pre-allocate or pool the per-callback AVAudioPCMBuffer wrapper) — both real concerns but should land behind a benchmark
  • Other audit findings: STT model-switch race in STTRouter, failed-transcription persistence crash window, MeetingPromptDetector polling cost, transcript styler I/O on @MainActor

🤖 Generated with Claude Code

r3dbars and others added 2 commits April 24, 2026 20:15
When stopAndAwaitFiles times out waiting for Audio.onRecordingComplete,
the WAV header is not yet fully patched. Previously the controller fed
those URLs straight into transcription, risking a corrupted transcript.
Now the bridge returns CaptureStopResult with didTimeOut, the controller
routes to the failed queue on timeout, and the user can retry from
Settings - Meetings once the file finalizes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CoreAudio I/O block is real-time critical and was emitting debug,
warning, and error logs on the audio callback thread (throttled but
still per-callback). Strip all logging, remove the now-dead callbackCount
captured var, and document the RT-safety contract so future edits stay
on the right side of it. Counter increments still use short NSLock
acquisitions (acceptable); cleanup logs aggregate stats off-thread.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@r3dbars
r3dbars merged commit 88616ec into main Apr 25, 2026
@r3dbars
r3dbars deleted the claude/angry-panini-c41639 branch April 25, 2026 01:54
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