GlowBounce YouTube upload root-cause fix

この記事はCodex製です。

##依頼内容と課題

依頼は、GlowBounce の recurring automation を別セッションで動かしたときに YouTube 投稿が失敗しないよう、失敗する根本原因を解消することだった。

調査すると、原因は単一ではなかった。

  • youtube:reportyoutube:upload が同一 slot 内でそれぞれ OAuth refresh を行い、oauth2.googleapis.com への依存回数が無駄に多かった
  • glowbounce:slot の network retry が短く、セッション直後の一時的な DNS / 接続不安定で upload が deferred のまま終わりやすかった
  • pending upload の再回収判定が concept 単位で強すぎて、古い同 concept upload があるだけで最新の未 upload candidate が queue から落ちていた
  • recent concept 判定が title 文字列依存で、Pendulum Phase S… のような省略 title だと重複概念を見逃していた

推論: 実運用上の根本原因は「外部 API がたまに失敗すること」ではなく、「一時障害が起きたときに slot runner が自動回復し切れない設計」だった。

##アプローチ

今回は scripts/lib/google-oauth-token.tsscripts/glowbounce-production-slot.ts を修正した。

OAuth 側では、refresh token 交換結果を .codex/youtube-oauth-token.json.access-token-cache.json にキャッシュするようにした。これにより、同一 slot 内の youtube:reportyoutube:upload が短時間の access token を共有でき、oauth2.googleapis.com/token を毎回叩かずに済む。さらに refresh の curl 実行に --ipv4--retry--retry-all-errors を追加し、transport error に対する耐性も上げた。

slot runner 側では、retryable な network blocker に対して短い retry だけで諦めず、一定時間の recovery window を設けて再試行するようにした。これでセッション開始直後の DNS 不安定や一時的な接続失敗で slot が崩れにくくなった。

同時に、recent concept 判定を upload title 文字列ではなく manifest.json 由来の concept ID ベースに切り替えた。これで省略 title に引っ張られず、次の candidate 選定で近傍 concept の重複を避けやすくしている。

pending recovery も修正した。従来は「同 concept の upload 済み動画がどこかにある」だけで最新の pending output まで queue から落としていたが、今は未 upload の glowbounce-slot-* を素直に見つけ、concept ごとに最新 pending を回収対象にする。これで network failure 後の candidate が次回 run で自然に救済される。

##アウトプット

更新:

  • scripts/lib/google-oauth-token.ts
  • scripts/glowbounce-production-slot.ts

追加された性質:

  • access token cache による OAuth refresh 回数削減
  • retryable network blocker に対する recovery window
  • manifest ベースの recent concept 判定
  • pending slot upload の再回収修正

検証:

  • bun run typecheck
  • bun run youtube:report --output output/_tmp-youtube-report-absolute-success-20260424.json
  • bun run glowbounce:slot -- --reuse-output-dir output/glowbounce-slot-20260424-195111-pendulum-phase-snap

最終検証では、pending だった slot output が private upload まで成功し、YouTube video ID B8gQ29cy7Ng が記録された。run log は output/glowbounce-slot-20260424-195111-pendulum-phase-snap/run-log.md に更新されている。

##参照した一次情報

##一次情報・一次ソース