Commit graph

4 commits

Author SHA1 Message Date
c8dfc8a34a Public-flip audit: scrub audit-ticket prefixes + LAN refs + tighten README
URLs → git.sulkta.com. Audit-ticket prefixes (SPEC §N, audit Track X, vc=N
audit-fix, FIX (audit ...), PORT DEVIATION) stripped from comments — technical
reasoning retained. Crafting-table LAN refs softened to 'Sulkta build host'.
README sheds marketing scaffolding + stale status tables.
2026-05-27 13:29:52 -07:00
56afa423fb Drop dead Method variants, Downloader default fns, parsing/stream_helper unused, suppress_unused leftovers, stale comments
Second pass through the cruft inventory. All deletes — no behavior change.

Method enum + downloader trait:
  * Method::Head / Put / Delete dropped (no caller). Match arms in
    request.rs::as_str() and default_impl.rs::execute() collapse to
    just Get / Post.
  * Request::head builder dropped.
  * Downloader trait's get / get_localized / head / post default
    methods dropped. Every caller went through execute() directly
    anyway; the convenience wrappers carried 4 dead arms each.

Parsing module:
  * bootstrap_visitor_data — pub fn, no caller.
  * discover_web_client_version + CACHED_WEB_CLIENT_VERSION +
    reset_web_client_version_cache — entire sw.js live-version
    discovery pipeline, never wired up by any caller. The cache was
    never populated, so web_client_version() always returned the
    hardcoded constant. Collapsed to just returning the constant.
  * Drops once_cell::Lazy, parking_lot::RwLock around the version
    cache (consent flag still uses RwLock), Regex import, serde_json::Value
    import, downloader/exceptions/Request/InnertubeClientRequestInfo
    imports — all only kept alive by the deleted code.

stream_helper:
  * get_web_embedded_player_response — pub fn, no caller.

js/player_manager + extractor:
  * player_manager::player_hash — pub fn, no caller. Was only kept
    alive by its own definition.
  * extractor::extract_player_hash — pub fn, only called by the now-
    dead player_hash. Test removed alongside.

Stale comments:
  * itag.rs:1 header claimed 53 entries; ITAG_TABLE has 57 and the
    test at line 179 already asserts it.
  * js/mod.rs:12-13 claimed the submodules were 'crate-private
    plumbing' but they're declared pub mod. Tightened the comment to
    explain the integration-test dependency that keeps them public.

Net delete: ~170 LOC of dead surface across 9 files.
2026-05-26 22:33:00 -07:00
a47e142ab7 Phase 4 (complete) — stream_extractor orchestrator
Wire the Android-primary fetch path + JSON-walking + URL post-processing
into a single stream_info(video_id) entry point. Mirrors NPE
YoutubeStreamExtractor.onFetchPage() per audit Track C §1.2.

src/youtube/stream_extractor.rs
  * stream_info(video_id) + stream_info_with(video_id, options)
  * fetch_android — reel endpoint (anonymous) OR /player (with po_token)
  * check_playability_status — maps to ContentUnavailable variants
    (AgeRestricted, GeoRestricted, Paid, Private, YoutubeMusicPremium,
    AccountTerminated, Other)
  * is_player_response_not_valid — decoy-video detection
  * populate_video_details + populate_microformat + populate_streams +
    populate_manifests + populate_captions
  * process_url — sig deobf path (signatureCipher → JS function call)
    + unconditional nsig deobf + cpn append + pot append
  * build_video_progressive / build_video_only / build_audio +
    push_*_dedup helpers (FIX: NPE bug — dedup by itag id, not by
    mediaFormat.id which collides 140/141)

Consolidated stream_helper's local ExtractionError into the crate-wide
exceptions::ExtractionError with a new DownloaderMissing variant.

Tests: 73 lib unit pass (+9 since Phase 3) + 7 new Phase 4 offline
integration tests = 80 lib green. Live YT end-to-end smoke deferred
to Straw integration; the code path is in place.
2026-05-24 17:08:04 -07:00
cd98673684 Phase 4 (partial) — stream value types + InnerTube /player helpers
Lands the data shapes + the HTTP layer for stream extraction. The
extractor orchestrator + DASH manifest creator are deferred to the
next session — the parsing logic is dense enough to want a focused
pass.

src/stream/
  * mod.rs       — StreamInfo + StreamInfoItem (full + 'card' shapes)
                   mirroring NPE StreamInfo.java + StreamInfoItem.java
  * delivery.rs  — DeliveryMethod (Progressive/Dash/Hls/Torrent)
  * audio.rs     — AudioStream (itag, format, url, bitrate, codec,
                   audio_track_id, content_length, etc.)
  * video.rs     — VideoStream (itag, format, url, resolution, fps,
                   bandwidth, codec, video_only flag)
  * subtitles.rs — SubtitlesStream (url, lang, auto_generated, mime)

src/youtube/stream_helper.rs
  * generate_content_playback_nonce() — 16-char LCG-shuffled cpn
  * get_web_metadata_player_response       (microformat + thumbnails only)
  * get_web_embedded_player_response       (embed-url + signatureTimestamp)
  * get_android_player_response            (full Android /player + poToken)
  * get_android_reel_player_response       (no-poToken fallback)
  * get_ios_player_response                (iOS — flagged with 917 KiB cap
                                            warning in the doc comment)

Per-helper headers + URL shapes match audit Track C §2.7 verbatim:
Android/iOS hit gapis endpoint with mobile UA; WEB family hits
www.youtube.com with the WEB headers.

Tests: 64 lib unit pass (up from 62 in Phase 3).

Next session: full stream_extractor.rs orchestrator + dash_manifest/
creator + Phase 4 done-when smoke (extract NCS Spektrem).
2026-05-24 17:01:03 -07:00