{
  "schemaVersion": 1,
  "slug": "frame-sequence-to-review-clip",
  "locale": "en",
  "evidenceClass": "executed-local-fixture-not-provider-generation",
  "providerModelTest": false,
  "productionTaskRun": false,
  "runCommand": "node run-recipe.mjs --out ./my-run",
  "environment": {
    "nodeVersion": "v24.18.0",
    "ffmpeg": {
      "version": "ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers",
      "binarySha256": "a90e3db6a3fd35f6074b013f948b1aa45b31c6375489d39e572bea3f18336584"
    }
  },
  "title": "Assemble an ordered PNG sequence into a review clip",
  "description": "Validate contiguous PNG names and hashes, reject missing or reordered inputs, then encode three original frames into a 1.5-second review MP4.",
  "goal": "Build a review clip from existing still frames with an explicit two-FPS schedule. This is forward sequence assembly, with no generated in-between frames or reverse video frame extraction.",
  "preparation": [
    "Prepare Node.js and FFmpeg, setting FFMPEG_BIN when needed. The inputs are three original 160×90 PNGs with red, green and blue fields plus a white edge marker.",
    "Read sequence.json: indices 1–3 are bound to frame-0001.png through frame-0003.png and their SHA-256 values, at a declared two FPS.",
    "Use a new output directory and require the exact input filename set. A visually plausible frame in the wrong sequence is still a manifest failure."
  ],
  "steps": [
    {
      "title": "01. Freeze the image sequence",
      "body": "Generate the three practice PNGs and an explicit ordered manifest. Each row contains an index, exact basename and SHA-256. Do not rely on filesystem iteration order, which is not the editorial order of shots."
    },
    {
      "title": "02. Reject gaps, extra names and wrong bytes",
      "body": "Before encoding, replay a swapped-row manifest, remove frame 2 temporarily, add frame 5 and supply a wrong hash. Each invalid case fails; finally blocks restore the original complete sequence before the actual encode."
    },
    {
      "title": "03. Encode using the declared input rate",
      "body": "Use -framerate 2 -start_number 1 with frame-%04d.png and an explicit three-frame output cap. The encoder creates review.mp4 using yuv444p and no audio. Each source PNG contributes one frame; the intended duration is 1.5 seconds."
    },
    {
      "title": "04. Verify frame count and colour order",
      "body": "Fully decode the MP4 and confirm exactly three 160×90 RGB frames. Sample the central field of every frame against its intended red/green/blue input within four channel values. The recorded worst difference is one; no interpolation was added."
    }
  ],
  "acceptance": [
    "The three-row manifest exactly matches contiguous frame-0001.png through frame-0003.png.",
    "Swapped manifest rows are rejected before encoding.",
    "A missing frame and an extra noncontiguous frame are separately rejected.",
    "An incorrect expected PNG SHA-256 is rejected.",
    "The actual review file decodes to exactly three 160×90 frames at the declared two-FPS assembly schedule.",
    "The central colours appear red, green and blue in order within four channel values; all nine checks pass."
  ],
  "troubleshooting": [
    {
      "symptom": "The clip contains the right images in the wrong order.",
      "change": "Correct only the manifest order and its index-to-filename binding, then rerun preflight before encoding."
    },
    {
      "symptom": "Encoding stops early because a numbered frame is missing.",
      "change": "Restore the missing original PNG at the exact basename and hash. Do not silently duplicate its neighbour."
    },
    {
      "symptom": "The review plays too quickly.",
      "change": "Change only the declared input framerate and document the new expected duration; preserve the three input identities and rerun frame-order checks."
    }
  ],
  "ending": "Keep sequence.json beside the assembled review. This fixture proves the chosen order and frame count; it does not create motion, extend frame holds beyond the chosen rate or qualify a distribution codec.",
  "assetCaption": "Original three-colour PNG sequence, actual review MP4 and an ordered-frame diagram. Local encoding only; no model interpolation or generation."
}
