summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md45
1 files changed, 36 insertions, 9 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 807a35c..f0b6412 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -283,15 +283,42 @@ by default and correct; it is simply waiting for a publisher who marks breaks.
needed no changes: `effectiveIntroMs`, `effectiveOutroMs` and `PlayheadPolicy` already read
them. No migration either.
-- **The confirmation threshold does not survive simultaneous mirroring, and currently detects
- ads rather than intros.** Proved, not suspected: the segment confirmed on 8 of 8 Radiolab
- episodes was searched for in an ad-free copy of the same episode fetched hours earlier and
- scored **r = 0.0621**. It is in the ad break, not the programme. Mirroring 8 episodes within
- one minute from the same ad server makes them maximally dependent, so whatever campaign is
- running is in all of them, identical -- and `SelfCheck` cannot catch it, because the segments
- genuinely *are* the same audio. Do not describe the current offsets as intro detection. The
- fix is to record fetch times and require the agreeing episodes to span more than one fetch
- occasion; full reasoning in `docs/detection-findings.md`.
+- **The server detects the advertising, not the intro, and that is now deliberate.** The
+ property that broke intro detection is what makes ad detection work: eight episodes mirrored
+ within one minute share whatever ad campaign is running, identically. `detect.BestLags` finds
+ where two recordings align with one cross-correlation over every lag -- not one correlation
+ per window position, which is why whole episodes are now scannable at all -- and
+ `detect.MatchedRuns` walks the extent of the agreement directly.
+
+ **It is validated against a number the detector does not produce.** The feed declares the
+ ad-free length, the file is longer, and the difference is the advertising. On Radiolab's eight
+ mirrored episodes the scan accounted for **53:29 of the 59:39** implied, every episode between
+ 71% and 105%. First time in this project that detection has been checked against external
+ ground truth and agreed.
+
+ Breaks are published as ranges into `episode_midrolls`, which `MidrollSkip` and
+ `PlayheadPolicy` already read -- no playback changes, no migration. Two guards publish nothing
+ rather than something wrong: an episode whose matches cover over 35% of it, and any single
+ match over four minutes, are refused (a re-aired episode or a two-parter would otherwise be
+ eaten). Both record the refusal, because "found nothing" and "refused what it found" are
+ different states and conflating them is the readout mistake again.
+
+- **Intro and outro offsets are computed, logged, and deliberately not published.** They assume
+ the agreeing episodes were fetched independently, and mirroring eight at once means they were
+ not. Proved, not suspected: the segment confirmed on 8 of 8 Radiolab episodes was searched for
+ in an ad-free copy of the same episode fetched hours earlier and scored **r = 0.0621** -- it
+ was in the ad break. `SelfCheck` cannot catch that, because the segments genuinely *are* the
+ same audio. They become trustworthy once the agreeing episodes are required to span more than
+ one fetch occasion; until then do not publish them.
+
+- **The subscription list is the one thing the server cannot rediscover, and it was being lost.**
+ Three bugs, all found by reading the journal after a restart rather than by a test: the list
+ was persisted only when a whole poll cycle finished (hours, for 61 feeds); a cycle re-applied
+ its stale snapshot at the end, which would undo a push that arrived during it and delete the
+ audio of every show the snapshot omitted; and detection ignored cancellation, so systemd's
+ 90-second stop SIGKILLed the process before the save-on-exit could run. Now: saved on arrival,
+ saved after every feed, reconciled against the live list, cancellation honoured, and
+ `TimeoutStopSec=600`.
- **`android-ui tap` can land on the soft keyboard.** The dump reports the layout's own
coordinates, which the IME does not move, so an element listed at y=1643 can be underneath the