Skip to content

Stream backpressure: no operator-facing degraded-stream readout #610

Description

@iamfatness

Spec docs/superpowers/specs/2026-09-23-stream-backpressure-design.md §7 requires: "The operator-facing readout must say the stream is degraded and at what frame rate. A stream quietly running at 15 fps is the same class of defect as a silent codec downgrade."

That was not built by the #597 backpressure branch, and the branch's own final review caught that neither the Outcome nor the "Not established" section listed it as deferred — so a reader of the spec would believe it shipped.

What exists today. The evidence is on the wire and nothing more:

  • sessionState().outputSenderSession.senders[].backpressure carries divisor (this destination's request), appliedDivisor (the rate it is actually fed at), level, bufferedMs, queuedChunks, enteredCount, discardedChunks, discardEvents, lastReason, runId, observedAtMs.
  • realtimeEvidence.encoderExport carries the global divisor/shedFrames/exporting.
  • GET /snapshot serves all of it verbatim.

What is missing. No shell or renderer file is touched anywhere on the branch. So a stream degraded to a quarter rate is visible to a diagnostician reading /snapshot and invisible to the operator running the show — exactly the silent-downgrade shape the spec sentence exists to forbid.

Suggested shape (not a design, just the constraints this repo already imposes): a scalar readout next to the existing stream status, not a new snapshot-rate bound collection (0xc000027b discipline); read appliedDivisor, not divisor, because Lever A is per-encoder and the per-destination request is not the rate the destination runs at; and say the resulting frame rate as programFps / appliedDivisor, never a hard-coded 60/30/20/15 ladder (the divisor applies to render frame numbers and the program rate is configurable).

Filed from the #597 final-review fix wave.

Activity

  1. iamfatness commented on Sep 24, 2026

    @iamfatness
    OwnerAuthor

    Architecture review at 6f4f025 (2026-09-24): keep this issue as the operator-facing degraded-stream readout. The broader problem — typed snapshot, redacted qualification JSON, and HTTP/OSC ControlState drifting independently — is #621. Implement #610 on one projection; do not hand-write a fourth.

  2. iamfatness commented on Sep 29, 2026

    @iamfatness
    OwnerAuthor

    2026-09-29 live YouTube test reproduction on #703 Windows Release app build 3c4507d2 (watch event _u4AlERgci4): owner saw YouTube low throughput. After the bounded A/V pattern send ended and the app RTMP sender was restored, the app's own sender repeatedly sat at backpressure.level=3, appliedDivisor=4 (effective 15 fps from 60 fps Program) while status=live, destinationHealth=ok, and the snapshot queue happened to read bufferedMs=0. This is not proof of recovery: the native log shows repeated recovery steps followed by rapid re-entry, e.g. 16:30:31 step-down to divisor 3 at 0 ms, 16:30:34 step-up to 4 at 438 ms; 16:31:45 step-down to 3, 16:31:50 step-up to 4 at 543 ms. At 16:31:50-52 the video pipe recorded WriteFile calls lasting 101-260 ms for ~13-22 KiB chunks, then a pipe-break error 232. No per-socket network cause has been established. At a later snapshot the sender remained live/ok with divisor 4, 191 discarded chunks and 503 slow writes. App UI showed RTMP live 10 Mbps and frame drops ~0.2%, without stating the current effective 15 fps. Logs: %LOCALAPPDATA%/CoreVideoPro/media-core.log from this app session. This matches the prior pipe/backpressure failure class and provides a current full-meeting reproduction; it should be investigated against the sender/FFmpeg/network boundary, not explained away as only the brief encoder switch used for the A/V test.

  3. added a commit that references this issue on Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogRanked in docs/BACKLOG.md

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions