The Data API captions.download endpoint is owner-only: every subscription video the user does not own returned HTTP 403, producing 0 summaries and a ~150-line error spew in the first live Stage-0 run. Captions-first (ADR-007) is sound; only the acquisition mechanism was wrong. FetchTranscript now resolves caption tracks from the InnerTube player response (ANDROID client, unauthenticated) and GETs the chosen track's timedtext baseUrl with a plain http.Client — no OAuth token, which can break the endpoint. The srv3 XML, json3, and legacy <transcript> formats all parse; non-asr tracks in a preferred language win. Watch-page ytInitialPlayerResponse scrape is the fallback when InnerTube returns no tracks. Degrade, don't error (explicit quick-fix): no captionTracks, empty baseUrl, a non-200 fetch, or an unparseable body yield Source=none, not an error. Only genuine transport faults error — this kills the spew. OAuth stays on ListSubscriptions/NewVideos (Data API); only transcript fetch goes unauthed. Validated live from koala: the ANDROID client returned working baseUrls and real transcript text for public videos the run identity does not own. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>