impl LesavkaClientApp {
    /*──────────────── mic stream ─────────────────*/
    #[cfg(not(coverage))]
    /// Keeps `voice_loop` explicit because it sits on the live uplink path, where stale media must be dropped instead of queued into latency.
    /// Inputs are the typed parameters; output is the return value or side effect.
    async fn voice_loop(
        ep: Channel,
        initial_source: Option<String>,
        telemetry: crate::uplink_telemetry::UplinkTelemetryHandle,
        media_controls: crate::live_media_control::LiveMediaControls,
        pause_when_camera_active: bool,
    ) {
        let mut delay = Duration::from_secs(1);
        static FAIL_CNT: AtomicUsize = AtomicUsize::new(0);

        loop {
            let state = media_controls.refresh();
            if pause_when_camera_active && state.camera {
                tokio::time::sleep(Duration::from_millis(100)).await;
                continue;
            }
            if !state.microphone {
                telemetry.record_enabled(false);
                tokio::time::sleep(Duration::from_millis(100)).await;
                continue;
            }
            let microphone_source_choice = state.microphone_source.clone();
            let active_source = microphone_source_choice.resolve(initial_source.as_deref());
            let active_audio_codec = state
                .audio_codec
                .resolve(lesavka_common::audio_transport::UpstreamAudioCodec::Opus);
            let active_noise_suppression = state.noise_suppression.resolve(false);
            let use_default_source = matches!(
                microphone_source_choice,
                crate::live_media_control::MediaDeviceChoice::Auto
            ) && active_source.is_none();
            let setup_source = active_source.clone();
            let result = tokio::task::spawn_blocking(move || {
                if use_default_source {
                    MicrophoneCapture::new_default_source_options(
                        active_audio_codec,
                        active_noise_suppression,
                    )
                } else {
                    MicrophoneCapture::new_with_source_options(
                        setup_source.as_deref(),
                        active_audio_codec,
                        active_noise_suppression,
                    )
                }
            })
            .await;
            let mic = match result {
                Ok(Ok(mic)) => Arc::new(mic),
                Ok(Err(err)) => {
                    telemetry.record_disconnect(format!("microphone uplink setup failed: {err:#}"));
                    warn!(
                        "🎤 microphone uplink setup failed for {:?}: {err:#}",
                        active_source.as_deref().unwrap_or("auto")
                    );
                    abort_if_required_media_source_failed("microphone", "🎤", active_source.as_deref(), &err);
                    delay = app_support::next_delay(delay);
                    tokio::time::sleep(delay).await;
                    continue;
                }
                Err(err) => {
                    telemetry.record_disconnect(format!("microphone uplink setup task failed: {err}"));
                    warn!("🎤 microphone uplink setup task failed before StreamMicrophone could start: {err}");
                    abort_if_required_media_source_failed(
                        "microphone",
                        "🎤",
                        active_source.as_deref(),
                        &err,
                    );
                    delay = app_support::next_delay(delay);
                    tokio::time::sleep(delay).await;
                    continue;
                }
            };

            telemetry.record_reconnect_attempt();
            let mut cli = RelayClient::new(ep.clone());
            let queue = crate::uplink_fresh_queue::FreshPacketQueue::new(AUDIO_UPLINK_QUEUE);
            let drop_log = Arc::new(std::sync::Mutex::new(UplinkDropLogLimiter::new(
                "microphone",
                "🎤",
            )));

            let queue_stream = queue.clone();
            let telemetry_stream = telemetry.clone();
            let drop_log_stream = Arc::clone(&drop_log);
            let outbound = async_stream::stream! {
                loop {
                    let next = queue_stream.pop_fresh().await;
                    if next.dropped_stale > 0 {
                        telemetry_stream.record_stale_drop(next.dropped_stale);
                        log_uplink_drop(
                            &drop_log_stream,
                            UplinkDropReason::Stale,
                            next.dropped_stale,
                            next.queue_depth,
                            duration_ms(next.delivery_age),
                        );
                    }
                    if let Some(mut packet) = next.packet {
                        telemetry_stream.record_streamed(
                            queue_depth_u32(next.queue_depth),
                            duration_ms(next.delivery_age),
                        );
                        attach_audio_queue_metadata(
                            &mut packet,
                            next.queue_depth,
                            next.delivery_age,
                        );
                        yield packet;
                        continue;
                    }
                    break;
                }
            };

            match cli.stream_microphone(Request::new(outbound)).await {
                Ok(mut resp) => {
                    let (stop_tx, stop_rx) = std::sync::mpsc::channel::<()>();
                    let mic_clone = mic.clone();
                    let telemetry_thread = telemetry.clone();
                    let queue_thread = queue.clone();
                    let drop_log_thread = Arc::clone(&drop_log);
                    let media_controls_thread = media_controls.clone();
                    let initial_source_thread = initial_source.clone();
                    let active_source_thread = active_source.clone();
                    let active_audio_codec_thread = active_audio_codec;
                    let active_noise_suppression_thread = active_noise_suppression;
                    let mic_worker = std::thread::spawn(move || {
                        let mut paused = false;
                        while stop_rx.try_recv().is_err() {
                            let state = media_controls_thread.refresh();
                            let desired_source = state
                                .microphone_source
                                .resolve(initial_source_thread.as_deref());
                            let desired_audio_codec = state
                                .audio_codec
                                .resolve(lesavka_common::audio_transport::UpstreamAudioCodec::Opus);
                            let desired_noise_suppression =
                                state.noise_suppression.resolve(false);
                            if pause_when_camera_active && state.camera {
                                tracing::info!(
                                    "🎤 microphone-only uplink yielding to bundled webcam A/V"
                                );
                                break;
                            }
                            if desired_source != active_source_thread
                                || desired_audio_codec != active_audio_codec_thread
                                || desired_noise_suppression != active_noise_suppression_thread
                            {
                                tracing::info!(
                                    from = active_source_thread.as_deref().unwrap_or("auto"),
                                    to = desired_source.as_deref().unwrap_or("auto"),
                                    from_codec = active_audio_codec_thread.as_id(),
                                    to_codec = desired_audio_codec.as_id(),
                                    from_noise_suppression = active_noise_suppression_thread,
                                    to_noise_suppression = desired_noise_suppression,
                                    "🎤 microphone route changed; restarting live uplink pipeline"
                                );
                                break;
                            }
                            if !state.microphone {
                                if !paused {
                                    telemetry_thread.record_enabled(false);
                                    tracing::info!("🎤 microphone uplink soft-paused");
                                    paused = true;
                                }
                                std::thread::sleep(Duration::from_millis(20));
                                continue;
                            }
                            if paused {
                                telemetry_thread.record_enabled(true);
                                tracing::info!("🎤 microphone uplink resumed");
                                paused = false;
                            }
                            if let Some(mut pkt) = mic_clone.pull() {
                                trace!("🎤📤 cli  {} bytes → gRPC", pkt.data.len());
                                let enqueue_age = stamp_audio_timing_metadata_at_enqueue(&mut pkt);
                                let stats = queue_thread.push(pkt, enqueue_age);
                                if stats.dropped_queue_full > 0 {
                                    telemetry_thread.record_queue_full_drop(stats.dropped_queue_full);
                                    log_uplink_drop(
                                        &drop_log_thread,
                                        UplinkDropReason::QueueFull,
                                        stats.dropped_queue_full,
                                        stats.queue_depth,
                                        duration_ms(enqueue_age),
                                    );
                                }
                                telemetry_thread.record_enqueue(
                                    queue_depth_u32(stats.queue_depth),
                                    duration_ms(enqueue_age),
                                    0.0,
                                );
                            }
                        }
                    });
                    delay = Duration::from_secs(1);
                    telemetry.record_connected();
                    while resp.get_mut().message().await.transpose().is_some() {}
                    telemetry.record_disconnect("microphone uplink stream ended");
                    queue.close();
                    let _ = stop_tx.send(());
                    let _ = mic_worker.join();
                }
                Err(e) => {
                    telemetry.record_disconnect(format!("microphone uplink connect failed: {e}"));
                    if FAIL_CNT.fetch_add(1, Ordering::Relaxed) == 0 {
                        warn!("❌🎤 connect failed: {e}");
                        warn!("⚠️🎤 further microphone‑stream failures will be logged at DEBUG");
                    } else {
                        debug!("❌🎤 reconnect failed: {e}");
                    }
                    delay = app_support::next_delay(delay);
                }
            }

            queue.close();
            tokio::time::sleep(delay).await;
        }
    }
}
