The wedge-#1 proof. RMS/energy VAD in on_pcm_frame on the dedicated
thread, in the 20ms loop — caller speech trips SpeechStarted locally,
without any brain round-trip. Debounce (N=3 frames = 60ms) filters
transients. Composes as LocalVadReflex<Reflex<TapAudioPipe>>; both
the local VAD + the brain's advisory feed the same advisory_tx mpsc
(spec §6.1). Revised after adversarial review (initial brainstorming
was advisory-only, which contradicts ARCHITECTURE.md:79-81; wedge-#1
mandate at README:98-100). Spec §3.4 (VAD trigger) + §6.4 (wrapper-
not-inline) load-bearing.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
Fix 1: removes a Task-1 forward-reference comment in reflex.rs that
contradicted itself once Task 2 added the imports it claimed were
"intentionally absent."
Fix 2: MockPipe::on_pcm_frame was a no-op, so Test 6 could not
distinguish "delegated to inner" from "dropped on the floor." Add
last_inbound_frame: Option<PcmFrame> capture + assert delegation so
the reflex's inbound-passthrough guarantee is verified, not assumed.
Addresses the two Important findings from the Task 2 review.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
The decorator that instruments any AudioPipe with turn-taking reflexes.
SpeechStarted -> muted=true + barge_in_flush + epoch bump. First fresh
audio_out -> un-mute. SpeechStopped is observational (no toggle). Inbound
audio (on_pcm_frame) is NEVER gated — the brain still hears the caller
during barge; the FOB only kills its OWN playout. loop_driver +
rtc_session byte-identical (seam holds).
barge_epoch is load-bearing THIS slice (spec §6.1, commit 86b7460) — the
local VAD (Task 2b) fires ~0 ms after caller speech; the brain's slower
ASR advisory fires ~300 ms later on the SAME barge; the epoch
disambiguates a fresh re-barge from the late confirmation.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
Reflex<P> owns a tokio::sync::mpsc::Receiver<AdvisoryEvent> (the advisory
channel the TapEngine feeds from its tokio task), so tokio must be a
runtime dep of rutster-media at lib-compile time, not dev-only. The
crate itself makes no tokio runtime calls — the dedicated media thread
drives Reflex, not an executor (ARCHITECTURE.md; slice-1 spec §3.4).
Signed-off-by: Aaron D. Lee <himself@adlee.work>