summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-10-17 07:55:17 +0000
committerClaude <noreply@anthropic.com>2026-10-17 07:55:17 +0000
commitd3538646200832583b6662dbdd4c292a1cfe8141 (patch)
tree0ba2a6eaa063d62d22250b1cd63e06e1e94c88d4 /CLAUDE.md
parent999759f8bb495e8dbce4655a0ec13fe0a3062510 (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.md27
1 files changed, 25 insertions, 2 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index d838416..36d8eaa 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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