Upload the downloaded Vimeo masters (TASK-246) to YouTube via the upload pipeline (TASK-249), then update _data platform records so YouTube becomes primary. Newly-on-YouTube videos then re-enter transcription backfill (TASK-250) and caption/metadata (TASK-252/TASK-248). Outward-facing: private/unlisted first, public only on approval.
videos/masters/ (27, integrity-passed)._data/vimeo_migration_manifest.yml drives ordering + carries caption_readiness (19 caption-ready / 8 needs-transcription).youtube_id, migration_state: unlisted).--publish <asset_id> action gated on migration_state == unlisted). No batch flip-all-public. Only on approval does the pipeline set privacy public and migration_state: public._data/video_assets.yml (structure/data only)platform: youtube entry to platforms[] (asset_id, url: https://www.youtube.com/watch?v=<id>, embed_url: https://www.youtube.com/embed/<id>, carry duration/thumbnail as available) and set primary_platform: youtube._includes/video-stage.html, schema-factory.html, video-asset-player.html) auto-repoint the embed the moment the youtube entry exists._data/transcripts/<transcript_id>.yml with structured turns → they need only a caption track (TASK-252): push the existing transcript to the new YouTube id as a caption/subtitle track. Do not re-transcribe.bin/batch_ztranscribe.rb’s existing selection logic (transcript_id empty AND a youtube platform id present) — post-upload those exact 8 become eligible automatically, so no custom re-enqueue of the 19. Enqueue via zdots-ctx enqueue transcription '{"url":"https://www.youtube.com/watch?v=<id>","video_asset_id":"<id>"}' (fingerprint-idempotent; worker drains)._data/video_assets.yml gains youtube ids + primary_platform: youtube (vimeo entry retained until 256).No content rewriting. No public publish without explicit approval. Planning only — no uploads/API calls performed now.