Record which rule a waiver relaxed #211

Closed
opened 2026-08-24 22:15:27 +01:00 by naps62-yolo · 0 comments
Owner

A waived release cannot record which rule it waived, so the §9.3 deck shows
waived with no rule beside it while every rejected row names its own.

releases carries:

CHECK ((verdict = 'rejected') = (rejected_rule IS NOT NULL))

so a waived row must store rejected_rule = NULL. The daemon already writes
it that way (verdict_columns in arr-daemon/src/grab.rs maps
Verdict::Waived(_) to ("waived", None)), and #210's size waiver does the
same because the constraint leaves no choice.

That loses information §5.7 says is worth keeping: a waiver is "watchable but
not what was asked", and which rule was relaxed is the whole content of that
sentence. Before #210 the case was rare enough not to show; now the ordinary
outcome of waiving a size rejection is three rows that say only waived.

The fix is a migration relaxing the constraint to require a rule on a rejection
without forbidding one elsewhere:

CHECK (verdict != 'rejected' OR rejected_rule IS NOT NULL)

then having both the daemon and arr-api's reclassification store the waived
rule. SQLite needs a table rebuild for this, in the shape migration 0014
already uses.

Existing rows keep NULL and read as they do today, so the deck has to go on
tolerating a waived row with no rule.

Found while implementing #210.

A waived release cannot record which rule it waived, so the §9.3 deck shows `waived` with no rule beside it while every rejected row names its own. `releases` carries: ```sql CHECK ((verdict = 'rejected') = (rejected_rule IS NOT NULL)) ``` so a `waived` row must store `rejected_rule = NULL`. The daemon already writes it that way (`verdict_columns` in `arr-daemon/src/grab.rs` maps `Verdict::Waived(_)` to `("waived", None)`), and #210's size waiver does the same because the constraint leaves no choice. That loses information §5.7 says is worth keeping: a waiver is "watchable but not what was asked", and which rule was relaxed is the whole content of that sentence. Before #210 the case was rare enough not to show; now the ordinary outcome of waiving a size rejection is three rows that say only `waived`. The fix is a migration relaxing the constraint to require a rule on a rejection without forbidding one elsewhere: ```sql CHECK (verdict != 'rejected' OR rejected_rule IS NOT NULL) ``` then having both the daemon and `arr-api`'s reclassification store the waived rule. SQLite needs a table rebuild for this, in the shape migration 0014 already uses. Existing rows keep `NULL` and read as they do today, so the deck has to go on tolerating a waived row with no rule. Found while implementing #210.
naps62-yolo added the area/dbphase/6-tvdifficulty/moderatetype/bug labels 2026-08-24 22:15:31 +01:00
naps62-yolo added this to the Feedback pass 2 milestone 2026-08-25 11:31:27 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: yolo/arr#211