diff options
| author | Claude <noreply@anthropic.com> | 2026-10-17 07:55:17 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-10-17 07:55:17 +0000 |
| commit | d3538646200832583b6662dbdd4c292a1cfe8141 (patch) | |
| tree | 0ba2a6eaa063d62d22250b1cd63e06e1e94c88d4 /CLAUDE.md | |
| parent | 999759f8bb495e8dbce4655a0ec13fe0a3062510 (diff) | |
Record that the silent publisher fallback is gone
CLAUDE.md still described it as deliberate design with its original
rationale, which would have had a future session reintroduce the exact
behaviour Peter asked to remove. Also records the three cases that must
keep downloading directly, why a rejected token is permanent rather than
transient, and what audioFromServer is for.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 27 |
1 files changed, 25 insertions, 2 deletions
@@ -276,8 +276,31 @@ by default and correct; it is simply waiting for a publisher who marks breaks. **Serving the audio is load-bearing, not a convenience.** Dynamic ad insertion is on every episode: Radiolab's Grass Apes declares 22:05 and the server was served 28:18. An offset measured on one copy is minutes wrong for another, so the phone has to play the bytes the - detector examined. `EpisodeDownloader` prefers the server and falls back to the publisher -- - the fallback matters, because skips improve playback rather than being a precondition for it. + detector examined. + + **The silent publisher fallback is gone, by Peter's decision (2026-10-17).** It used to be + deliberate -- skips improve playback rather than being a precondition for it -- and that + reasoning was retired once the server's copy became load-bearing for accuracy. With a server + configured, an episode it cannot supply yet enters `WAITING_FOR_SERVER` and is retried on + every refresh. Taking the publisher's differently-ad-inserted copy is an explicit action on + the episode screen that sets `audioFromServer = false`. Do not reintroduce an automatic + fallback for a transient failure. + + **Three cases still download directly, and must keep doing so:** YouTube and Facebook (they + never touch the server), an unresolvable feed, and -- critically -- **no server configured at + all**. Without that last one the app stops working for anyone who has not set a server up. + + **A rejected token is permanent, not transient.** 401 and 403 download the publisher's copy + at once and raise a notice in Settings; 404, 5xx, a connection failure, an unparseable body + and the server's own `pending` all still wait. The transport reports Body / Rejected / + NoAnswer and holds no decisions. Before this split, a mistyped token meant *nothing + downloaded, ever*, silently -- the earlier "every failure means the same thing to the caller" + rule stopped being true the moment the consequence changed from "no skips" to "wait forever". + + **`audioFromServer` records which copy actually landed**, which is what makes refreshing + skips safe: `SkipRefresher` re-queries only episodes whose bytes the server itself measured, + six at a time. Server timestamps must never reach publisher audio -- that would seek into the + middle of the programme, which is worse than having no skips. **The offsets go into the same columns the on-device detector wrote**, which is why playback needed no changes: `effectiveIntroMs`, `effectiveOutroMs` and `PlayheadPolicy` already read |
