ABR overhaul Phase 4 — the final phase (planning PR #20, RFC §5.1, amended per Enrico 2026-08-27: no capability handshake — the semantics change outright; new-client→old-host is byte-for-byte today's behavior, old-client→new-host shifts conservative by the overhead share). Stacked on #407 — merge that first and this diff reduces to Phase 4 alone.
"20 Mbps" used to mean 22–30+ Mbps on the wire — FEC parity (1–50 %), packet framing (~4.5 %), and audio all rode on top — and on constrained links that overshoot was the failure. Now the number is the total session wire budget:
Host — the whole control plane (Hello resolve, SetBitrate, acks, live_bitrate, console/mgmt) speaks budget; only the encoder boundary converts:
EncDerive (pure, Copy) does video = (budget − audio) × payload/(payload+64) × 100/(100+fec) and its inverse, snapshotted at the live FEC percent at each encoder open/reconfigure; read-backs convert back so a short apply reports budget truth. The inverse rounds against the derivation, so a roundtrip can never inflate the budget the client believes (unit-tested, with the worked 20 Mbps example).
A FEC step re-derives the encoder rate in place — parity reallocates within the budget instead of fattening the wire. (The stored encoder-ceiling budget-equivalent can drift a few % across FEC moves; the existing +12.5 % re-probe ladder re-latches it — no extra machinery.)
The audio reservation is the resolved plane's cost: exact pcm::bitrate_kbps on lossless, else the shared plan_audio_budget ladder — closing the review's §3.2 "audio invisible to ABR" seam structurally.
PyroWave: identity (the pin is an all-intra encoder operating point). GameStream/Moonlight: untouched, historical semantics.
Client — the controller's actual becomes the wire measure: received bytes with headers, seals and parity (they spend the budget), minus speed-test filler, plus the mirrored audio reservation (exact for PCM; Opus mirrors the host's shared ladder at the default tier — an operator-pinned tier skews it a few hundred kbps, inside the ¾ gate's tolerance). Utilization and the proven mark now compare like with like against budget targets; against an old host the same arithmetic reads ~8–12 % optimistic, which only eases climbs — the safe direction.
Docs: client-settings.md and configuration.md bitrate sections say what the number now means; the FEC_PCT row notes the pinned percent is carved from the budget too.
Verified:punktfunk-core --features quic — all 500 lib tests green natively; punktfunk-hostclippy --all-targets -D warnings green on the CI image (emulated); derivation arithmetic cross-checked; cargo fmt + docs-drift clean. Workspace tests ride ci / rust; a windows-host.yml dispatch follows once PR CI is green.
ABR overhaul **Phase 4** — the final phase (planning PR #20, RFC §5.1, **amended per Enrico 2026-08-27: no capability handshake** — the semantics change outright; new-client→old-host is byte-for-byte today's behavior, old-client→new-host shifts conservative by the overhead share). **Stacked on #407** — merge that first and this diff reduces to Phase 4 alone.
"20 Mbps" used to mean 22–30+ Mbps on the wire — FEC parity (1–50 %), packet framing (~4.5 %), and audio all rode on top — and on constrained links that overshoot *was* the failure. Now the number is the **total session wire budget**:
**Host** — the whole control plane (Hello resolve, `SetBitrate`, acks, `live_bitrate`, console/mgmt) speaks budget; only the encoder boundary converts:
- `EncDerive` (pure, `Copy`) does `video = (budget − audio) × payload/(payload+64) × 100/(100+fec)` and its inverse, snapshotted at the live FEC percent at each encoder open/reconfigure; read-backs convert back so a short apply reports budget truth. The inverse rounds against the derivation, so a roundtrip can never inflate the budget the client believes (unit-tested, with the worked 20 Mbps example).
- A **FEC step re-derives the encoder rate in place** — parity reallocates *within* the budget instead of fattening the wire. (The stored encoder-ceiling budget-equivalent can drift a few % across FEC moves; the existing +12.5 % re-probe ladder re-latches it — no extra machinery.)
- The audio reservation is the resolved plane's cost: exact `pcm::bitrate_kbps` on lossless, else the shared `plan_audio_budget` ladder — closing the review's §3.2 "audio invisible to ABR" seam structurally.
- **PyroWave**: identity (the pin is an all-intra *encoder* operating point). **GameStream/Moonlight**: untouched, historical semantics.
**Client** — the controller's `actual` becomes the wire measure: received bytes with headers, seals and parity (they spend the budget), minus speed-test filler, **plus the mirrored audio reservation** (exact for PCM; Opus mirrors the host's shared ladder at the default tier — an operator-pinned tier skews it a few hundred kbps, inside the ¾ gate's tolerance). Utilization and the proven mark now compare like with like against budget targets; against an old host the same arithmetic reads ~8–12 % optimistic, which only eases climbs — the safe direction.
Docs: `client-settings.md` and `configuration.md` bitrate sections say what the number now means; the `FEC_PCT` row notes the pinned percent is carved from the budget too.
**Verified:** `punktfunk-core --features quic` — all 500 lib tests green natively; `punktfunk-host` `clippy --all-targets -D warnings` green on the CI image (emulated); derivation arithmetic cross-checked; `cargo fmt` + docs-drift clean. Workspace tests ride `ci / rust`; a `windows-host.yml` dispatch follows once PR CI is green.
'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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
ABR overhaul Phase 4 — the final phase (planning PR #20, RFC §5.1, amended per Enrico 2026-08-27: no capability handshake — the semantics change outright; new-client→old-host is byte-for-byte today's behavior, old-client→new-host shifts conservative by the overhead share). Stacked on #407 — merge that first and this diff reduces to Phase 4 alone.
"20 Mbps" used to mean 22–30+ Mbps on the wire — FEC parity (1–50 %), packet framing (~4.5 %), and audio all rode on top — and on constrained links that overshoot was the failure. Now the number is the total session wire budget:
Host — the whole control plane (Hello resolve,
SetBitrate, acks,live_bitrate, console/mgmt) speaks budget; only the encoder boundary converts:EncDerive(pure,Copy) doesvideo = (budget − audio) × payload/(payload+64) × 100/(100+fec)and its inverse, snapshotted at the live FEC percent at each encoder open/reconfigure; read-backs convert back so a short apply reports budget truth. The inverse rounds against the derivation, so a roundtrip can never inflate the budget the client believes (unit-tested, with the worked 20 Mbps example).pcm::bitrate_kbpson lossless, else the sharedplan_audio_budgetladder — closing the review's §3.2 "audio invisible to ABR" seam structurally.Client — the controller's
actualbecomes the wire measure: received bytes with headers, seals and parity (they spend the budget), minus speed-test filler, plus the mirrored audio reservation (exact for PCM; Opus mirrors the host's shared ladder at the default tier — an operator-pinned tier skews it a few hundred kbps, inside the ¾ gate's tolerance). Utilization and the proven mark now compare like with like against budget targets; against an old host the same arithmetic reads ~8–12 % optimistic, which only eases climbs — the safe direction.Docs:
client-settings.mdandconfiguration.mdbitrate sections say what the number now means; theFEC_PCTrow notes the pinned percent is carved from the budget too.Verified:
punktfunk-core --features quic— all 500 lib tests green natively;punktfunk-hostclippy --all-targets -D warningsgreen on the CI image (emulated); derivation arithmetic cross-checked;cargo fmt+ docs-drift clean. Workspace tests rideci / rust; awindows-host.ymldispatch follows once PR CI is green.