zebra-report didn't have a defect tracker before; until now everything
lived in commit-message archaeology and signal-server log greps. Two
known defects make this the right moment to start one:
0001: fedora chrome cannot hear speakers (P0, in-progress)
P0 because every invariant (RTP arriving, worklet started,
ctxState=running) is green but the user hears nothing — silent
regression is trust-eroding. Primary hypothesis is that
AudioContext.destination always routed to system-default while
the speaker-output picker only setSinkId'd <audio> elements.
Fix landed in 467146a (applySinkToAudioCtx), awaiting fox retest
in production.
0002: fedora firefox cannot share camera (High, open)
Camera publish fails on firefox; chrome same machine works.
No telemetry yet; ticket enumerates the candidates to narrow
on the next attempt.
README.md spells out the format (status / priority / surface / first
seen, then symptom / telemetry / hypothesis / fix / status notes)
and the resolution loop (telemetry → failing test → fix → stamp →
deploy → update ticket).
4.3 KiB
0001: fedora chrome cannot hear speakers
Status: in-progress Priority: P0 (silent regression — every invariant green except audible output) Surface: fedora chrome — observed under both listener and speaker roles First seen: 2026-06-04 (or earlier — "for days") Reporter: fox (blanka-chrome identity)
Symptom
On fedora chrome, no audio from any speaker in the room is audible. Affects every role chrome takes: as listener, no mic audio plays. As speaker, no peer mic audio plays through the mesh+SFU path. Same chrome can publish mic + camera + screen fine — only the receive-side audio is silent.
Other browsers on the same machine (firefox) hear the room correctly once the same code is loaded — so the codebase is not uniformly broken.
Telemetry / Repro
Signal-server log (/var/log/zebra-spaces-signal.log,
CLIENT_LOG actor_handle="blanka-chrome") on 2026-06-06 ~23:24 UTC:
· role=speaker sub=connected/connected pub=connected/connected
mesh=2 sListen=0 streamMode=0 muted=1 xcr=off
aud.recv pkt=308 lost=0 bytes=197428 jitter=0.0080 level=0.000 jbuf=? lp=0.2s
aud.recv pkt=22075 lost=3 bytes=44147 jitter=0.3210 level=0.000 jbuf=? lp=0.9s
aud.recv pkt=44242 lost=4 bytes=751664 jitter=0.0260 level=0.000 jbuf=? lp=0.3s
- RTP arriving at ~50 pps on the active speaker (real Opus voice traffic)
level=0.000on EVERY receivermesh=2(both mesh peers connected)sub=connectedandpub=connected(both SFU PCs healthy)
Earlier in the session:
audio attach uuid=2d4a target=0.5s (current pool=3)
audio via AudioContext 2d4a target=0.5s ctxState=running
jitter-buffer installed uuid=2d4a target=0.5s
jitter-buffer started uuid=2d4a target=0.5s
mesh stream swapped into worklet for 2d4a — buffer cushion now applies to mesh too
Every attach invariant green. Worklet started event fired. ctxState=running.
Yet the user hears nothing.
User report: chrome tab indicator shows NO audio playing.
Hypothesis
Primary (deployed 2026-06-06, awaiting retest): the speaker-output
dropdown in the page calls setSinkId on <audio> elements only. The
worklet path (every listener AND every speaker monitor since c3ff58c routed
mesh through the worklet) runs through audioCtx.destination, which always
emits to the system default sink. If the user picks a non-default sink
in the dropdown, the worklet keeps emitting to the wrong device — silence
on the device they're monitoring.
Fox 2026-06-06 confirmed picking a non-default sink on fedora chrome. Firefox defaults to system default which happens to match the right speaker for him, which is why firefox music started working without needing this fix.
Secondary (not yet ruled out):
- AudioContext.setSinkId() may not be honored on this chrome version / flag set → silent fallthrough to default
- PulseAudio per-app default routing for chrome may override the picked sink at the OS layer
- The worklet's
started=truemay flip back tofalseon a network blip and never re-arm if the queue can't refill to target (rearm guard fires)
Fix
Landed: 467146a 2026-06-06 — applySinkToAudioCtx() calls
audioCtx.setSinkId(speakerDeviceId) on creation and in the dropdown's
fan-out. Diagnostic log line now includes sink=... so the next
telemetry session shows which sink the worklet is routed to.
Deployed: 0f36e02 to www.unturf.com — blanka-chrome needs page reload
(it's a code-shell change, not SDP-level).
Pinned by tests:
audioCtx.setSinkId is called on creation so the worklet routes to the user-picked sink (not just system default)audioCtx without setSinkId support (older browser) does not throw — silent fallback to default
Status notes
- 2026-06-07 (open): awaiting fox retest after reload. Next telemetry
should show
sink=<device-id>(notdefault) on theaudio via AudioContextline. If chrome still silent withsink=<correct-id>, hypothesis shifts to PulseAudio per-app routing or chrome's WebAudio sink negotiation. - 2026-06-06: the Jun 5 cascade + flushSfuStreams prefix-match fix
(
0ce1339) helped firefox but not chrome. Telemetry above ruled out the FSM / attach defects. - 2026-06-04 → 2026-06-05: earlier cascade commits (
2e74b92,f479878,144dd15,61b21a6) tightened the audio attach path but did not address this defect (they targeted double-audio on fxhp-android-firefox).