vc=70: audit-fix sprint round 3 (wrapper)

Round-3 audit (on vc=69) caught three real HIGHs plus three worth-fixing
MEDs. All in the same family: 'isAllowedYtUrl gate missing at consumer
side.'

HIGH-1 — ChannelScreen ignored the round-2 loadedUrl gate
  Round 2 added loadedUrl to ChannelUiState but ChannelScreen never
  read it. Channel A → back → Channel B showed A's data for one frame
  before vm.load(B) cleared it. Same shape as the VideoDetailScreen
  fix; matching gate added.

HIGH-2 — PlaybackService.tryAutoplay missing allowlist
  Both the SameChannel path (channelInfo(uploaderUrl)) and the
  candidate-resolve path (streamInfo(candidateUrl)) hit strawcore
  with extractor-derived URLs. Gate added on both call sites, plus
  the picker's intermediate uploaderUrl check.

HIGH-3 — VideoActionsSheet.enqueue missing allowlist
  Long-press on a poisoned related-card / channel video → 'Add to
  queue' invoked uniffi.strawcore.streamInfo on the raw target.url.
  Bail with Toast before launching the resolve coroutine.

MED-1 — FeedRefreshWorker doesn't retry on RequiresLogin
  reCAPTCHA challenges clear minutes-to-hours later. Treating them
  as permanent ate a full refresh cycle. Catch
  StrawcoreException.RequiresLogin → Result.retry().

MED-3 — VideoDetail.uploaderUrl persisted raw extractor value
  Round-2 added safeFresh for the avatar but the uploaderUrl saved
  to VideoDetail.detail was still info.uploaderUrl. NowPlaying →
  PlaybackService picked up the raw value. Validate once and persist
  the SAFE value so the whole downstream chain inherits it.

MED-4 — enrich-job filter rebuilt Set per iteration
  .filter { it.url in channelsSnapshot.map { c -> c.url }.toSet() }
  was O(N²). Hoist via mapTo(HashSet()) once.

Bonus sweep — gated two more uniffi.strawcore.* sites the round-3
agent's category prediction caught:
  * SubscriptionFeedViewModel.enrichVisibleItems → enrichFeedItem
    now skips items failing isAllowedYtUrl.
  * PlaybackService autoplay candidate-resolve already covered
    under HIGH-2 above.
This commit is contained in:
Kayos 2026-05-26 21:55:29 -07:00
parent 23fb6f52b0
commit d73a4b53aa
7 changed files with 69 additions and 7 deletions

View file

@ -55,6 +55,6 @@ const val NEWPIPE_APPLICATION_ID_NEW = "net.newpipe.app"
// vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via
// strawcore-core (Sulkta-Coop/strawcore) via the UniFFI wrapper; no
// NewPipeExtractor in the runtime path.
const val STRAW_VERSION_CODE = 69
const val STRAW_VERSION_NAME = "0.1.0-CC"
const val STRAW_VERSION_CODE = 70
const val STRAW_VERSION_NAME = "0.1.0-CD"
const val STRAW_APPLICATION_ID = "com.sulkta.straw"