diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/detection-findings.md | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/docs/detection-findings.md b/docs/detection-findings.md index 35c4525..c821062 100644 --- a/docs/detection-findings.md +++ b/docs/detection-findings.md @@ -668,3 +668,86 @@ Found by reading the journal after a restart, not by a test: State is also saved after every feed now, so a restart costs one feed's progress rather than a whole cycle's. + +## Detection re-ran forever, and what the first full corpus then showed + +The first complete pass over Peter's 42 feeds finished on 2026-10-06: 322 episodes mirrored, +286 publishing ad breaks. It then kept going over the same unchanged files, producing results +identical to the digit -- Radiolab reported "53:29 of 59:39" four separate times in one day. + +`pollOne` called `detect` unconditionally, and the mirror skips files it already has, so nothing +had changed between passes. One cycle is ~6.5 minutes a show, 4.5 hours for 42 shows, against a +two-hour poll interval: the machine never finished a cycle and never idled -- 13h42m of CPU in +11h of wall clock. Roughly 60% of that was the intro/outro search whose results are deliberately +not published. + +`Episode.DetectedAtUnix` existed but could not be used as the gate: it is only set for episodes +that appear in `result.Offsets`, so an episode nothing was found in never got a timestamp and +the gate would never close. The unit is the batch anyway -- every offset and every break is +found by comparing an episode against the others fetched alongside it, so one arrival or one +pruning legitimately changes all of them. `Show.DetectedBatch` records the set of episode ids +the last completed pass examined, order-independent because feeds are not reliably sorted. +Recorded only after a pass completes, so a cancelled or failed one is retried. + +Deployed 2026-10-07 with the field backfilled for the 42 shows already examined, which saved an +immediate 4.5-hour redundant cycle. Verified in production: 31 feeds polled in five minutes with +exactly one detection running -- The Ezra Klein Show, which had genuinely gained an episode. + +### Filtering by partner count or run length is wrong, and the length gap proves it + +The obvious cleanup is to drop weakly-supported breaks. 635 of 1574 published breaks (40%) have +`partners == 1`, with a median length of 5.0s against 19.0s for `partners >= 4` -- they look +exactly like correlation noise, and 270 of them sit at `MinRunSamples`, the 4-second floor. + +Measured against the declared-versus-served length gap -- the one figure the detector does not +produce -- every such filter makes agreement **worse**: + +| filter | median found/inserted | within 75-125% | skipping on shows with no gap | +|---|---|---|---| +| none (current) | 67% | 31% | 164 min | +| `partners >= 2` | 43% | 17% | 141 min | +| `partners >= 3` | 39% | 13% | 127 min | +| length >= 8s | 58% | 24% | 141 min | +| both | 41% | 13% | 130 min | + +Detection already **under**-reports -- a 67% median means a third of the advertising is missed -- +so removing breaks moves away from the truth, and it barely dents the unverifiable skipping it +was meant to clean up. The single-partner short runs are mostly real advertising. Hypothesis +disproven; the thresholds stay as they are. + +### What is worth fixing is fragmentation + +45% of the gaps between consecutive breaks are under ten seconds, and **152 of 262** multi-break +episodes contain at least one such gap -- which plays as a skip, one to nine seconds of audible +advertisement, then another skip. `merge` only folds breaks that overlap or touch. + +Merging across a tolerance both cleans that up and moves agreement the right way, because the +bridged gap was advertising too: + +| merge tolerance | median found/inserted | within 75-125% | total breaks | +|---|---|---|---| +| 0s (current) | 69% | 32% | 1240 | +| 2s | 70% | 33% | 973 | +| 5s | 70% | 34% | 885 | +| 10s | 73% | 34% | 820 | +| 15s | 73% | 35% | 786 | + +### Sleepy History was not eating the programme + +Reported on 2026-10-06 as finding 117:42 of "advertising" in a show whose feed declares no +inserted ads at all. That reading was wrong: it was a show-level sum, and almost all of it sat +inside the two episodes the 35% guard **already refused** -- a 3h08m Rosa Parks compilation that +literally contains other episodes (53:41 matched) and Antarctica (22:30). + +The six episodes that do publish skip 0:34 to 4:33 each, under 10% of their runtime, and the +largest block in each is a genuine closing segment shared by every episode in the batch -- +`48:20-51:36 partners=22`, `46:19-49:19 partners=26`. That is the show's own outro, which is what +intro/outro detection was supposed to find in the first place. The rest is 4-second floor noise. + +Across the whole corpus only 4 of 279 published episodes skip more than 20% of their runtime, and +all but one are corroborated by the length gap to within a minute. The exception is The Trip +(3:54 of 14:51, no declared gap), which is the one show worth watching. + +Sleepy History also serves files consistently **shorter** than declared -- 50:59 declared against +49:23 served, about 1:36 short on every episode -- so `Accounting` reports a zero gap for it. A +feed can be wrong in that direction too, and when it is there is no external check available. |
