A stall learns whether anything was dirty, and lateness stops cutting the bitrate #413

Merged
enricobuehler merged 2 commits from worktree-standby-sink-investigation into main 2026-08-27 13:00:17 +00:00
Owner

Ground-up re-investigation of the standby-sink metronomic stutter family (full report: the "Metronome That Wasn't" artifact; memory topic punktfunk-vdisplay-standby-sink-stutter). The family splits into three mechanisms; this PR ships the two fixes that fell out of it.

The reattribution

The 2026-08-27 "laptop panel" field case (0.31.4, RTX 4050, Moto G75 over Wi-Fi) was never a display stall:

  • dwm_flush=8–33ms inside every 150–780 ms hole — DWM ran composition passes throughout and presented nothing because nothing was dirty;
  • the desktop's only damage source is the DWM-composited cursor, driven solely by client input, and the input injector (lazy-opened on the first datagram) came up 14 ms after the first stall line — the 781 ms first "hole" is the pre-input dead zone;
  • offered_during_gap=1 is exactly the stall-ending frame; zero DxgKrnl DDI brackets; the "1.87 s metronome" is only the early phase — the tail runs a 0.22–0.5 s duty cycle, a hand/radio cadence;
  • the visible damage was ours: resume edges report loss_ppm=50000 exactly — the frames_dropped bump with measured loss 0 (every presumed-lost packet arrived late) — ratcheting 20→14→9.8→6.86 Mbps in 4 s plus an RFI storm.

A radio pause stalls both directions at once: input stops (compose hole) and in-flight video lands late (false ratchet). Apollo on the same box is clean because its cursor is client-drawn and it has no lateness ratchet — parity this PR restores by construction.

Commit 1 — the cursor damage witness (pf-capture)

  • try_consume samples GetCursorPos (user32 only, 8 ms rate limit) and accumulates motion per gap; the stall-ending frame's own move is held back one call so it never counts into the gap it ended.
  • window_report attributes the pre-hole flow: flow_dwm_only = every lookback present came from dwm.exe — a game session is never demoted, whatever the cursor did.
  • New class DAMAGE-IDLE (compose-silence + working present witness + dwm-only flow + cursor still): excluded from the metronome (now fed post-classification via StallWatch::cycle), from both repeated-stall WARNs, and from the connected_inactive blame — which fires on every laptop under the exclusive isolate and was a standing correlation trap. A cursor that moves through a present-free hole is now a positive display-stack conviction the old CONTENT-SILENCE could never make; that is the armed falsifier for the remaining standby-sink flavor (zero confirmed cases on ≥0.28 with the REALTIME levers off).
  • Per-stall lines carry cursor_moved_px_during_gap + flow_dwm_only; the below-OS METRONOMIC warn stops prescribing panel A/Bs for holes the witness already explains.

Commit 2 — the lateness ratchet kill (punktfunk-core)

window_loss_ppm's +50k bump now exempts the all-late window (lost == 0 && late > 0): frames that died of lateness stop cutting bitrate ×0.7 — FEC repairs loss, not delay, and a backoff cannot shorten a hole. Silent total loss (shards that never arrived count in neither recovered nor late, so late == 0) still bumps. Client-side mint; old clients keep the old behavior until updated.

Verification

  • The stall logic (stall.rs verbatim incl. the restructured report(), plus the ETW pure slice) extracted into a native scratch crate against the real pf-frame metronome and real tracing: 16/16 tests green, including the new damage_idle_split and damage-idle-does-not-feed-the-metronome cases.
  • punktfunk-core --features quic --lib: 501 passed, incl. the extended window_loss_ppm matrix (all-late exemption, mixed windows keep the bump, silent-total-loss keeps the bump).
  • fmt + clippy clean. The thin Windows FFI glue (sampler, field inits) compiles on the windows-host.yml main-push leg after merge — pf-capture is in its path filter.
