Scale the size band by episode runtime #209

Closed
opened 2026-08-24 21:43:03 +01:00 by naps62-yolo · 2 comments
Owner

Depends on: #187

Implement the §5.5 amendment from #187: the per-episode size comparison scales
with the episode's runtime instead of assuming a fixed length.

score and is_below_floor already take episode_count (#180). They now need
the runtime too, and the same rule applies as before: arr-core has no IO, so
the caller supplies it.
apply_auto_track(series, ever_refreshed, seasons)
and #180's episode_count are both precedent.

Runtime comes from TMDB and is already persisted for series metadata; check what
crates/arr-meta and the series table hold before adding a column. If it is
not stored, storing it is in scope — a new migration, never an edit to an
applied one.

Missing or zero runtime falls back to the reference runtime, reproducing
today's behaviour.

Callers to update, the same set #180 touched: crates/arr-api/src/series.rs
(both rescore sites), crates/arr-api/src/search.rs,
crates/arr-api/src/movies.rs, crates/arr-daemon/src/grab.rs.

Tests:

  • a 22-minute episode and a 45-minute episode of the same bitrate score the same
    size term
  • the Rick and Morty S09 packs above stop being rejected below floor
  • a movie scores exactly as it does today — pin it, the same way #180 pinned
    movie scoring against pack normalisation
  • missing runtime reproduces the pre-change score
Depends on: #187 Implement the §5.5 amendment from #187: the per-episode size comparison scales with the episode's runtime instead of assuming a fixed length. `score` and `is_below_floor` already take `episode_count` (#180). They now need the runtime too, and the same rule applies as before: **`arr-core` has no IO, so the caller supplies it.** `apply_auto_track(series, ever_refreshed, seasons)` and #180's `episode_count` are both precedent. Runtime comes from TMDB and is already persisted for series metadata; check what `crates/arr-meta` and the `series` table hold before adding a column. If it is not stored, storing it is in scope — a **new** migration, never an edit to an applied one. Missing or zero runtime falls back to the reference runtime, reproducing today's behaviour. Callers to update, the same set #180 touched: `crates/arr-api/src/series.rs` (both rescore sites), `crates/arr-api/src/search.rs`, `crates/arr-api/src/movies.rs`, `crates/arr-daemon/src/grab.rs`. Tests: - a 22-minute episode and a 45-minute episode of the same bitrate score the same size term - the Rick and Morty S09 packs above stop being rejected below floor - a movie scores exactly as it does today — pin it, the same way #180 pinned movie scoring against pack normalisation - missing runtime reproduces the pre-change score
naps62-yolo added this to the Size bands and waivers milestone 2026-08-24 21:43:03 +01:00
naps62-yolo added the area/coretype/bugdifficulty/hard labels 2026-08-24 21:43:03 +01:00
naps62-yolo added a new dependency 2026-08-24 21:43:03 +01:00
Author
Owner

Correcting an acceptance criterion in this issue: "the Rick and Morty S09
packs stop being rejected below floor" is wrong and must not be implemented.

Checked against production after #208 settled the reference runtime at 45
minutes:

  • scaled 1080p floor at 22 minutes is 1 GiB × 22/45 = 0.489 GiB/episode
  • the three S09 packs are 0.32, 0.24 and 0.19 GiB/episode

All three stay below the floor after scaling. They are genuinely low-bitrate —
0.32 GiB for a 22-minute episode is about 2.1 Mbps — and the floor is doing its
job. Do not tune the reference runtime, the scale formula, or anything else to
force those packs through; that would be fitting the model to one bad example.

Second, and more limiting: GET /api/series/1/metadata returns
"runtime": null for Rick and Morty in production. TMDB's episode_run_time
is frequently empty for returning series. Under §5.5 as amended, a missing
runtime means a scale factor of 1, so for this series — and any other with no
runtime — this issue changes nothing at all.

That does not make the issue wrong. A 22-minute show whose runtime is known
should not be judged against 45-minute bands, and that is worth fixing. But it
does mean:

  • the acceptance criteria must not include the S09 packs becoming eligible
  • it is worth checking, while in arr-meta, whether a per-episode runtime can
    be recovered when episode_run_time is empty — TMDB exposes runtime on the
    episode records themselves, and the season refresh already walks them. If
    that is more than a small change, comment here and leave it; do not widen
    this issue into a metadata project.

Replace the S09 criterion with: a series whose runtime is known and short is
judged against a proportionally scaled floor and target, proven by test at both
22 and 45 minutes.

Correcting an acceptance criterion in this issue: **"the Rick and Morty S09 packs stop being rejected below floor" is wrong and must not be implemented.** Checked against production after #208 settled the reference runtime at 45 minutes: - scaled 1080p floor at 22 minutes is `1 GiB × 22/45` = **0.489 GiB/episode** - the three S09 packs are 0.32, 0.24 and 0.19 GiB/episode All three stay below the floor after scaling. They are genuinely low-bitrate — 0.32 GiB for a 22-minute episode is about 2.1 Mbps — and the floor is doing its job. Do not tune the reference runtime, the scale formula, or anything else to force those packs through; that would be fitting the model to one bad example. Second, and more limiting: `GET /api/series/1/metadata` returns `"runtime": null` for Rick and Morty in production. TMDB's `episode_run_time` is frequently empty for returning series. Under §5.5 as amended, a missing runtime means a scale factor of 1, so for this series — and any other with no runtime — this issue changes nothing at all. That does not make the issue wrong. A 22-minute show whose runtime *is* known should not be judged against 45-minute bands, and that is worth fixing. But it does mean: - the acceptance criteria must not include the S09 packs becoming eligible - it is worth checking, while in `arr-meta`, whether a per-episode runtime can be recovered when `episode_run_time` is empty — TMDB exposes runtime on the episode records themselves, and the season refresh already walks them. If that is more than a small change, comment here and leave it; do not widen this issue into a metadata project. Replace the S09 criterion with: a series whose runtime is known and short is judged against a proportionally scaled floor and target, proven by test at both 22 and 45 minutes.
Author
Owner

Checked the episode-record fallback while in arr-meta: it is more than a small change, so leaving it per the correction above.

The refresh only fetches season detail for seasons the library has not seen — known seasons sync through the lighter per-season endpoint and the series row. Recovering a runtime when episode_run_time is empty would mean either fetching season detail on every refresh or adding a derivation rule (which episode's runtime, how to aggregate a range like 19–23 minutes) plus a second persistence path. That is a metadata project of its own; this issue lands with the series-level episode_run_time only, stored on add and on refresh, and a known value is never blanked by TMDB's empty spells.

Checked the episode-record fallback while in `arr-meta`: it is more than a small change, so leaving it per the correction above. The refresh only fetches season detail for seasons the library has not seen — known seasons sync through the lighter per-season endpoint and the series row. Recovering a runtime when `episode_run_time` is empty would mean either fetching season detail on every refresh or adding a derivation rule (which episode's runtime, how to aggregate a range like 19–23 minutes) plus a second persistence path. That is a metadata project of its own; this issue lands with the series-level `episode_run_time` only, stored on add and on refresh, and a known value is never blanked by TMDB's empty spells.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: yolo/arr#209