tests/fixtures/feed_lookup/past_stream.json still carried trackingParams
and clickTrackingParams (opaque YouTube tokens, 27 and 34 bytes once
base64-decoded; neither holds the capturing address as text or as four
bytes, checked with a planted control). They are removed; nothing reads
them. The three feed fixtures now each come out unchanged from the
README's scrub filter.
the_fixtures_carry_no_request_bound_data listed the twelve Live tab
fixtures by name and never looked at the three feed fixtures, and its
markers missed clickTrackingParams (the match was case-sensitive),
URL-encoded "ip%3D" and a bare IPv4 address. It now reads every JSON
file in both fixture directories from disk, checks that the walk found
five named files (so a moved directory cannot pass empty), and fails on
any "...TrackingParams" field, "ip%3D" or "ip%3d", and a dotted IPv4
address with every group at most 255. "20.772.51.34", a duration the
Indonesian fixture carries, is not taken for an address (772 > 255);
first_ipv4 has its own test. Run on the old past_stream.json, the guard
fails on trackingParams.
Correction to
|
||
|---|---|---|
| .. | ||
| kurzgesagt_live_request.json | ||
| lofigirl_live.json | ||
| lofigirl_live_de.json | ||
| lofigirl_live_fi.json | ||
| lofigirl_live_fr.json | ||
| lofigirl_live_id.json | ||
| nasa_home_tabs.json | ||
| nasa_live.json | ||
| nasa_live_da.json | ||
| nasa_live_page2.json | ||
| nasaspaceflight_live.json | ||
| README.md | ||
| skynews_live.json | ||
| skynews_live_de.json | ||
| skynews_live_page2.json | ||
| spacex_live.json | ||
Live tab fixtures
Captured on 2026-10-23 from public channels with the request strawcore sends:
POST https://www.youtube.com/youtubei/v1/browse, WEB client envelope
(build_desktop_envelope), utcOffsetMinutes 0, the channel's browseId
and the Live tab params EgdzdHJlYW1z8gYECgJ6AA==. Continuation pages were
fetched with {"continuation": <token>} against the same endpoint.
| File | Language | What it holds |
|---|---|---|
nasa_live.json |
en-GB | 2 scheduled, 2 live, 26 past, continuation |
nasa_live_page2.json |
en-GB | page 2 of the above: 30 past, continuation |
skynews_live_page2.json |
en-GB | page 2 of skynews_live.json: 30 past, two of them with a row naming collaborating channels above the views row, continuation |
skynews_live.json |
en-GB | 3 scheduled (one with no waiting count), 2 live, 25 past, continuation |
skynews_live_de.json |
de-DE | the same channel in German |
lofigirl_live.json |
en-GB | 23 live, 2 past with durations past 999 hours, no continuation |
lofigirl_live_de.json |
de-DE | the same channel in German |
lofigirl_live_fr.json |
fr-FR | the same channel in French |
lofigirl_live_fi.json |
fi | the same channel in Finnish: durations past 999 hours written 20\u00a0772.51.34 |
lofigirl_live_id.json |
id | the same channel in Indonesian: durations past 999 hours written 20.772.51.34 |
spacex_live.json |
en-GB | 30 past, nothing live or scheduled, continuation |
nasa_live_da.json |
da | nasa_live.json's channel in Danish, later the same day: 1 scheduled, 3 live, 26 past, durations written 28.10 and 1.42.26, continuation |
nasaspaceflight_live.json |
en-GB | 1 scheduled, 3 live, 26 past, some with a members-only or fundraiser badge row |
nasa_home_tabs.json |
en-GB | tab list of a Home tab response from a channel with a Live tab |
kurzgesagt_live_request.json |
en-GB | tab list of the answer to the Live tab params from a channel without a Live tab (its Home tab comes back selected) |
The da, fi and id files were requested with that bare language code
and gl GB.
Every response was trimmed with this jq filter before it was saved
($mode is page, continuation or tabs), then written with
jq -a -c, so non-ASCII text is kept as JSON escapes. It drops request-bound and
tracking data, item menus and hover actions, the sort and filter chips above
the grid, and the query string of every i.ytimg.com URL, and keeps every
other field of each item as captured. The chips and the badge
animationActivationEntityKey are dropped because gitleaks 8.21.2 (the
version CI runs) reports opaque tokens in them as generic API keys; neither
is read by the parser:
def scrub:
walk(
if type == "object" then
del(.trackingParams, .clickTrackingParams, .loggingDirectives, .loggingContext,
.watchEndpointSupportedOnesieConfig, .menuButton,
.thumbnailHoverOverlayToggleActionsViewModel, .themedPalette,
.serviceTrackingParams, .visitorData, .accessibilityContext,
.animationActivationEntityKey)
| if has("overlays") and (.overlays | type) == "array"
then .overlays |= map(select(. != {})) else . end
| if has("richGridRenderer") then .richGridRenderer |= del(.header) else . end
elif type == "string" and test("^https://i[0-9]?\\.ytimg\\.com/") then sub("\\?.*$"; "")
else . end);
if $mode == "page" then {contents} | scrub
elif $mode == "continuation" then {onResponseReceivedActions} | scrub
elif $mode == "tabs" then {contents: {twoColumnBrowseResultsRenderer: {tabs: [.contents.twoColumnBrowseResultsRenderer.tabs[] | if has("tabRenderer") then .tabRenderer |= del(.content) else . end]}}} | scrub
else error("mode") end
The ../feed_lookup/ files are the narrowed metadata lookup the
subscription feed already makes per item (stream_metadata: the ANDROID
reel/reel_item_watch call with
$fields=playerResponse.playabilityStatus,playerResponse.videoDetails),
captured the same day for a stream that was live, a past stream and a
scheduled stream. The query string of each i.ytimg.com URL was removed
when they were captured; past_stream.json was first committed with two
tracking fields (trackingParams, clickTrackingParams) that were
removed later. Each file now comes out unchanged when the scrub filter
above is run on it as the jq program (jq -a -c).
the_fixtures_carry_no_request_bound_data in tests/live_tab.rs reads
every JSON file in both directories and fails on googlevideo,
visitorData, trackingParams or any ...TrackingParams field, ip=
(plain or URL-encoded), a bare IPv4 address, or a thumbnail URL with a
query string.