Pairs with strawcore's new extractor instrumentation to make "Send logs to Kayos"
actually diagnosable. Today's bot-wall outage produced a log dump that was 90%
framework noise, one mangled strawcore line, and zero failure signal.
- LogDump: split the scrubber into a FULL profile (share-sheet export + on-screen
error strings — unchanged, still over-redacts) and a lighter DOGFOOD profile
(the logs.sulkta.com ingest path, our own infra) that KEEPS bare YouTube ids
(video/channel/playlist/youtu.be — the triage signal) while still scrubbing
every real credential: signed googlevideo URLs, bearer/cookie/token headers,
sig/pot/n/cpn params, URL queries, emails, high-entropy tokens (visitorData),
and IPs. LogShipper uses the dogfood profile.
- Fixed the IPv6-compressed regex that mangled Rust module paths
(`strawcore::stream` -> `strawcor<ip>stream`) and, as a bonus, a latent
false-negative where `::1` was never scrubbed.
- Always-log extraction + playback failures (strawLogI) so a user-visible failure
always lands in the ring.
- Wrapper (rust/strawcore): one catch-all WARN in run_extract that traces EVERY
extraction failure system-wide, and raise android_logger Info->Debug so the
extractor's DEBUG tier is live in the dogfood build.
- Added a JVM unit test for the scrubber (not yet wired into CI — the repo has no
test source set; follow-up).
- Thumbnails + channel icons stay cached: pin an explicit 256MB Coil disk
cache + sized memory cache via SingletonImageLoader.Factory. Coil's
default disk cap is 2% of the device's free space, so on a storage-tight
phone the subs feed (most image-heavy screen) thrashed it and
re-downloaded thumbnails on every visit.
- SponsorBlock + Return-YouTube-Dislike clients moved Kotlin -> Rust
(strawcore net.rs: fetchSponsorSegments / fetchRydVotes). SponsorBlock
keeps its privacy-preserving SHA-256 hash-prefix lookup. Kotlin is now a
thin shim mapping the FFI records onto the SbSegment/RydVotes domain
types; behavior identical. Migration #2 of "all backend -> Rust".
- Fix crash: extract_channel_id sliced the channel URL by a length derived
from a lowercased copy of itself; to_lowercase() can change byte length
on non-ASCII, so a non-ASCII URL tail could panic across the FFI and
abort the app on a feed refresh. Now matches the prefix case-insensitively
against the original with length + char-boundary guards.
- Fix autoplay hijack: advancing to the next video resolves over ~500ms; if
you manually start a different video meanwhile, autoplay would replace
your choice with the stale next-up. Added a staleness fence.
Verified: cargo check/test/clippy on the wrapper, full Android
compileDebugKotlin green, adversarial FFI pre-push audit passed.
Wire the new strawcore continuation fetchers through UniFFI and add
load-more-on-scroll to the Channel and Search screens — previously both
loaded only page 1 and stopped.
FFI (rust/strawcore): search() now returns Page{items, continuation};
channelInfo carries videos_continuation; new searchContinuation() and
channelVideosContinuation() suspend funs map the core ContinuationPage.
Channel + Search ViewModels: loadMore() fetches the next page, dedups by
url, advances the token, and stops when the token runs out or a page
yields zero net-new items (guards a looping continuation). Result-set
swaps (channel switch / new submit / cache preview) cancel the in-flight
page, and a token fence inside the state update prevents a stale page
being spliced into a replaced list. Screens add a near-end LazyColumn
trigger (rememberLazyListState + derivedStateOf) and a footer spinner.