diff options
| -rw-r--r-- | docs/superpowers/specs/2026-10-08-furniture-and-cues-design.md | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-10-08-furniture-and-cues-design.md b/docs/superpowers/specs/2026-10-08-furniture-and-cues-design.md new file mode 100644 index 0000000..2e91362 --- /dev/null +++ b/docs/superpowers/specs/2026-10-08-furniture-and-cues-design.md @@ -0,0 +1,142 @@ +# Telling a show's own audio from the advertising inserted into it + +2026-10-08. Design for review; nothing here is built. + +## What is wrong now + +Three defects, all in the ad scan, all visible in the first full corpus (42 shows, 322 mirrored +episodes). + +**D1 -- it finds about two thirds of the advertising.** Median agreement with the declared-versus- +served length gap is 67%, and 47 of 108 checkable episodes come in under half. The scan can only +see advertising that two simultaneously-mirrored episodes *share*; an advertisement served into +one episode and not another is invisible to it. Search Engine is the extreme: 8:23 of insertion +on one episode, of which we skip 0:49. + +**D2 -- it reports a show's own audio as advertising.** 138 of 322 mirrored episodes have a served +length equal to their declared length, which means no advertising was inserted into them at all. +The scan publishes "ad breaks" on 111 of those, 74 minutes in total. What it has actually found is +the show's opening theme, its break cue and its closing credits. Worth skipping -- that is what +intelligent skipping was asked for -- but it is not advertising, and the app says "Ads inserted". + +**D3 -- intro and outro offsets are computed and withheld.** They are found by eight episodes +agreeing, and eight episodes mirrored inside one minute are not independent evidence: that is how +an advertisement came to be confirmed as an intro on 8 of 8 Radiolab episodes. Nothing has changed +that, so the offsets stay unpublished. + +## The observation that connects them + +A show's own recurring audio is **permanent**. The opening theme is in this week's batch and will +be in next month's. Inserted advertising is **transient**: three consecutive fetches of one +enclosure came back byte-identical to each other and 82KB different from the copy mirrored days +earlier, so the ad load is fixed within a session and rotates over days. + +So persistence across separate fetch occasions is both the thing that distinguishes furniture from +advertising *and* the independence test D3 has been waiting for. + +Peter's observation about theme music is the same structure seen from the listener's side. Tangle, +Jon Stewart and Search Engine each play a short cue at every break, and the scan already finds it +-- it is the short, high-partner-count block that the partner-count filter would have discarded. +Search Engine's is 8.0s at `13:08`, `35:28` and `44:51`, found in 5 to 13 other episodes; +templating it and scanning episodes it was not taken from locates it at r = 0.96, 0.92, 0.85. + +**It marks a break's entry, not its extent.** Scanning down to r = 0.6 returns one isolated hit +per slot in ad-laden and ad-free copies alike. There is no closing cue, so a cue says a break +starts here and nothing about how long it runs -- and the length is what a skip needs. + +## Three approaches + +### 1. Read it off what is already computed (recommended) + +No stored audio, no new state. + +- **D2, exactly and for free.** Served length equal to declared means nothing was inserted, + therefore everything found is furniture. That classification is available on every mirrored + episode -- all 322 have a usable declared duration -- and it settles all 111 mislabelled ones. +- **Cues, from their signature within one batch.** A cue is a short block (<= ~15s) of near- + identical duration occurring several times per episode across most of the batch. Search Engine: + 8.0s, three or four per episode. Jon Stewart: ~5s, four per episode. Both already in the data. +- **D1, partially.** Treat a cue as a local prior: in the window after a cue an advertisement is + certainly present, so accept weaker cross-episode evidence there than mid-programme. This + attacks the under-reporting where we know to look, rather than lowering the threshold globally + -- which the disproven filter experiment shows is indiscriminate. +- **D3: not addressed.** + +### 2. A per-show furniture library + +Everything in approach 1, plus a stored set of the show's own clips. + +Per show, up to 8 clips, each holding the audio at the discovery rate (250Hz -- 8s is 2000 +samples, 16KB), the number of separate fetch occasions it has been seen on, where it sits +(opening / mid-episode / closing), and when it was last seen. Clips live as files beside the +mirrored audio; `state.json` keeps the metadata and a reference. 42 shows at 8 clips is about +5.4MB. + +Each pass scans every episode for every known clip -- one cross-correlation per clip per episode, +2000 samples over 750,000, which benchmarks around 0.33s, so roughly 20-40s per show against the +6-10 minutes a pass already costs. Candidates come from the ad scan's short high-partner blocks, +and a candidate is **promoted only when it reappears on a later pass whose batch differs** -- a +genuinely separate fetch occasion. + +- **D3 addressed.** A clip confirmed on two separate occasions and consistently at the opening + *is* the intro, on independent evidence. The withheld offsets become publishable. +- **D2 more precisely.** For the 154 episodes that do carry advertising, this separates furniture + from ads *inside* them, which approach 1 cannot. +- Cost: new persistent state, a promotion rule, and the eviction policy. + +### 3. Metadata-only persistence + +Store each candidate's shape across cycles -- duration, position, partner count -- but not its +audio. Cheap, and useless: it can confirm that a block of some shape recurs, but cannot locate it +in a new episode, which is the entire purpose. Rejected. + +## Recommendation + +**Approach 1 now. Approach 2 only if the intro and outro offsets are wanted back.** + +Approach 1 fixes the one defect that is provably wrong today (D2), attacks the largest one (D1), +needs no storage and no new state, and can be validated immediately. Approach 2 is the only route +to D3, but its value arrives a fetch occasion later and it carries the one genuinely awkward risk +below. + +## How it gets judged + +The declared-versus-served length gap stays the judge, because the detector does not produce it. + +- **D2 is binary.** The 138 zero-gap episodes must report zero *advertising* while still reporting + furniture. Any advertising reported on them is a failure. +- **D1 moves or it does not.** Median found-versus-inserted must rise from 67%, while the + over-150% group -- 9 of 108 episodes today -- does not grow. +- **A new guard: the gap as a budget.** Where a feed declares a length, never publish more + skipping than the gap implies. `MaxSkipFraction` (0.35) and `MaxBreakMs` (240s on the matches) + stay as they are. + +## Risks + +**A long campaign could be promoted as furniture** (approach 2 only). A sponsor running for weeks +survives two fetch occasions and looks permanent. Bounded by the eviction cap and visible in the +gap accounting, but real, and the honest answer is that persistence is a good discriminator rather +than a perfect one. + +**The cue prior could over-extend a break.** Bounded by the gap budget and the fraction guard. + +**Cue identification could misfire on musically repetitive shows.** Sleepy History reuses long +ambient beds. Mitigated by requiring a cue to appear at *several distinct positions within a +single episode* -- which a break cue does and an opening theme does not -- at a consistent +duration. + +## Question for Peter + +Furniture and advertising both get skipped by default, and the readout names which is which -- +"Show intro", "Break cue", "Credits", "Ads inserted" -- rather than calling all of it advertising? +That is the proposed default on the grounds that skipping the intro is what was originally asked +for. The alternative is to skip only inserted advertising and merely mark the furniture. + +## Phases + +1. Zero-gap classification. Stops reporting advertising where none was inserted. Safe: changes + what the readout *says*, not what gets skipped. +2. Cue identification within a batch, reported but not acted on, so the signature can be checked + against real shows before it moves a playhead. +3. The cue prior, validated against the length gap. +4. Approach 2's library, if D3 is wanted. |
