'20 Mbps' used to mean 22-30+ Mbps on the wire: FEC parity (1-50 %),
packet framing (~4.5 %) and the audio plane all rode on top of the
number the user set — and on the constrained links where the setting
matters most, that overshoot WAS the failure. Per the signed-off RFC
§5.1 (amended 2026-08-27: no capability handshake — the semantics just
change; new-client→old-host is byte-for-byte today's behavior, and
old-client→new-host shifts conservative by the overhead share):
Host: every number on the control plane — Hello resolve, SetBitrate,
acks, live_bitrate, the console — is the TOTAL WIRE BUDGET. Encoder
opens/reconfigures convert through EncDerive (budget − audio, over
framing + FEC) snapshotted at the live FEC percent, and read-backs
convert back so a short apply reports budget truth. A FEC step
re-derives the encoder rate in place, so parity reallocates WITHIN the
budget instead of inflating the wire. The audio reservation comes from
the resolved plane (exact PCM cost, or the shared Opus budget ladder).
PyroWave is the identity (its pin is an encoder operating point);
GameStream keeps its historical semantics untouched.
Client: the controller's actual becomes the WIRE measure — received
bytes with headers, seals and parity (they spend the budget), minus
probe filler, plus the mirrored audio reservation — so utilization and
the proven mark compare like with like against budget targets.
The derivation is pure and unit-tested: roundtrips never inflate the
budget, reallocation is monotone in FEC, and a budget too small for
its own audio floors honestly. punktfunk-core --features quic: all 500
lib tests green natively; punktfunk-host clippy -D warnings green on
the CI image. Docs: the bitrate sections say what the number now means.