Compare commits

...
4 Commits
Author SHA1 Message Date
timothy 81996709b0 chore(release): re-trigger PR CI for v26.14.0
Prior attempts on this branch produced no pull_request run: two CLI pushes, a
close/reopen, and a body edit all yielded nothing, and the workflow_dispatch I
fired (run 1564) went green but writes NO commit statuses, so it cannot satisfy
the required Build & test / review-verdict/h10 checks.

The queue is now idle (run 1560, main @ a2b3a56d9, completed success), which is
the condition docs/ci-cd.md says matters -- back-to-back pushes get silently
dropped, a spaced-out one does not.

No [skip ci] token -- this branch's merge commit is the v26.14.0 tag target.
2026-08-05 00:30:55 +02:00
timothy 7b20dbd360 docs(release): fold #674/#688 into the v26.14.0 notes after rebasing on main
main moved while this branch was open: #725 (fix/674-688-decisions-validator)
merged, so v26.14.0 now also carries the decisions-validator PyYAML cross-check.
Rebased onto a2b3a56d9 rather than merging main in, per
release.format-as-you-touch-rebase.

The added claim is verified, not assumed: re-breaking this release's own
readrate-catchup record (unquoting rule: so an unquoted " #350" truncates it)
now fails decisions_validate with

  frontmatter key 'rule' means different things to the two parsers ...
  PyYAML wrote this file, so its reading is the real value and the record is
  silently corrupt. Common cause: an unquoted ` #` ...

which is exactly the defect that reached CI earlier in this session (57ad5efb3)
because the pre-#725 validator could not see it. Local gate now catches it.

scripts/tests: 432 passed (was 411 before #725 added its cases).

No [skip ci] token -- this branch's merge commit is the v26.14.0 tag target.
2026-08-04 23:49:35 +02:00
timothy e997668ac4 chore(release): re-trigger CI for v26.14.0 release notes
The release/v26.14.0 push produced NO ActionRun records at all -- verified
against 7168 listed tasks, zero for b48f44dc7. This is the documented Gitea
behavior in docs/ci-cd.md: several pushes fired back-to-back (the #737 merge,
then this branch, then the PR open) and the later events were silently dropped.
The remedy is a spaced-out re-push, not assuming the runner is broken.

No [skip ci] token -- this branch's merge commit is the v26.14.0 tag target.
2026-08-04 23:47:11 +02:00
timothy 9a3371ecd9 docs(release): record the v26.14.0 release notes
Headline is ersatztv#726: Live TV stalled on any item carrying an embedded
PGS/DVD bitmap subtitle, because -readrate paces an input off its furthest-behind
stream and that sparse subtitle shares the video's own -i. Fixed with a
capability-gated -readrate_catchup rather than the structural change the issue
originally proposed, which would have removed the throttle from the
frame-producing path that ffmpeg.qsv-extra-hw-frames-floor depends on.

Also in this release: the H10 review-verdict gate's raced-sentinel false-open
(#706/#707/#711), and two Renovate dependency bumps.

No [skip ci] token -- this commit is the release tag target, and Gitea reads
skip-ci from the TAGGED commit, which would suppress the release build.

Refs #726
2026-08-04 23:47:11 +02:00
+1
View File
@@ -40,6 +40,7 @@ Upstream's final release was **`v26.3.0`** (archived). Our line continues from t
| `v26.11.0` | **QSV profiles decode via VA-API**`QsvPreferNativeDecoder`, default **on**, fixes ~50% channel cold-start failures on Intel (#498); unified logo/on-screen bug via a shared watermark preset (#67). Media-scanner resilience: Jellyfin mixed-content libraries (#489), music-video scan correctness (#488/#494/#497), remote-stream probing before ffmpeg (#473/#480); weighted-distribution SPA (#404). **First release deployed to `jazz`** (server-management#633). |
| `v26.12.0` | **`ErsatzTV.Mcp` MCP server** — read + cautious-write over `/api/v1`, `ERSATZTV_ALLOW_WRITES`-gated (#58). **External channel-logo URLs download + cache at save time** (#525), with the on-screen bug now rendered for external-URL logos (#502). HLS cold-start hardening: burst-read the first segments so start isn't `-readrate`-bound (#350) and floor QSV extra hardware frames so an unthrottled read can't exhaust the pool (#529); remote graphics-engine image fetches bounded — timeout, size cap, decode cap, redirects, pooling (#511). Decision-lifecycle tooling + parallel-orientation startup rewrite (#520/#521); CI `docker build` lane rebalance (#508). |
| `v26.13.0` | **RuleBuilder maturation** — arbitrary-depth group nesting (#436), inline smart-query authoring in Channel Builder (#437), DB-sourced facet typeahead + relative-date operators + validation (#434/#435/#438), and an artist typeahead covering music-video/song credits with `album_artist` no longer 404ing (#578). **Per-channel On Now/Next transient overlay** (#74/#570) and **per-schedule clock-boundary padding** (#392); in-browser channel preview (#60); Auto-Tune per-source weight steppers + exclude/add-untagged (#440). Library-browse pickers now resolve by search instead of a 100-row window, closing several silent at-cap truncations (#644/#650/#651/#634). Correctness: one watermark resolver for all four attachment points, incl. `MiddleCenter` (#503/#510); QSV HDR tonemaps through OpenCL because `vpp_qsv=tonemap` is a silent no-op (#505); `LibraryFolder` unique index + concurrent-insert tolerance (#491); per-library music-video identity with soft trash (#496); Jellyfin Album/Track music-video projection (#177); metadata-collection dedup (#500); accented facet values via a registered Unicode fold on SQLite (#668); `WorkAheadSlots` atomic slot claim, never a negative count (#536/#539); on-demand guide rebuild on thaw (#68). Process/CI: the H10 review-verdict gate became a sha-bound **required** commit status and was hardened through its false-open chain (#622/#629/#632/#648/#649/#672/#698), the decision corpus split to one YAML-frontmatter record per file (#610/#620), and headless Playwright UI-E2E flows landed (#445/#533). Five dual-provider migrations. |
| `v26.14.0` | **Live TV no longer starves on embedded bitmap subtitles**`-readrate` paces an input off its *furthest-behind* stream, and a PGS/DVD subtitle read through the video's own `-i` is 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+) on realtime inputs, keeping `-readrate` on the frame-producing path so the `ffmpeg.qsv-extra-hw-frames-floor` bound is untouched; measured 0.533x → 1.067x on QSV and software, with a 240s QSV soak clean of allocation errors (#726). Affects items carrying an embedded bitmap subtitle matching the channel's subtitle mode — 3,182 of 24,646 media versions on prod, and a property of the *item*, not the channel, which is why the stall presented as random. Process/CI: the H10 review-verdict gate's repair sentinel became a fixed point and its write is now fenced on the timeline retarget count, closing a raced-sentinel false-open (#706/#707/#711). **The decisions validator now cross-checks its dependency-free frontmatter parse against PyYAML** and reports both the truncating unquoted `` #`` and the scalar-closing bare apostrophe as errors, so a record whose `rule:` silently halves under PyYAML fails the local gate instead of CI (#674/#688) — the ceiling-calibration claim was also split so the suite pins what the derivation MEANS rather than live-corpus order statistics. Dependencies: CliWrap 3.10.4, JetBrains.ReSharper.GlobalTools 2025.3.5. |
**Before cutting a release — sweep `docs/decisions.md` + `docs/decisions/`** (ersatztv#521, supersedes
the ersatztv#303 H9 append-only ritual). Supersession/retirement is now a same-PR act (add the new