### The receipt ledger holds a decode to the frames it delivered, as one animated PNG

- **Tariff and invoice version 5** ([extensions/receipt-ledger.md](extensions/receipt-ledger.md) §4.8): version 4's
  layout, rules and prices, and one rule more. A decode (a job whose route record's operation is `media.decode`)
  delivers its reconstruction, and the codestream is what it read. Version 4 gives every `int_motion` output as its
  receipt and codestream and holds the codestream to what the hop delivered: true of an encode, false of a decode,
  whose hop had to state an object it never delivered and commit its receipt to it. Under version 5 a decode's output
  also gives `frames`, one animated PNG (PNG's third edition) of 8-bit RGB frames, each the whole picture and blended
  over nothing, its default image its first frame, read whole and then frame by frame as packaging §5 reads a still's
  image data, each frame's samples hashing (integer-payloads §15.1) to the receipt's frame at its index; the receipt is
  still re-derived from the codestream, the decode's input; and the served hop states exactly that animation, by
  content hash, and nothing else (`output_invalid` at the animation or the frame, `output_not_delivered` at its place,
  or at `outputs` for an object past it). One object, not one per frame, because a route record states a hop's outputs
  once each and at most 1024, and a clip runs longer and repeats frames. The frame hash binds the samples, not the
  PNG's bytes, so any writer's animation of the right samples holds. An encode, and every other job, is held as in
  version 4, and a decode bills its receipts' subpixels as before. A version-4 reader would refuse a decode's frames,
  and a version-4 verdict must not change, so this is a version of its own; versions 1 to 4 read, verify and bill
  exactly as before.
- **Animated PNG** (`png_still::encode_animation`, `png_still::animation`): a writer every byte of which is a function
  of the frames and the delay, and a reader of §4.8's rules that reads the whole structure first and each frame's
  samples only when asked, so a long clip is never held decoded.
- **The corpus** adds nineteen vectors: a decode held to its animation beside an encode; a decode whose record states
  the codestream it read, and one stating it past the animation; a decode in version 4's form; a frame with one sample
  changed, two frames swapped, a still for the animation, a frame missing, frames of another shape holding the same
  samples, and a codestream not the receipt's; an animation that blends a frame over the one before, disposes of one by
  no defined operation, holds a frame of part of the picture, skips a sequence number, keeps its default image apart
  from its frames, counts a frame more than it holds, or has a frame with no data; a decode in version 5's form under
  version 4; and a version-4 invoice under a version-5 tariff. `receipt_ledger_verify.py` reads version 5 with an
  animation reader of its own, reads each frame's data with the packaging verifier's PNG reader, and drops one more
  check (`decode-frames`); three more mutated copies of the corpus must fail. The ledger service (`wai/wai-ledger`)
  bills version 5 as version 4.
- **Breaking:** `record:corpus:wai/live-conformance/ledger/vectors.json`: the control `invoice_version` gives an
  invoice of version 6, since version 5 is now defined, and is refused `unknown_version` as before; every other vector
  keeps its outcome, and the new vectors are added.

