docs: record the jitter buffer's unreachable shrink path as a known bug
CI / check (push) Canceled after 0s
CI / check (push) Canceled after 0s
`target_delay` grows +1 per disruption to MAX_DELAY_FRAMES (240 ms) but only shrinks after 250 consecutive clean frames — 5 s of unbroken audio. Two of the five `clean_run` resets fire on every natural pause in speech (jitter.rs:201 benign underrun, jitter.rs:181 re-prime), and the sender stops transmitting outright while the gate is closed (core/mod.rs:2041). The AIMD decrease half is therefore unreachable under conversational voice: one early jitter burst pins the extra latency for the rest of the session. Found by code review; not yet reproduced live. Pairs with field-test debt #5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -137,6 +137,35 @@ covers internals). When you ship a feature, add it here.
|
||||
|
||||
---
|
||||
|
||||
## Known bugs
|
||||
|
||||
Defects found by code review, not yet fixed.
|
||||
|
||||
1. **Adaptive playout delay never shrinks back in real conversation**
|
||||
(`src/core/jitter.rs`) — `target_delay` grows +1 per disruption up to
|
||||
`MAX_DELAY_FRAMES` (12 frames = 240 ms) but only shrinks after
|
||||
`CLEAN_RUN_TO_SHRINK` = 250 consecutive cleanly-played frames, i.e. **5 s of
|
||||
unbroken audio**. `clean_run` is reset in five places; two of them fire on
|
||||
every natural pause in speech: the benign-underrun branch (`jitter.rs:201`,
|
||||
talker went quiet) and the subsequent re-prime (`jitter.rs:181`). Because the
|
||||
sender skips transmitting entirely while the noise gate is closed
|
||||
(`src/core/mod.rs:2041`), a pause between sentences *always* underruns the
|
||||
receiver and zeroes the clean run — twice.
|
||||
|
||||
Net effect: the controller is a one-way ratchet. A single burst of jitter
|
||||
early in a call pins up to 240 ms of extra playout latency for the rest of
|
||||
the session, because no conversational speaker talks for 5 continuous
|
||||
seconds without the gate closing. The AIMD "decrease" half is effectively
|
||||
unreachable under the workload the app is built for.
|
||||
|
||||
Likely fix: let `clean_run` survive a benign idle→re-prime transition rather
|
||||
than resetting it. Silence is not evidence the link is bad, so it should not
|
||||
count against the clean run. Distinguish "talker stopped" (benign) from
|
||||
"playout broke" (real) at `jitter.rs:195-202`.
|
||||
|
||||
Found 2026-07-31 by code review. Not yet reproduced in a live call — pairs
|
||||
with field-test debt item 5 below.
|
||||
|
||||
## Known field-test debt (the 🧪 rows above, collected)
|
||||
|
||||
Re-run on a real desktop ↔ dopedart call before calling these done:
|
||||
|
||||
Reference in New Issue
Block a user