zebra-report/web
Russell Ballestrini f479878fff
zebra-spaces: idempotent attach + drop stale stream cache (kill host double-audio)
Fox 2026-06-05 telemetry on host: "host is hearing two" — peer-joined
u=64b0 (fxhp-phone rejoin with new uuid, same pubkey) fired THREE
attach calls within 1 second for the SAME uuid:

  Call 1: pool=1 → fallback <audio> path, "tracks=0"
  Call 2: pool=1 → AudioContext success
  Call 3: pool=2 → AudioContext success (after mesh stream swap)

Three overlapping audio chains = "two streams" perceived.

Root causes:

1. flushSfuStreams used the cached sfuStreamsByPubHex entry, which still
   pointed at the OLD phone session's stream (uuid=91ab had left 5s
   earlier). Old stream's audio tracks were ended. attach received a
   zero-live-track stream and fell through to <audio> fallback.

2. Multiple paths (peer-joined → flushSfuStreams, sub PC ontrack,
   mid-spotlight supplant) each tried to attach the same uuid in the
   same tick. No idempotency check, so each call tore down and rebuilt.

Two fixes:

A. attachAudioStreamViaWorklet: reject streams with zero live audio
   tracks (skip silently); make same-uuid + same-stream calls a no-op.
   Repeated calls during a peer-joined burst stop racing.

B. handleRemoteSfuTrack: listen for the cached track's 'ended' event
   and drop the sfuStreamsByPubHex entry. Next flushSfuStreams won't
   hand a dead stream to attach.

Combined: the publisher's rejoin cycle now produces exactly ONE attach
chain — the one fed by the live ontrack — and ignores stale cache hits
+ duplicate attach calls.
2026-06-05 19:41:17 -04:00
..
blog phase 1: unfirehose reconstruction from session JSONL ingest 2026-05-27 13:51:14 -04:00
fonts phase 2: gap analysis — cat>> append + binary asset recovery 2026-05-27 13:54:19 -04:00
chat.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
host-your-own.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
how-it-works.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
index.html web: bump mobile body padding from 1rem to 1.25rem so the right edge has visible breathing room 2026-05-31 14:13:25 -04:00
kernel.html web: bump mobile body padding from 1rem to 1.25rem so the right edge has visible breathing room 2026-05-31 14:13:25 -04:00
stamp.js web: stamp each zebra-report page with build date + md5/sha256 2026-05-28 17:50:12 -04:00
zebra-audio.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
zebra-spaces.html zebra-spaces: idempotent attach + drop stale stream cache (kill host double-audio) 2026-06-05 19:41:17 -04:00