feat(33): StepDownPolicy — two ladders, one budget, recovery behind a flag
Pure policy, no wiring yet. 12 unit tests, 584 green overall, 0 warnings. - **Machine starvation** buys less work: 60 → 30 fps first, then 1080 → 720. The vertical tier has no resolution step — its floor *is* its only geometry. - **Upload congestion** buys fewer bits: `current − max(0.5, current × lossFraction)`, floored at 3.0 Mbps (16:9) / 4.0 (vertical). Resolution is deliberately not a bandwidth lever: 1080p30 and 720p60 cost the same, so dropping pixels at an unchanged bitrate relieves nothing. - **Budgets** as ruled: three steps for a 1920-wide start, one for 720 and vertical. 15 s of evidence, 30 s cooldown, ambiguous evidence does nothing at all. - **Recovery** is `allowClimb`, default off (the one-way ruling): the machine carries its ceiling from construction, climbs one step after 180 s of clean windows, and a climb followed by a relapse inside 120 s freezes the session at the low value — one flap pair is proof enough. Inputs are the poster's own counters (`PumpStalls`, `PumpDrops`, `AvgRenderMs`, `EncoderDrops`), not a throughput reading: `StreamHealth.CurrentBitrate` is ffmpeg's *encoded output* rate and sits at target even while the socket is gagging, so it cannot size a step.
This commit is contained in:
@@ -49,7 +49,7 @@ cited first), then 35 / 37 / 40·A/C/D / 55·2–3. TASK 32 is complete, Back on
|
||||
| 40·A/C/D | ☐ | App Settings: active-camera picker; persist output resolution + surface transition defaults + confirm-before-End; accent consolidation | [`task-40`](TASKS/task-40-app-settings-round.md) |
|
||||
| 3·20 | ✅ | Session report — **derived from `superChatEvents.list` on demand, not persisted** (YouTube is the authority; no ledger). Per-currency totals, money off by default (done 2026-11-05) | [`task-03`](TASKS/task-03-capture-pipeline.md) |
|
||||
| 32 | ✅ | Stream resilience: fragmented MP4, blip retry, poll-driven RECONNECTING (no countdown — YouTube's cutoff is not a constant), ingest pre-flight, one-click Back on air (`BackOnAirTests`) | [`task-32`](TASKS/task-32-stream-resilience.md) |
|
||||
| 33 | ◇ | Auto step-down, **cause-classified** (machine starvation → fps/resolution; upload congestion → bitrate only), shed our own capture cost first, one-way, hard floors, plain-words toast | [`task-33`](TASKS/task-33-bandwidth-step-down.md) |
|
||||
| 33 | 🔶 | Auto step-down — **`StepDownPolicy` + 12 unit tests done 2026-11-09** (two ladders, budgets, floors, cooldown, ambiguity, recovery behind a flag); remaining: pump/health wiring, encoder restart, toast + session line, capture-cost shed | [`task-33`](TASKS/task-33-bandwidth-step-down.md) |
|
||||
| 34 | ☐ | Scheduled streams (Text-drawer version) | [`task-34`](TASKS/task-34-scheduled-streams.md) |
|
||||
| 35 | ☐ | Scene-linked audio | [`task-35`](TASKS/task-35-scene-linked-audio.md) |
|
||||
| 37 | ☐ | Defaults vs current layout split (build-id); enables one-click revert to defaults | [`task-37`](TASKS/task-37-defaults-current-split.md) |
|
||||
|
||||
Reference in New Issue
Block a user