The mock can now emit speech_started/speech_stopped on a programmable
schedule keyed by input_audio_buffer.append count. Used by the slice-4
secondary-path e2e to exercise the brain advisory → reflex path. The
schedule is shared via an Arc<Mutex<_>> so set_advisory_schedule right
after start() is picked up by accepted connections.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
The media thread will own the advisory channel (two senders: the engine +
the local VAD). spawn_tap_engine now takes advisory_tx as a parameter +
forwards brain speech_started/speech_stopped through it.
Temporary bridge: session_map.rs's legacy poll-task call site creates a
throwaway advisory channel until dev-a Task 7 (MediaThread) owns the real
channel.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
The brain's advisory events now flow to the FOB reflex via the dedicated
advisory_tx side-channel (3rd mpsc alongside tx_pcm_in/tx_audio_out).
handle_brain_frame + run_tap_client thread the sender through; the engine
loop constructs the channel internally until Task 5 moves ownership to the
caller.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
The kill-now path on the seam object: clears the playout ring AND drains
rx_audio_out of pre-barge in-flight brain frames. The drain is what makes
the resume condition race-free — the first audio_out post-barge is
provably post-barge.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
Responds to the 2026-07-01 adversarial review's load-bearing finding:
advisory-only puts the brain round-trip in the barge-in trigger path,
contradicting wedge #1 (README:98-100, ARCHITECTURE.md:79-81).
Spec changes:
- §1.1: LocalVadReflex<P> added to scope as primary trigger
- §1.2: local VAD tuning framework deferred (the VAD itself in scope)
- §3.4: new — LocalVadReflex design (RMS, debounce, observe-then-delegate)
- §5.1: data flow shows local VAD as primary (≤80ms, zero brain round-trip);
brain advisory as secondary (confirms ~300ms later)
- §6.1: 'Why advisory-only' → 'Why both, local VAD primary' (revised rationale)
- §7: done-criteria 5-12 (added LocalVadReflex unit tests + two e2e paths)
Plan changes:
- Task 2b: new — LocalVadReflex<P> + 6 unit tests
- Task 5: spawn_tap_engine signature revised (takes advisory_tx parameter;
media thread owns the channel; two senders via tokio mpsc Sender Clone)
- Task 6: Connected spawn site wires LocalVadReflex<Reflex<TapAudioPipe>>
- Task 9: two e2e cases — PRIMARY (kill WITHOUT brain, wedge #1 proof) +
SECONDARY (advisory backstop)
- Self-review: wedge-#1 audit line added — Task 9 step 1 is the proof
DCO signoff added per AGENTS.md (commit -s).
Signed-off-by: opencode controller <controller@local>