Six defects found by a sweep of the Automatic-bitrate path, all of them the same
shape: a single window, or a single refusal, taught the controller something it
then treated as permanent.
- Rolling baselines (OWD, client decode, host encode) armed off ONE sample. The
baseline is a rolling minimum, so one window IS the floor — and `on_ack`
deliberately clears the encode baseline after every decrease we ourselves
asked for, re-opening that hole each time. A calm re-seed window followed by
ordinary motion read as 4 ms of "congestion", backed off, cleared again, and
ratcheted toward the floor on a link that was never the problem. All three now
need BASELINE_MIN_WINDOWS of evidence before they may fire, via one shared
`score_baseline` (the three copies had already drifted apart).
- A mode switch rebased only the encode baseline. Decode and OWD are just as
mode-scoped: 4K120 decodes slower and puts bigger frames on the wire than
1080p60, so the old floor was one the new mode cleared on its first window —
~30 s of every window scoring bad, i.e. a backoff every other window. A switch
UP in mode cratered the rate instead of raising it. `proven_kbps` goes with
them; throughput the old mode's decoder digested is not evidence about this one.
- `proven_kbps` — never decayed, and permanent authority over how far every
later climb may step — was raised by any window without a decode rise,
including ones scored SEVERE. The windows that overstate delivered throughput
are exactly the damaged ones: a stall's backlog draining at once, a flush's
queue, the FEC surge answering a loss burst. Now only clean windows raise it.
- A learned cap escaped at +12.5 % per ~60 s. The host cannot distinguish a
durable encoder ceiling from a climb refused while it is transiently behind
cadence, and the latter routinely latches during slow start at the 20 Mbps
default — from which crossing the gap to a probe-measured ceiling took upwards
of twenty minutes. Re-probe after 12 s instead, doubling the interval each time
the lift is immediately re-learned: a transient is out in one interval, a real
ceiling settles into a slow poll.
- The decode cap latched AT the rate that choked, authorizing a climb straight
back into the failure, and a bare jump-to-live flush could teach a "decoder
knee" from what was a network event. It now latches just under the choke rate
(inside the ±1/8 band the evidence already required) and only credits a flush
where the decode signal is absent and cannot speak for itself.
- PUNKTFUNK_ABR_MAX_MBPS bound only probe-learned ceilings, not the negotiated
start rate — so the one knob an Automatic session gives the operator did
nothing when the session already started above it. It now binds at
construction, and a session sitting above its ceiling steps down to it (no
congestion signal will ever find that: the link is fine, the cap is policy).
Also: a SetBitrate dropped by a full control queue counted toward MAX_UNACKED,
so three of them retired the controller for the session while logging that an
"older host" was at fault. The pump now tells the controller what happened.
Wire format and ABI untouched. 34 abr tests green (3 new).