product

Auto-Demo — screen-recording + multi-channel distribution (decision doc)

Status: proposal, no code/infra changed. Covers the two remaining auto-demo next-steps that need a decision before building — #5 true screen-recording video and #6 YouTube/TikTok/IG distribution (see the ranked list in AUTO_DEMO_HANDOFF.md). Both are grounded in the current code; each ends with a concrete recommendation + what you'd need to decide.

Refinements #2–#4 (registry auto-PICK, stale regen, earned auto-post) are already built + merged (#1199–#1201). This doc is about the last two.


#5 — True screen-recording video

The real situation (not what the landmine note implies)

The handoff says true recording "needs full Chromium + --headless=new + xvfb on Railway (nixpacks change)." Reading the actual infra, that's more pessimistic than reality:

  • The full chromium binary is already installed on prod. nixpacks.toml runs npx playwright install chromium chromium-headless-shellboth. The system libs it needs are already apt-installed (the aptPkgs list).
  • The reason recordVideo fails today is purely the launch mode: persona-browser/pool.ts launches headless: true, which resolves to chrome-headless-shell — the stripped binary that lacks the screencast path Playwright's video recorder uses. The full chromium (already on disk) does have it.

So the limitation is a code/launch-config choice, not a missing binary and not necessarily a nixpacks change.

Options

OptionWhat it isInfra changeRiskNotes
A — full-chromium capture contextAdd a second launch path that uses the full chromium binary in --headless=new (or headless:false) only for the demo-capture context; keep headless-shell for the cheap screenshot/PDF/poster paths. Enable Playwright recordVideo on that context.None (binary + libs already present)Med — new-headless video recording is generally reliable but unverified on this Railway image; needs a prod smoke test.Smallest change; reversible; falls back to screenshots on failure.
B — xvfb + full chromiumAdd xvfb to nixpacks.toml aptPkgs, launch full chromium headless:false under a virtual display.nixpacks (aptPkgs += xvfb, process wrapper)Higher — new build-image surface, another thing that can break the deployThe "classic" recipe. Only needed if A's new-headless video proves flaky.
C — do nothingKeep the Phase-2b real-UI screenshot frames (already built, config-gated on DEMO_CAPTURE_BASE_URL).NoneNoneScreenshots already show the real UI per step; the gap vs. true recording is motion (scroll/typing/transition fidelity), not "is it the real app."

Recommendation

  1. Do #1 first (validate the 2b screenshot capture on prod). It's built and costs nothing to turn on. If per-step real-UI screenshots read well enough as a product tour, #5 may not be worth building at all — motion is the only thing they lack.
  2. If motion fidelity is needed, try Option A (code-only, no nixpacks risk), gated behind a DEMO_VIDEO_RECORD_ENABLED flag, with the existing caption-card / screenshot path as the automatic fallback if a recording fails. Validate on a single demo on prod before making it the default.
  3. Fall back to Option B only if A's video is unreliable on the Railway image.

Decision needed: after #1, is screenshot fidelity enough (→ close #5), or do we want true motion (→ I build Option A behind a flag)?


#6 — YouTube / TikTok / Instagram distribution

What exists to build on

  • The marketing posting console (social-posting.ts
    • /dashboard/admin/social-posting, migrations 343/349) is a human-in-loop console: it picks candidate seasons that have a 9:16 vertical trailer + a caption draft and no social_post_log row for a platform yet, and tracks posts. Platforms: youtube_shorts, fb_reels, tiktok, instagram_reels.
  • YouTube upload is automated (youtube-upload.ts): OAuth + videos.insert. But it's Shorts-shaped — returns a shorts_url, folds #Shorts into the description, assumes a vertical clip.
  • Bluesky is already done (#4 — earned auto-post + the manual button).

The honest blocker: aspect ratio, not plumbing

Demo videos render 16:9 landscape (1280×720VIDEO_W/VIDEO_H in demo-video-args.ts). The console's four platforms are all 9:16 vertical (Shorts/Reels/TikTok). So:

  • A demo MP4 fits YouTube as a regular (landscape) video natively — but not as a Short, and not TikTok/IG Reels/FB Reels, without a vertical re-render.
  • Feeding demos into the console as-is would offer them to platforms whose format they don't match.

Plan (in dependency order)

  1. YouTube (landscape) — the natural first channel. Add a non-Shorts upload path (the demo is a normal video, not a Short) or a small uploadDemoToYouTube that reuses the OAuth/videos.insert half of youtube-upload.ts without the #Shorts framing. This is the one channel demos fit today. ~1 PR.
  2. Vertical demo render — the gate for everything else. To reach Shorts/TikTok/IG, render a 9:16 variant (a VIDEO_W/H swap + caption reflow in the pure demo-video-args.ts; store video_url_vertical). Until this exists, the other three platforms are format-blocked regardless of plumbing. ~1 PR (pure-function change + a column).
  3. Console integration. Generalize the candidate pool + social_post_log to accept a demo subject (today it's keyed on season_id — needs a nullable demo_slug or a polymorphic subject). Then approved demos surface in the existing human-in-loop console alongside seasons. ~1 PR after (1)+(2).

Deliberately NOT auto-posting these. Unlike Bluesky (native video upload, low-stakes, already gated), YouTube/TikTok/IG posting should stay human-in-loop through the console — same discipline the season pipeline uses. Auto-post is a Bluesky-only trust tier for now.

Recommendation

Start with step 1 (YouTube landscape) — it's the only channel demos fit without a re-render, and the upload half is already written. Hold steps 2–3 until you actually want vertical Shorts/TikTok/IG demos, since that's a real format-and-schema investment, not just wiring.

Decision needed: (a) do you want YouTube-landscape demo upload now? (b) is a 9:16 vertical demo render worth building for Shorts/TikTok/IG, or is that not how you'd distribute a product tour (vs. a story trailer)?


Summary of decisions to make

  1. #5: validate 2b screenshots on prod (#1) → then decide screenshot-enough vs. build Option A (flagged full-chromium recording).
  2. #6a: YouTube-landscape demo upload — build now? (reuses existing OAuth uploader.)
  3. #6b: vertical (9:16) demo render for Shorts/TikTok/IG — worth it for a product tour, or skip?

None of these are blocking; the system is complete + spend-safe as shipped. This doc exists so the next build starts from a decision, not a guess.

AUTO DEMO DISTRIBUTION AND CAPTURE — Docs | HiveJournal