feat: queue only targets still waiting for a file

The needs-a-decision queue had no liveness condition on the season lane
and none at all in the API reader, so a season pack that hard-failed
twice, fell back to per-episode grabbing exactly as §6.2 intends, and was
then fully acquired kept notifying for 30 days, and
`GET /api/queues/attention` listed titles the daemon never notified on.

DESIGN.md §5.7 now states the third face of the same rule alongside the
count and the window: a movie or an episode is queued while `wanted` and
not `available`; a season, holding no intent of its own (§4.1), while at
least one of its episodes is. Both readers apply it on all three lanes.

`just ci` passed through the gate.
This commit is contained in:
Miguel Palhas
2026-08-25 10:49:02 +01:00
parent 50056a2bd9
commit 6847d25cf5
8 changed files with 365 additions and 66 deletions
+16
View File
@@ -395,6 +395,22 @@ guard retries at worst weekly (§6.2) — and stays queued for exactly as long a
it is genuinely broken. Nothing is dismissed by hand and no acknowledgement
state is stored, so there is no second thing to keep correct.
**Only a target still waiting for a file is queued.** The count and the window
are one rule seen twice — the queue is meant to be visited and emptied — and
this is its third face: a failure history queues a target only while that
target still has a gap to fill. A movie or an episode is queued while it is
`wanted` and not `available`. A season holds no intent of its own (§4.1), so it
is queued while at least one of its episodes is still wanted and still without
a file. A season pack that hard-failed twice, fell back to per-episode grabbing
exactly as §6.2 says it should, and was then fully acquired leaves at once
rather than waiting out the 30 days — that is the system working, not a
decision. A target that is still broken keeps producing failures and stays.
The same rule applies on all three lanes and in both readers.
`GET /api/queues/attention` (§9.3) and the `ntfy` notification (§9.5) are two
views of one queue; filtering differently tells the operator two different
stories on two channels.
## 6. Sourcing
### 6.1 Prowlarr, per-indexer Torznab