Make the quality profile cutoff a ceiling, not just a stopping point - #17
Merged
Conversation
Live symptom: an upgrade request set to 1080p grabbed a 2160p release instead. Root cause: every seeded quality profile (Any, HD-1080p, Ultra-HD) marks every tier from its floor up through 8K as "allowed" — that list only ever existed to gate the floor. ReleaseEvaluator scored a release's rank in that allowed list, so a higher tier always scored higher and won, regardless of the profile's cutoff. Nothing ever said no to going above what was actually requested. A user who picks "1080p" means exactly that — bigger files, more bandwidth, and playback devices that may not handle 4K weren't asked for. ReleaseEvaluator now ranks the profile's cutoff the same way it ranks a candidate's own tier, and rejects anything strictly above it with a new AboveCutoff rejection reason. The one exception is the existing relaxation path: once repeated empty searches have found nothing AT the target, something above it is better than nothing, matching how below-floor relaxation already works. Added two tests pinning the behavior (reject above cutoff; relaxation still admits it) using the same "allow everything above floor" profile shape the seeded production profiles use, so this doesn't regress silently. 125/125 tests pass, build clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Live bug, caught during the House of the Dragon upgrade test in PR #16: a request targeting 1080p grabbed a
2160p.MAX.WEB-DL.DV.HDRrelease instead.Root cause, confirmed against the live DB: every seeded profile (
Any,HD-1080p,Ultra-HD) marks every tier from its floor up through 8K asallowed: trueinItemsJson. That list only ever existed to gate the floor ("nothing below 720p"), butReleaseEvaluatorscores a candidate's rank in that allowed list (Profile rank" = r * 100, the dominant score term) and accepts anything allowed — so a 2160p release, ranked far above 1080p, always won when one was available. TheCutoffQualityDefinitionIdwas only ever consulted to decide whether to keep searching, never to cap what gets accepted.Fix
ReleaseEvaluator.Evaluatenow ranks the profile's cutoff the same way it ranks a candidate's own tier and rejects anything strictly above it (RejectionReason.AboveCutoff) — a hard ceiling, matching "give me 1080p" as meaning exactly that, not "1080p or better." The existing relaxation path (nothing at target found after repeated empty searches) still admits above-cutoff releases, same as it already does for below-floor ones — something is better than nothing once the target has genuinely been exhausted.Verification
Rejects_a_tier_above_the_profiles_cutoff,Relaxing_admits_a_tier_above_cutoff_when_nothing_at_target_was_found.Not addressed here: the House of the Dragon request currently sits on the
Anyprofile (which allows everything, a migration-era catch-all), not a profile actually scoped to 1080p. That's a separate seeding/assignment question — this PR fixes the evaluator so that whatever profile a request is on, its cutoff is respected as a ceiling.