fix(stream): TEST-tab chat — resolve liveChatId from snippet, poll until the broadcast is live

The open creator report ('I still cannot post a chat message in the TEST tab',
feedback 'Chat polling couldn't start — Mock Chat Input is disabled') was a single
cause: the liveChatId never resolved. Two YouTube API facts:
1. The id lives in snippet.liveChatId — contentDetails has no such property
   (TASK 44 read part=contentDetails: could never resolve).
   https://developers.google.com/youtube/v3/live/docs/liveBroadcasts
2. It only exists once the broadcast is LIVE — the official sample lists
   broadcastStatus=active, and our fetch ran before the frame pump pushed RTMP
   (enableAutoStart flips ready→live). A ready-state list legitimately returns
   no id.
   https://github.com/youtube/api-samples/blob/master/java/src/main/java/com/google/api/services/samples/youtube/cmdline/live/GetLiveChatId.java

Fix: GetBroadcastLiveChatIdAsync reads part=snippet and polls with a bounded
retry (10x/2s); PrepareAndStartLiveAsync starts the frame pump FIRST, then
resolves the id. Chat stays non-fatal. Docs ai.md/TASKS.md/HANDOFF.md +
MyMistakes recipe updated same commit. TASK 44.

Good Dog: ONE integration test (GetBroadcastLiveChatIdAsync_Polls_Snippet_...
) drives a broadcast that gains its id mid-retry and asserts every request used
part=snippet. Gate: clean build 0 warnings, vstest 318/318.
This commit is contained in:
2026-09-25 08:06:02 -07:00
parent d4aa588da0
commit 94f015044a
8 changed files with 219 additions and 83 deletions
+12
View File
@@ -28,6 +28,18 @@ calling it; a leaked 403→parse chain means your "whole request failed" symptom
paper over a second crash that only appears once the 403 is fixed (test the full
happy path, not just the error path).
### liveChatId LIVES IN SNIPPET AND ONLY EXISTS ONCE THE BROADCAST IS LIVE (RECIPE)
YouTube Data API v3 `liveBroadcasts`. `liveChatId` is in **`snippet.liveChatId`** —
`contentDetails` has NO such property. AND it is only populated once the broadcast is
**live** (the official `GetLiveChatId.java` sample lists `broadcastStatus=active`);
a fetch right after insert (lifecycleStatus `ready`) returns nothing. (2026-09-25: this
cost a whole investigation — the TEST-tab "Chat polling couldn't start — Mock Chat Input
is disabled" report — because the code read `part=contentDetails` + ran before the frame
pump pushed RTMP.) Fix = read part=snippet + bounded retry AFTER the encoder starts
(`GetBroadcastLiveChatIdAsync(broadcastId, maxAttempts=10, delayMs=2000)`). Debug lens:
missing liveChatId ≈ "broadcast not live yet", NOT an auth failure.
### CHANNELS.LIST auditDetails PART 403s THE WHOLE REQUEST WITHOUT A PARTNER SCOPE (RECIPE)
YouTube Data API v3 `channels.list` rejects the ENTIRE request with