The controller learns stillness from the host, and motion stops reading as congestion #407

Merged
enricobuehler merged 3 commits from worktree-abr-phase3 into main 2026-08-27 09:22:24 +00:00
3 Commits
Author SHA1 Message Date
enricobuehler cba7587684 chore(ci): baseline the two new wire constants — protocol internals, not knobs
apple / swift (pull_request) Successful in 2m13s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
android / android (pull_request) Successful in 5m57s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 3m1s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m18s
ci / bun-nix (pull_request) Successful in 20s
ci / docs-drift (pull_request) Successful in 23s
ci / docs-site (pull_request) Successful in 1m44s
ci / web (pull_request) Successful in 1m52s
ci / rust-arm64 (pull_request) Successful in 2m34s
ci / rust (pull_request) Successful in 7m24s
2026-08-27 11:03:08 +02:00
enricobuehler 2b107f5a18 chore(core): prefix the two new exported constants in the C header (R21)
ci / bun-nix (pull_request) Successful in 39s
ci / docs-drift (pull_request) Failing after 36s
ci / docs-site (pull_request) Successful in 1m2s
ci / web (pull_request) Successful in 1m16s
apple / swift (pull_request) Successful in 2m9s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
ci / rust-arm64 (pull_request) Successful in 2m49s
android / android (pull_request) Successful in 6m6s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m16s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 2m44s
ci / rust (pull_request) Successful in 15m42s
2026-08-27 10:42:00 +02:00
enricobuehler a387ddd4ab The controller learns stillness from the host, and motion stops reading as congestion (ABR overhaul Phase 3)
Static content used to poison the client's ABR against the first moment
of motion (the 2026-08-26 field chain, step 5), and a frame-driven
source could never climb at all (the documented dead band). Four
changes, per the signed-off RFC §4.1–4.3 + §7 Q4:

- The host marks idle-keepalive re-encodes on the wire
  (USER_FLAG_REPEAT; whole-frame and streamed paths) and says so in a
  new trailing Welcome byte (host_caps2 / HOST_CAP2_REPEAT_MARK — the
  second capability byte the 0x80 wall predicted, same append
  discipline, placeholder chain extended one link). Old clients ignore
  both; against an old host the client keeps every legacy rule.
- Idle windows (every AU a repeat) are NEUTRAL: they train no OWD/
  decode/encode baselines, accrue no climb credit or re-probe
  authority, and never authorize a climb — loss/flush/drop keep their
  full power. The pinned climb-gate test is extended, not deleted.
- Utilization is measured per frame at the source's own rate: a 35 fps
  menu on a 90 Hz config climbs when its frames run full. The
  proven-headroom cap prorates with it — it bounds the next target's
  projected WIRE rate at ×1.5 over what was delivered — or the two
  gates would deadlock exactly where the fix is needed.
- Recovery is bounded and multiplicative: the proven mark is a
  two-bucket windowed max (~30–60 s) instead of all-session, and the
  first active window after ≥3 s of stillness re-arms slow start with
  the cooldown cleared — the ~103 s additive crawl from the floor
  becomes seconds, never past ×1.5 over recently-proven delivery.
- FLOOR_KBPS drops 5000 → 2000 (RFC §7 Q4), with a one-shot log
  warning on the first descent below the old fence; the client-settings
  doc says so.

punktfunk-core --features quic: all 500 lib tests green natively,
including six new field-shaped scenarios (frame-driven climb, idle
neutrality head-to-head vs a legacy host, bounded onset re-arm,
windowed proven decay, floor + warning, idle-never-climbs).
2026-08-27 10:40:48 +02:00