spoolcast mobile export — Reels/TikTok/Shorts (A.1)
Vertical 1080×1920 exports of spoolcast widescreen videos for mobile-first platforms — scene regens at native 4:5, burned captions + watermarks on letterbox bars, per-part MP4s / SRTs / thumbnails.
added a mobile export path (A.1) to the spoolcast pipeline, separate from the widescreen render. takes a shipped widescreen video and turns it into a 1080×1920 vertical for reels/tiktok/shorts — bottom letterbox bar carries captions + watermarks (artlu.ai bottom-left in jetbrains mono, made by spoolcast bottom-right in comic neue bold), top bar carries the part badge when split. content area is 4:5 centered so scenes don't get cropped. most chunks are either the existing widescreen scene cropped to 4:5, the chunk's meme image rendered directly, or the parent chunk's mobile png with overlays composited on top. bumpers render live via ffmpeg drawtext with a canvas-agnostic fontsize formula (temp path until remotion-native bumpers ship). captions go through libass with montserrat black, top-anchored for 1-3 line cues and bottom-anchored for the rare 4+ line case. for a 2-part split this session shipped: 2 mp4s at 1080×1920, 2 srts, 2 thumbnails.
one real friction: the qwen vision audit on WIDESCREEN pngs couldn't catch text clipping even after four prompt revisions — strong "centered = safe" bias that no amount of prompt tightening fixed. the pivot was changing the input, not the prompt: crop first, audit the cropped png directly. worked on the first try. separately found a manifest race condition where two concurrent batch_scenes.py runs orphaned 4 chunks' manifest entries (non-atomic read-modify-save). fixed with fcntl.flock around the manifest write. ffmpeg also has no svg decoder so overlay svgs rasterize via rsvg-convert from librsvg before compositing.
technical wins — replay_mobile.py does byte-faithful regens at a new aspect by reading the original prompt + image_input from the scenes manifest (not re-deriving from the current shot-list, which drifts from backfill scripts). one run produced 11 of 13 regens correctly; 2 failed on manifest orphans and that was the thread that uncovered the race condition. guidelines landed in PIPELINE.md (end-to-end flow decision tree covering stage 0 through shipping through A.1), SHIPPING.md part 4 (mobile layout conventions, separation principle, per-part srt/thumbnail specs), VISUALS.md (manifest race failure mode), rules.md (prompt-engineering stall signal meta-rule), and ROADMAP.md items 3 and 5. also separated A vs A.1 explicitly across every rule file so future work doesn't shim widescreen logic into mobile paths.