summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/superpowers/specs/2026-10-08-furniture-and-cues-design.md142
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.