Size-band scoring #63
Reference in New Issue
Block a user
Delete Branch "issue/13-size-scoring"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Scores a candidate by distance from a target size (DESIGN.md §5.5) instead of by source tier.
SizeBandgainspenalty_points_per_gib_over;Policygainsscore_weights, and migration 0004 puts both in thepoliciesrows — floor, target, penalty and the three term weights are all tunable per policy, as §5.5 requires.arr-core::score: size ramp from floor to target, growing penalty above it, source tier as a small tiebreaker, seeders log-scaled by doubling.SizeRulein the verdict pipeline: below the floor is a hard filter, not a low score.evaluateandEvaluationContextgainsize_bytes, since neitherNameClaimsnorProbedMediacarries one.Acceptance:
twenty_gigabyte_web_dl_beats_a_sixty_gigabyte_remuxranks a four-candidate set, andthe_remux_still_wins_when_it_is_the_only_candidateshows the 60 GB remux scoring badly while stayingEligible.Closes #13
@@ -130,1 +135,4 @@pub target_bytes: u64,/// Points lost per gigabyte above `target_bytes`, against the scale set/// by [`ScoreWeights::size_at_target`].pub penalty_per_gb_over: i32,penalty_per_gb_over: i32cannot represent the existing seeded policy value0.5; retain a fractional or explicitly scaled representation so a policy row can round-trip without changing its penalty.@@ -0,0 +28,4 @@/// Points per step of the policy's `source_weights`. Small: the source/// tier is a tiebreaker.pub source_tier: i32,/// Points per doubling of the seeder count. Log-scaled and small —The new score scales remain
Defaultconstants while thepoliciesschema stores no score-weight data; persist them with each policy (and migrate/seed them) so the ranking remains tunable per policy row.Fixed, though not by making the field fractional.
0.5was on no scale — the seed predates any scoring code, so there was nothing for it to round-trip to. Migration 0004 restates both bands in the scorer's own units:penalty_points_per_gib_over: 60, againstsize_at_target: 1000. One point is a tenth of a percent of the target score and the penalty is applied per byte over, so a partial gibibyte still costs its fraction — the granularity a fractional type would buy is below what anyone tunes at.The field is now named for its unit, so a row and the type it loads into cannot disagree about what the number means.
Done. Migration 0004 adds a
score_weightscolumn topoliciesand seeds{"size_at_target":1000,"source_tier":25,"seeder_doubling":8};arr-dbasserts every policy row carries all three, alongside the band's floor, target and penalty.ScoreWeights::default()stays as the value tests construct and as the documented placeholder, but it is no longer the only place the numbers exist.@@ -0,0 +12,4 @@CHECK (json_valid(score_weights));-- Sizes in gibibytes, matching the bytes the scorer compares, and the penalty-- restated in points: 60 points per gibibyte over target puts a 60 GiB remuxThis unconditionally replaces
size_bandsfor every existing policy, erasing any hand-tuned floors, targets, and penalties; migrate each existing JSON value to the renamed/scaled fields instead of replacing it with the defaults.