[P1] ZARA-014 — Bound the wake audio pipeline and make active/conversation timeouts effective #15

Closed
opened 2026-07-18 19:20:41 +00:00 by lost-rob0t · 0 comments
lost-rob0t commented 2026-07-18 19:20:41 +00:00 (Migrated from github.com)

Problem

The wake callback pushes every audio frame into an unbounded asyncio.Queue using run_coroutine_threadsafe(). There is no backpressure/drop policy, and the returned futures are discarded. Slow transcription/LLM/TTS paths can accumulate stale audio and memory.

After wake detection, collect_audio_until_silence() can wait forever before first speech. TIMEOUT_ACTIVE and conversation timeout are checked only before entering collection, so saying the wake word and then remaining silent can leave Zara active indefinitely.

Required fix

  • Use a bounded audio queue with an explicit real-time overflow policy.
  • Avoid scheduling one coroutine future per audio callback frame.
  • Add separate deadlines for first speech, end-of-speech silence, maximum utterance, and conversation inactivity.
  • Drain/mark stale frames at state transitions.
  • Ensure stop/shutdown unblocks all pending collectors.
  • Keep current chunk/VAD behavior otherwise; streaming optimization comes later.

Required tests

  • Deterministic fake-clock tests for no speech after wake, continuous noise, endless speech, queue overflow, slow consumer, shutdown while waiting, and stale-frame transition.
  • Verify memory stays bounded under a long synthetic input run.
  • Add scripts/test-wake-lifecycle.sh with synthetic frames and no microphone.

Acceptance

  • Zara returns to passive after the configured no-speech deadline.
  • Queue length never exceeds its bound.
  • Shutdown completes promptly from every wait state.

Branch

fix/zara-014-wake-lifecycle

Dependencies

ZARA-001, ZARA-005, ZARA-011.

## Problem The wake callback pushes every audio frame into an unbounded `asyncio.Queue` using `run_coroutine_threadsafe()`. There is no backpressure/drop policy, and the returned futures are discarded. Slow transcription/LLM/TTS paths can accumulate stale audio and memory. After wake detection, `collect_audio_until_silence()` can wait forever before first speech. `TIMEOUT_ACTIVE` and conversation timeout are checked only before entering collection, so saying the wake word and then remaining silent can leave Zara active indefinitely. ## Required fix - Use a bounded audio queue with an explicit real-time overflow policy. - Avoid scheduling one coroutine future per audio callback frame. - Add separate deadlines for first speech, end-of-speech silence, maximum utterance, and conversation inactivity. - Drain/mark stale frames at state transitions. - Ensure stop/shutdown unblocks all pending collectors. - Keep current chunk/VAD behavior otherwise; streaming optimization comes later. ## Required tests - Deterministic fake-clock tests for no speech after wake, continuous noise, endless speech, queue overflow, slow consumer, shutdown while waiting, and stale-frame transition. - Verify memory stays bounded under a long synthetic input run. - Add `scripts/test-wake-lifecycle.sh` with synthetic frames and no microphone. ## Acceptance - Zara returns to passive after the configured no-speech deadline. - Queue length never exceeds its bound. - Shutdown completes promptly from every wait state. ## Branch `fix/zara-014-wake-lifecycle` ## Dependencies ZARA-001, ZARA-005, ZARA-011.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/zara#15
No description provided.