SIGSEGV on hangup: capture thread calls writeAudio() via JNI after
teardown() has freed the native engine handle. TOCTOU race between
the nativeHandle==0L check and destroy() on the ViewModel thread.
Fix: CountDownLatch(2) — audio threads count down after exiting loops,
teardown() awaits before destroy(). 2 Kotlin files, no Rust changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete spec for fixing the playout ring buffer cursor race that
causes 12-16s bidirectional silence mid-call. Includes exact code,
memory ordering rationale, unit tests, and verification steps.
Any agent can implement from this document alone.
See also: debug/INCIDENT-2026-04-06-playout-ring-desync.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>