Ground-up re-investigation of the standby-sink metronomic stutter family (full report: the "Metronome That Wasn't" artifact; memory topic `punktfunk-vdisplay-standby-sink-stutter`). The family splits into three mechanisms; this PR ships the two fixes that fell out of it. ## The reattribution The 2026-08-27 "laptop panel" field case (0.31.4, RTX 4050, Moto G75 over Wi-Fi) was never a display stall: - `dwm_flush=8–33ms` **inside** every 150–780 ms hole — DWM ran composition passes throughout and presented nothing because *nothing was dirty*; - the desktop's only damage source is the DWM-composited cursor, driven solely by client input, and the input injector (lazy-opened on the first datagram) came up **14 ms after the first stall line** — the 781 ms first "hole" is the pre-input dead zone; - `offered_during_gap=1` is exactly the stall-ending frame; zero DxgKrnl DDI brackets; the "1.87 s metronome" is only the early phase — the tail runs a 0.22–0.5 s duty cycle, a hand/radio cadence; - the visible damage was ours: resume edges report `loss_ppm=50000` exactly — the `frames_dropped` bump with measured loss 0 (every presumed-lost packet arrived **late**) — ratcheting 20→14→9.8→6.86 Mbps in 4 s plus an RFI storm. A radio pause stalls both directions at once: input stops (compose hole) and in-flight video lands late (false ratchet). Apollo on the same box is clean because its cursor is client-drawn and it has no lateness ratchet — parity this PR restores by construction. ## Commit 1 — the cursor damage witness (`pf-capture`) - `try_consume` samples `GetCursorPos` (user32 only, 8 ms rate limit) and accumulates motion per gap; the stall-ending frame's own move is held back one call so it never counts into the gap it ended. - `window_report` attributes the pre-hole flow: `flow_dwm_only` = every lookback present came from dwm.exe — a game session is never demoted, whatever the cursor did. - New class **DAMAGE-IDLE** (compose-silence + working present witness + dwm-only flow + cursor still): excluded from the metronome (now fed post-classification via `StallWatch::cycle`), from both repeated-stall WARNs, and from the `connected_inactive` blame — which fires on every laptop under the exclusive isolate and was a standing correlation trap. A cursor that **moves** through a present-free hole is now a positive display-stack conviction the old CONTENT-SILENCE could never make; that is the armed falsifier for the remaining standby-sink flavor (zero confirmed cases on ≥0.28 with the REALTIME levers off). - Per-stall lines carry `cursor_moved_px_during_gap` + `flow_dwm_only`; the below-OS METRONOMIC warn stops prescribing panel A/Bs for holes the witness already explains. ## Commit 2 — the lateness ratchet kill (`punktfunk-core`) `window_loss_ppm`'s +50k bump now exempts the all-late window (`lost == 0 && late > 0`): frames that died of lateness stop cutting bitrate ×0.7 — FEC repairs loss, not delay, and a backoff cannot shorten a hole. Silent total loss (shards that never arrived count in neither `recovered` nor `late`, so `late == 0`) still bumps. Client-side mint; old clients keep the old behavior until updated. ## Verification - The stall logic (stall.rs verbatim incl. the restructured `report()`, plus the ETW pure slice) extracted into a native scratch crate against the real `pf-frame` metronome and real `tracing`: **16/16 tests green**, including the new `damage_idle_split` and damage-idle-does-not-feed-the-metronome cases. - `punktfunk-core --features quic --lib`: 501 passed, incl. the extended `window_loss_ppm` matrix (all-late exemption, mixed windows keep the bump, silent-total-loss keeps the bump). - fmt + clippy clean. The thin Windows FFI glue (sampler, field inits) compiles on the `windows-host.yml` main-push leg after merge — `pf-capture` is in its path filter.
enricobuehler added 2 commits 2026-08-27 12:49:03 +00:00
The 2026-08-27 NVIDIA-laptop field case (36 stalls/27 s, blamed on the dark
laptop panel) reattributes to damage starvation: the desktop's only damage
source is the DWM-composited cursor, the cursor moves only while the client's
input arrives, and DwmFlush stayed 8-33 ms through every hole — DWM was
composing all along and correctly presenting nothing, because nothing was
dirty. The detector could not see that, so it fitted a 1.87 s 'display
metronome' to the reporter's input cadence and the WARN put the panel on
trial (connected_inactive lists it on every laptop under the exclusive
isolate — a standing correlation trap).

- try_consume samples GetCursorPos (rate-limited, user32 only) and
  accumulates motion per gap; the stall-ending frame's own move is held back
  one call so it never counts into the gap it ended. Some(0) = nothing was
  dirty anywhere; Some(n>0) through a present-free hole = damage existed and
  the display stack composed none of it — the positive conviction
  CONTENT-SILENCE could never make.
- window_report attributes the pre-hole flow: flow_dwm_only = every lookback
  present came from dwm.exe — a game's holes are never demoted.
- classify: ComposeSilence + working witness + flow_dwm_only + cursor still
  => new class DAMAGE-IDLE. Excluded from the metronome (fed post-
  classification via StallWatch::cycle now), both repeated-stall WARNs, and
  the connected_inactive blame; per-stall lines carry
  cursor_moved_px_during_gap + flow_dwm_only either way.
- The below-OS METRONOMIC warn stops prescribing panel A/Bs for holes the
  witness can already explain, and says every pre-0.28 field metronome ran
  with the REALTIME lever default-on.

Logic verified by extracting stall.rs verbatim (+ the etw pure slice) into a
native scratch crate: 16/16 tests green, incl. the new damage_idle_split and
damage-idle-does-not-feed-the-metronome cases. Windows-only glue (GetCursorPos
sampler, field inits) is compile-gated on the Windows legs.
fix(core/abr): frames that died of lateness stop ratcheting the bitrate — the +50k bump exempts the all-late window
ci / bun-nix (pull_request) Successful in 30s
ci / docs-drift (pull_request) Successful in 1m0s
ci / docs-site (pull_request) Successful in 1m6s
ci / web (pull_request) Successful in 1m27s
apple / swift (pull_request) Successful in 2m12s
ci / rust-arm64 (pull_request) Successful in 2m11s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
ci / rust (pull_request) Successful in 5m53s
android / android (pull_request) Successful in 6m39s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 8m22s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 7m14s
53621a0fe0
window_loss_ppm's frames_dropped bump fired even when lost == 0 && late > 0:
every presumed-lost shard eventually ARRIVED, the frames died of lateness —
a delivery hole (host compose stall's resume edge, client-radio pause), which
neither lever this number drives can touch: FEC repairs loss, not delay, and
a bitrate backoff cannot shorten a hole. In the 2026-08-27 field log that was
loss_ppm=50000 exactly, x0.7 three times to 6.86 Mbps in 4 s, on a wire with
zero measured loss — the false ratchet is why a 160 ms hole reads as a
quality crater on our stream while the same pause is a cursor hiccup on the
competition.

The bump survives everywhere it is right: silent total loss (shards that
never arrived count in neither recovered nor late) reads late == 0 and still
bumps, and any window with real net loss bumps as before. Client-side mint,
so old clients keep the old behavior until updated.
enricobuehler scheduled this pull request to auto merge when all checks succeed 2026-08-27 13:00:08 +00:00
enricobuehler merged commit 891f165f82 into main 2026-08-27 13:00:17 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#413