Normalise season pack size by episode count when scoring #180

Closed
opened 2026-08-24 19:30:29 +01:00 by naps62-yolo · 0 comments
Owner

Depends on: #179

score() takes size_bytes and compares it against the band for the claimed
resolution with no notion of how much video that size covers:

pub fn score(policy: &Policy, candidate: Candidate<'_>, size_bytes: u64, seeders: u32) -> Score

score_release passes release.size straight through, so a ten-episode season
pack is measured against a band written for one episode. The penalty grows with
every gigabyte over target, so the more episodes a pack holds the worse it
scores — the opposite of what a pack should do.

Observed on Rick and Morty S08 against TV — main (1080p target 2 GiB, 2160p
target 6 GiB, 60 points per GiB over, resolution step 300):

Release Size Over target Size penalty Total
Rick.and.Morty.S08.1080p.x265-ELiTE 4.3 GiB 2.3 GiB −138 917
Rick and Morty - S08 - Complete - 2160p HDR 13.8 GiB 7.8 GiB −468 896

The 330-point gap in size penalty beats the 300-point resolution step, so the
1080p release wins despite resolution_pref being ["2160p", "1080p"].

Implement §5 as amended by #179: divide the release size by the number of
episodes it covers before comparing against the band, in both score and
is_below_floor.

arr-core has no IO, so the caller supplies the count, the way
apply_auto_track(series, ever_refreshed, seasons) already takes a fact it
cannot look up. Design the signature; the count is not derivable inside
arr-core because a Season claim names a season, not a length.

arr_parse::EpisodeClaim already distinguishes Season, Seasons and
Episodes and carries is_season_pack(), so the parse side needs nothing new.
An Episodes claim knows its own length; a Season or Seasons claim needs
the season's episode count from the database.

Callers to update: crates/arr-api/src/series.rs (both rescore sites),
crates/arr-api/src/search.rs, crates/arr-api/src/movies.rs and
crates/arr-daemon/src/grab.rs. A movie passes one episode's worth and must
score exactly as it does today — add a test pinning that, so this change cannot
quietly move movie scoring.

Tests: a season pack and a single episode of the same per-episode size score the
same size term; a pack whose per-episode size is under the floor is rejected; the
S08 case above ranks 2160p above 1080p; an unknown episode count falls back to
one episode.

Depends on: #179 `score()` takes `size_bytes` and compares it against the band for the claimed resolution with no notion of how much video that size covers: ```rust pub fn score(policy: &Policy, candidate: Candidate<'_>, size_bytes: u64, seeders: u32) -> Score ``` `score_release` passes `release.size` straight through, so a ten-episode season pack is measured against a band written for one episode. The penalty grows with every gigabyte over target, so the more episodes a pack holds the worse it scores — the opposite of what a pack should do. Observed on Rick and Morty S08 against `TV — main` (1080p target 2 GiB, 2160p target 6 GiB, 60 points per GiB over, resolution step 300): | Release | Size | Over target | Size penalty | Total | |---|---|---|---|---| | `Rick.and.Morty.S08.1080p.x265-ELiTE` | 4.3 GiB | 2.3 GiB | −138 | **917** | | `Rick and Morty - S08 - Complete - 2160p HDR` | 13.8 GiB | 7.8 GiB | −468 | **896** | The 330-point gap in size penalty beats the 300-point resolution step, so the 1080p release wins despite `resolution_pref` being `["2160p", "1080p"]`. Implement §5 as amended by #179: divide the release size by the number of episodes it covers before comparing against the band, in both `score` and `is_below_floor`. `arr-core` has no IO, so **the caller supplies the count**, the way `apply_auto_track(series, ever_refreshed, seasons)` already takes a fact it cannot look up. Design the signature; the count is not derivable inside `arr-core` because a `Season` claim names a season, not a length. `arr_parse::EpisodeClaim` already distinguishes `Season`, `Seasons` and `Episodes` and carries `is_season_pack()`, so the parse side needs nothing new. An `Episodes` claim knows its own length; a `Season` or `Seasons` claim needs the season's episode count from the database. Callers to update: `crates/arr-api/src/series.rs` (both `rescore` sites), `crates/arr-api/src/search.rs`, `crates/arr-api/src/movies.rs` and `crates/arr-daemon/src/grab.rs`. A movie passes one episode's worth and must score exactly as it does today — add a test pinning that, so this change cannot quietly move movie scoring. Tests: a season pack and a single episode of the same per-episode size score the same size term; a pack whose per-episode size is under the floor is rejected; the S08 case above ranks 2160p above 1080p; an unknown episode count falls back to one episode.
naps62-yolo added this to the Season packs milestone 2026-08-24 19:30:29 +01:00
naps62-yolo added the area/coredifficulty/hardtype/bug labels 2026-08-24 19:30:29 +01:00
naps62-yolo added a new dependency 2026-08-24 19:30:29 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: yolo/arr#180