Slice 2 — The agent tap: splicing the brain seam #2
Reference in New Issue
Block a user
Delete Branch "slice-2-agent-tap"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements spearhead step 2 per docs/superpowers/specs/2026-06-28-slice-2-agent-tap-design.md (commit
f83bca9, post-adversarial-review).11 commits (+ final whole-branch review fixes). 46 tests pass across 9 crates. cargo fmt --check + cargo clippy -D warnings + cargo deny check (licenses/bans/sources) all clean. Slice-2 architecture: Decoupled TapEngine (Approach B) — TapAudioPipe is a thin sync wrapper over mpsc + bounded VecDeque playout ring that the slice-1 AudioSource/AudioSink seam holds; a separately-spawned TapEngine tokio task owns the WSS connection with bounded-exponential-backoff reconnect.
Spec §8.5 done criteria:
Out of scope per spec §1.2: wss:// TLS (step 6), authn on tap_url (step 6), real brain (step 3), OpenAI-Realtime adapter (step 3), barge-in (step 4), PSTN trunk (step 5), spend cap (step 6), CDR/event bus (step 5).
Reviewer focus (from whole-branch code review):
Open decision (spec §9): ADR-0007 ratifying the wire protocol is 'strongly recommended to land alongside or immediately after slice-2 implementation' — deferred past slice-2, should land before step-3 OpenAI adapter ships against the protocol shape.
- start_echo_server(addr): in-process WS server for integration tests; returns EchoHandle { shutdown, join, addr }. - echo_one_connection: the per-connection echo loop — hello handshake, audio_in → audio_out (same PCM), bye/session_end graceful close. - Reuses rutster-tap's protocol types — the wire-types-reusable contract test (spec §2.3). - Stateless across reconnects (spec §5.3) — every hello starts fresh. - Standalone binary: binds ws://127.0.0.1:8081, runs forever. - 1 unit test exercises full hello/ack/audio_in/audio_out/bye over a TCP loopback pair. Spec ref: 2026-06-28-slice-2-agent-tap-design.md §2.3, §5.3.- tap_engine.rs: spawn_tap_engine(session_id, tap_url) — dials the brain, runs TapClient with bounded exponential backoff (250ms→5s cap, infinite retries). Cold-path network I/O on tokio's pool, NOT a timing thread (spec §4.3 deviation boundary). - session_map.rs: +tap_registry (DashMap<ChannelId, TapConn>); +default_tap_url. drive_all_sessions observes Connected+tap.is_none() → spawn TapEngine, set channel.tap = Some(TapHandle). Observes Closing+tap.is_some() → fire close oneshot, abort task, clear tap BEFORE state advances to Closed. - routes.rs: POST /v1/sessions accepts optional {"tap_url":...} body; resolve_tap_url validates ws:// 127.0.0.1/localhost, rejects wss:// + non- loopback ws:// + bad schemes with 400 Bad Request (fail-fast per spec §4.4). - main.rs: reads RUTSTER_TAP_URL env (default ws://127.0.0.1:8081/echo). - rtc_session.rs (rutster-media): pipe field changed from EchoAudioPipe to Box<dyn AudioPipe + Send> — the seam test (§8.5 #6): loop_driver's call sites (sink.on_pcm_frame / source.next_pcm_frame) are byte-identical; only the field type widens. RtcSession::new keeps EchoAudioPipe default (slice-1 tests unchanged); binary uses RtcSession::set_pipe(tap_audio_pipe) to swap on the Connected transition. - 4 unit tests for tap_url validation (loopback accepted, non-loopback rejected, wss rejected fail-fast, default fallback). Spec ref: 2026-06-28-slice-2-agent-tap-design.md §4.3, §4.4, §5.1, §7.- tap_engine.rs: Backoff::next_delay now matches spec §4.3 exactly: 250ms -> 500ms -> 1s -> 2s -> 5s cap (no intermediate 4s step from naive doubling). Test asserts the spec enumeration including the "stays at 5s forever" cap-after-step-5 invariant. - session_map.rs: removed the dead 'Closing && tap.is_some()' branch from drive_all_sessions. AppState::close already handles teardown inline (fires close_tx, aborts task, clears field, advances state, removes entry). The branch was never exercised and pre-paved a "future peer-initiated close" path -- both AGENTS.md anti-patterns ("don't pre-pave the wrong pattern"). Spec ref: 2026-06-28-slice-2-agent-tap-design.md §4.3 step 4 + §5.1 step 3.