Docs-only, single commit off a2b3a56d9. Adds the v26.14.0 row to the release table in docs/ci-cd.md. This is the commit the v26.14.0 tag will be pushed onto, matching how v26.13.0 was cut (#716).
Replaces #738, which never received a pull_request CI run — see below.
Headline is #726. -readrate paces an input off its furthest-behind stream, and an embedded PGS/DVD subtitle is read through the video's own -i — sparse enough to drag the whole process to 0.53x realtime against the 1.0x a client consumes, draining the buffer until the channel stalls. Fixed with a capability-gated -readrate_catchup (ffmpeg 8.0+), keeping -readrate on the frame-producing path so ffmpeg.qsv-extra-hw-frames-floor is untouched. Measured 0.533x → 1.067x on QSV and software libx264; 240s QSV soak clean of allocation errors. Affects 3,182 of 24,646 media versions on prod, and it's a property of the item, not the channel.
#738 received no pull_request run across six trigger attempts, all verified against the actions/runs API (not actions/tasks, which does not surface in-progress runs):
attempt
result
push b48f44dc7
no run
push 21f0e50fd (empty commit)
no run
force-push 7b20dbd36 (rebase onto a2b3a56d9)
no run
close + reopen PR
no run
PR body edit (fires pull_request_target: edited)
no run
push 81996709b on an idle queue
no run
Only two things ever produced runs on that branch: Gitea's own Update branch button (0ac25e144 → runs 1561–1563, all green) and a workflow_dispatch I fired (run 1564, green).
Two findings worth recording:
workflow_dispatch runs write no commit statuses. Run 1564 completed successfully and left count: 0 on the commit's status list — so dispatching cannot satisfy Build & test (.NET) or review-verdict/h10, and is useless as a re-trigger for a merge.
actions/tasks hides in-progress runs. Polling it made live runs look like a dead event pipeline; I briefly and wrongly concluded the runners were down. actions/runs is the authoritative view — runs 1560 and 1564 were in flight the whole time.
This PR is a fresh branch and a fresh opened event, which is a different path from the synchronize-class events every #738 attempt used.
Release preflight (phase 1 of docs/ci-cd.md → "Cutting a release")
decisions_validate — OK (now PyYAML-aware via #725)
build_decisions_catalog — no drift
pytest scripts/tests — 432 passed
dotnet list package --vulnerable --include-transitive — clean across all 17 projects
main CI green: run 1560 (a2b3a56d9) completed success; queue idle, so a tag build won't contend with a main build over :buildcache / the smoke container name
No [skip ci] token in this commit (it is the tag target)
After this merges
Push v26.14.0 on the merge commit, detaching at origin/main first (H11 tag-push guard — #719).
Wait for tag CI to build :prod + immutable :26.14.0 + :<sha>.
scripts/security-scan.sh on jazz against the immutable :26.14.0; triage every finding.
Only then DeployStack jazz-media (media-servers is the dead stack on bumblebee — confirm with /read ListStacks). Promotion is manual; auto_update: false.
Docs-only, single commit off `a2b3a56d9`. Adds the `v26.14.0` row to the release table in `docs/ci-cd.md`. This is the commit the `v26.14.0` tag will be pushed onto, matching how `v26.13.0` was cut (#716).
**Replaces #738**, which never received a `pull_request` CI run — see below.
## What's in v26.14.0
Everything on `main` since `v26.13.0`:
| Change | Kind |
|---|---|
| **#726** — embedded bitmap-subtitle `-readrate` starvation (0.53x realtime → stalling Live TV) | app fix |
| **#674 / #688** — decisions validator cross-checks frontmatter against PyYAML | tooling |
| **#706 / #707 / #711** — H10 review-verdict gate raced-sentinel false-open | CI/process |
| CliWrap 3.10.4 | dependency |
| JetBrains.ReSharper.GlobalTools 2025.3.5 | dev dependency |
Headline is #726. `-readrate` paces an input off its *furthest-behind* stream, and an embedded PGS/DVD subtitle is read through the video's own `-i` — sparse enough to drag the whole process to **0.53x realtime** against the 1.0x a client consumes, draining the buffer until the channel stalls. Fixed with a capability-gated `-readrate_catchup` (ffmpeg 8.0+), keeping `-readrate` on the frame-producing path so `ffmpeg.qsv-extra-hw-frames-floor` is untouched. Measured 0.533x → 1.067x on QSV and software libx264; 240s QSV soak clean of allocation errors. Affects 3,182 of 24,646 media versions on prod, and it's a property of the *item*, not the channel.
## Why this PR exists instead of #738
#738 received **no `pull_request` run** across six trigger attempts, all verified against the `actions/runs` API (not `actions/tasks`, which does not surface in-progress runs):
| attempt | result |
|---|---|
| push `b48f44dc7` | no run |
| push `21f0e50fd` (empty commit) | no run |
| force-push `7b20dbd36` (rebase onto `a2b3a56d9`) | no run |
| close + reopen PR | no run |
| PR body edit (fires `pull_request_target: edited`) | no run |
| push `81996709b` on an idle queue | no run |
Only two things ever produced runs on that branch: Gitea's own **Update branch** button (`0ac25e144` → runs 1561–1563, all green) and a **`workflow_dispatch`** I fired (run 1564, green).
Two findings worth recording:
1. **`workflow_dispatch` runs write no commit statuses.** Run 1564 completed successfully and left `count: 0` on the commit's status list — so dispatching cannot satisfy `Build & test (.NET)` or `review-verdict/h10`, and is useless as a re-trigger for a merge.
2. **`actions/tasks` hides in-progress runs.** Polling it made live runs look like a dead event pipeline; I briefly and wrongly concluded the runners were down. `actions/runs` is the authoritative view — runs 1560 and 1564 were in flight the whole time.
This PR is a fresh branch and a fresh `opened` event, which is a different path from the `synchronize`-class events every #738 attempt used.
## Release preflight (phase 1 of `docs/ci-cd.md` → "Cutting a release")
- `decisions_validate` — OK (now PyYAML-aware via #725)
- `build_decisions_catalog` — no drift
- `pytest scripts/tests` — 432 passed
- `dotnet list package --vulnerable --include-transitive` — clean across all 17 projects
- `main` CI green: run 1560 (`a2b3a56d9`) completed success; queue idle, so a tag build won't contend with a `main` build over `:buildcache` / the smoke container name
- No `[skip ci]` token in this commit (it is the tag target)
## After this merges
1. Push `v26.14.0` on the merge commit, detaching at `origin/main` first (H11 tag-push guard — #719).
2. Wait for tag CI to build `:prod` + immutable `:26.14.0` + `:<sha>`.
3. `scripts/security-scan.sh` on jazz against the **immutable `:26.14.0`**; triage every finding.
4. Only then `DeployStack jazz-media` (`media-servers` is the dead stack on bumblebee — confirm with `/read ListStacks`). Promotion is manual; `auto_update: false`.
Adds the v26.14.0 row to the release table. This is the commit the v26.14.0 tag
will be pushed onto, matching how v26.13.0 was cut (#716).
Contents since v26.13.0: the #726 bitmap-subtitle -readrate starvation fix
(headline), the #674/#688 decisions-validator PyYAML cross-check, the
#706/#707/#711 review-verdict raced-sentinel fix, and two Renovate bumps.
Replaces the branch behind PR #738, which never received a pull_request CI run
across six trigger attempts (two pushes, a force-push after rebase, a
close/reopen, a body edit, and a spaced push on an idle queue). A
workflow_dispatch run did complete green but writes no commit statuses, so it
cannot satisfy the required checks. Opening a fresh PR produces an `opened`
event rather than a synchronize, which is a different path.
No [skip ci] token -- this branch's merge commit is the v26.14.0 tag target.
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.
Docs-only, single commit off
a2b3a56d9. Adds thev26.14.0row to the release table indocs/ci-cd.md. This is the commit thev26.14.0tag will be pushed onto, matching howv26.13.0was cut (#716).Replaces #738, which never received a
pull_requestCI run — see below.What's in v26.14.0
Everything on
mainsincev26.13.0:-readratestarvation (0.53x realtime → stalling Live TV)Headline is #726.
-readratepaces an input off its furthest-behind stream, and an embedded PGS/DVD subtitle is read through the video's own-i— sparse enough to drag the whole process to 0.53x realtime against the 1.0x a client consumes, draining the buffer until the channel stalls. Fixed with a capability-gated-readrate_catchup(ffmpeg 8.0+), keeping-readrateon the frame-producing path soffmpeg.qsv-extra-hw-frames-flooris untouched. Measured 0.533x → 1.067x on QSV and software libx264; 240s QSV soak clean of allocation errors. Affects 3,182 of 24,646 media versions on prod, and it's a property of the item, not the channel.Why this PR exists instead of #738
#738 received no
pull_requestrun across six trigger attempts, all verified against theactions/runsAPI (notactions/tasks, which does not surface in-progress runs):b48f44dc721f0e50fd(empty commit)7b20dbd36(rebase ontoa2b3a56d9)pull_request_target: edited)81996709bon an idle queueOnly two things ever produced runs on that branch: Gitea's own Update branch button (
0ac25e144→ runs 1561–1563, all green) and aworkflow_dispatchI fired (run 1564, green).Two findings worth recording:
workflow_dispatchruns write no commit statuses. Run 1564 completed successfully and leftcount: 0on the commit's status list — so dispatching cannot satisfyBuild & test (.NET)orreview-verdict/h10, and is useless as a re-trigger for a merge.actions/taskshides in-progress runs. Polling it made live runs look like a dead event pipeline; I briefly and wrongly concluded the runners were down.actions/runsis the authoritative view — runs 1560 and 1564 were in flight the whole time.This PR is a fresh branch and a fresh
openedevent, which is a different path from thesynchronize-class events every #738 attempt used.Release preflight (phase 1 of
docs/ci-cd.md→ "Cutting a release")decisions_validate— OK (now PyYAML-aware via #725)build_decisions_catalog— no driftpytest scripts/tests— 432 passeddotnet list package --vulnerable --include-transitive— clean across all 17 projectsmainCI green: run 1560 (a2b3a56d9) completed success; queue idle, so a tag build won't contend with amainbuild over:buildcache/ the smoke container name[skip ci]token in this commit (it is the tag target)After this merges
v26.14.0on the merge commit, detaching atorigin/mainfirst (H11 tag-push guard — #719).:prod+ immutable:26.14.0+:<sha>.scripts/security-scan.shon jazz against the immutable:26.14.0; triage every finding.DeployStack jazz-media(media-serversis the dead stack on bumblebee — confirm with/read ListStacks). Promotion is manual;auto_update: false.