Skip to main content

WAI Extension: Direction Records

Mirrored from the canonical text at commit b1681667 ().

Status: Draft. Registers the record wai.media.direction: a person’s direction of generated or edited video, as signed evidence bound to the output. A director, a person named by an Ed25519 key (as a did:key, the same key), signs direction records at four levels of control: a storyboard fixes the shots, each with its duration, its subjects by reference picture and its framing (the shot level), and may fix their order (the sequence level); keyframes fix, at stated times of a shot, a subject’s box on screen, its size class, its screen position and its angle, relative to the subject, and a camera window, with a pinned interpolation between keys (the frame level), and regions hold samples of stated frames to a reference picture (the pixel level); a sequence fixes the edit: which shots, which part of each, in which order, cut or dissolved (the sequence level). Each record states the levels it sets. A tool that makes a video under direction signs a directed output record naming the direction records, the layout of every frame of every shot, the timeline of the edit and the output’s frames by digest. Where the output was made by the pinned render of this extension from layers that wai.generate.spectral regenerates or that the verifier holds, every frame recomputes, and the checks are exact: each cut falls at its directed frame, each duration and the order are the directed ones, each subject is where the keyframes and their interpolation put it under a pinned integer framing measure, and each held region holds. Where a model made the frames in floating point, the same checks run on the layout the tool states, and the outcome is attested with the class of what stated it, never exact. Every directed element governs the output frames that show what it directed, and the record states them: the per-frame map shows which person directed each frame’s framing, timing, held samples and place in the sequence, whoever made its samples, and each element maps onto a direct step of the contribution record and onto a C2PA action. WAI decides no legal question. No new transport. The reference implementation is the direction module of wai-rs (feature direction); the corpus is live-conformance/direction/, and its second implementation is live-conformance/direction_verify.py. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

Texts read for this revision, each pinned to the version named: the C2PA Technical Specification, version 2.4, §6.4, §18.2 (§18.2.2.1, §18.2.2.4 and §18.2.3 among it), §18.15.1, §18.15.2, §18.15.4.1 and §18.15.4.6; the Creator Assertions Working Group’s Identity Assertion, version 1.2, §5.1, §5.1.2 and §6.1; the serialized schemas of OpenTimelineIO release 0.18.1 (Timeline.1, Stack.1, Track.1, Clip.2, Transition.1, RationalTime.1, TimeRange.1) and its transition types; the abstract of arXiv 2606.01900; and Copyright and Artificial Intelligence, Part 2: Copyrightability, a report of the United States Copyright Office (January 2025), its Part II.F and its Part V. A section number of one of those texts in this extension is that version’s.

1. Scope

1.1 Why

Direction of generated video works at four levels: the pixel, the frame, the shot and the sequence. A director decides what each shot shows and how it is framed, where a subject sits on screen and how large, how the camera moves, which samples stay fixed, where each cut falls and in which order the shots run. arXiv 2606.01900 states framing as functions of the subject’s pose and motion (shot size, angle and composition) and directs a virtual camera with sparse keyframes deterministically interpolated into a trajectory. A generator then makes the samples.

The cited report concludes that outputs made with generative AI may be protected in whole or in part where a person was able to determine the expressive elements they contain, that prompts alone are unlikely to suffice at this stage, and that the questions are decided case by case (its Part V); and that a person may select, coordinate and arrange generated material, or modify it, in a way that contributes authorship (its Part II.F). Whether a director’s choices are such a contribution is a question for a registration authority or a court, under its own rule.

This extension makes the director’s choices signed facts, bound to the output they governed, and checks them: exactly, frame by frame, where the output recomputes; as the tool’s statement, with its class, where it does not. It states, for every frame, who directed what. It does not say what any of that makes anyone.

1.2 In scope and out of scope

In scope: the records and their encodings (§2); the levels and the elements of direction (§3); the storyboard (§4); keyframes, their interpolation and held regions (§5); the sequence and the timeline arithmetic (§6); the framing measure (§7); the directed output (§8); the render (§9); governance, the per-frame map and the contribution record’s direct act (§10); the mappings onto C2PA actions, identity assertions and an open timeline interchange format (§11); verification (§12).

Out of scope:

1.3 Relationships

Relationship to the core spec: wai.media.direction is a record (SPEC §5): signed records a WAI tool emits and verifies. It names no payload format and is not dispatchable.

Relationship to wai.generate.spectral: a layer of a directed output may be a picture that generator makes; a verifier holding the model file regenerates it (SPEC §5, Payload of wai.generate.spectral).

Relationship to deriving-edge: the render of §9 places layers as that extension’s wai.derive.overlay_composition does, opaquely at integer offsets, and resamples by the nearest sample, the reference rule of its wai.derive.scaling (§4.2 there), which this extension pins for its own render.

Relationship to synthesis: a directed output’s origin claim is that extension’s; direction changes no class. A video whose layers or frames a model generated is synthesized, however closely a person directed it.

Relationship to the contribution record, wai.media.contribution: that record reserves the act direct for this extension. §10.3 defines the step, its parameters and its dependency rule.

Relationship to the exploration record, wai.media.exploration: a subject’s view, a shot’s reference or a plate may be a picture an exploration archive holds, chosen by a pick; this extension names it by its samples digest, and the archive and the pick are that record’s.

2. Records

Every record of this extension is a JSON object (RFC 8259) under the encodings of jwp-receipts §2.4.3, read as synthesis §2 reads a record: strict JSON, no member named twice, at most 32 levels of nesting, byte strings in lowercase hexadecimal, integers unsigned and at most 2^53 − 1, no other number, no boolean, terms and date-times as defined there. Each record has exactly the members its section lists, no member missing and none added, at any level, and a kind naming it; one that does not is record_malformed. So is a member outside the values or ranges its section gives, or one that breaks a rule its section states of the record alone.

Every record carries signer_pubkey (32 bytes, an Ed25519 key of RFC 8032) and sig (64 bytes):

sig       = Ed25519(signer_key, "wai:direction\x01" || JCS(record without "sig"))
link_hash = BLAKE3("wai:direction-link\x01" || JCS(record))

JCS is RFC 8785. The signature is verified strictly (SPEC §7 Signatures): a key that fails step 1 or 2 is bad_key, and a signature that fails a later step bad_signature. A record is named by its link hash wherever another names it. issued_at holds the instant its signer signed it, self-asserted.

Values used throughout:

3. Levels and elements

A level is one of pixel, frame, shot and sequence, in that order. Each direction record has a member levels: the levels it sets, in that order, none twice. A record whose levels is not exactly the levels its members set (§4, §5, §6) is record_malformed.

An element is one directed choice of a record, named by a path:

levelelementpathwhat it fixesits record
shota shot["shot", i]the shot’s duration, its subjects and the framing it opens onstoryboard (§4)
framea shot’s keys["keyframes", e]each subject’s box and classes, and the camera, at each key and between keyskeyframes (§5)
pixela held region["region", j]the samples inside rects of stated frameskeyframes (§5.3)
sequencethe order and cuts["sequence"]which shots in which order, which part of each, each cut and dissolvestoryboard (§4) or sequence (§6)

i is a shot’s position in the storyboard, e an entry’s and j a region’s position in their keyframes record. A record’s elements are, in this order: a storyboard’s shots by position, then ["sequence"] where it sets that level; a keyframes record’s entries by position, then its regions by position; a sequence record’s ["sequence"].

4. The storyboard

A director signs a storyboard, kind "wai-storyboard":

membertypemeaning
kindstring"wai-storyboard"
levelsarray["shot"], or ["shot", "sequence"] when order is not null
width, heightintegerevery frame’s size: a picture’s sides (§2)
rateobject{"num", "den"}, each from 1 to 1 048 576: frames per second, as num / den
subjectsarray0 to 16 subjects (§4.1)
shotsarray1 to 256 shots (§4.2)
orderarray or null1 to 1024 shot positions, in the order the shots run, each a shot whole, joined by cuts; null where the storyboard does not fix an order
issued_atdate-timewhen the director signed it
signer_pubkey, sig§2: the director’s key

4.1 Subjects

A subject is {"views"}: 1 to 8 views, each {"angle", "samples", "width", "height"}, a term naming the angle the subject is seen from and a picture reference: the subject’s reference picture as seen from that angle, its whole extent edge to edge. No angle appears twice in one subject. Angles are the director’s terms; front, three-quarter, profile, back, high and low are examples, not a list. A subject is named by its position.

4.2 Shots

A shot is {"duration", "subjects", "framing", "reference"}:

A position in subjects or order that is not a subject’s or a shot’s, or an angle that is not one of the subject’s views’, is record_malformed.

5. Keyframes

A director signs a keyframes record, kind "wai-keyframes":

membertypemeaning
kindstring"wai-keyframes"
storyboard32 B hexthe link hash of the storyboard it directs
levelsarray["frame"] when only keyframes is not null, ["pixel"] when only regions is not, ["pixel", "frame"] when neither is null
keyframesarray or null1 to 256 entries, each {"shot", "keys"}: a shot’s position and 1 to 1024 keys (§5.1); no shot twice
regionsarray or null1 to 256 held regions (§5.3)
issued_atdate-timewhen the director signed it
signer_pubkey, sig§2: the director’s key

A record whose keyframes and regions are both null is record_malformed.

5.1 Keys

A key is {"t", "interp", "camera", "subjects"}:

Within an entry, every key’s subjects has one length, and for each subject either every key gives a box or none does; likewise the camera. Otherwise record_malformed.

A subject’s boxes, and the cameras, are tracks. A track begins at the entry’s first key. The classes of a key are checked at its t alone.

5.2 Interpolation

A track’s value at frame t of the shot, from the first key’s t to the shot’s last frame, is computed member by member (x, y, w, h): for t from a key k (at tₖ, value vₖ) up to the next key (at tₖ₊₁, value vₖ₊₁), with n = t − tₖ and D = tₖ₊₁ − tₖ, by key k’s interp:

interpvalue
holdvₖ
linearvₖ + ⌊(vₖ₊₁ − vₖ) · n / D⌋
easevₖ + ⌊(vₖ₊₁ − vₖ) · n² · (3D − 2n) / D³⌋

From the last key to the shot’s end the value is the last key’s. ease is the cubic that starts and ends with zero speed, s²(3 − 2s) of s = n / D, in integers. A value lies between its two keys’ values, so w and h stay at least 1 and a camera window between two windows inside the plate stays inside it.

5.3 Held regions

A held region is {"shot", "from", "to", "rects", "source"}: a shot’s position; its frames from up to, not including, to (from < to); 1 to 64 rects within the frame; and a picture reference of the frame’s size, the source. In those frames, every pixel inside a rect is the source’s pixel at the same position. A region holds a reference picture, a drawn matte, a fixed element or a locked background to exact samples, whatever made the rest of the frame.

6. The sequence

A director (an editor directs the sequence) signs a sequence, kind "wai-sequence":

membertypemeaning
kindstring"wai-sequence"
storyboard32 B hexthe link hash of the storyboard it edits
levelsarray["sequence"]
eventsarray1 to 1024 events (§6.1)
issued_atdate-timewhen the director signed it
signer_pubkey, sig§2: the director’s key

6.1 Events

An event is {"shot", "in", "out", "transition"}: a shot’s position; the frames of the shot it shows, in up to, not including, out (in < out ≤ 65 536), its length L = out − in; and the transition into it: {"kind": "cut"}, or {"kind": "dissolve", "frames"}, a dissolve over frames ≥ 1 frames. With dᵢ the dissolve frames into event i (0 for a cut): the first event’s transition is a cut, and dᵢ + dᵢ₊₁ ≤ Lᵢ for every event i (with d = 0 past the last), so no frame shows more than two events. Otherwise record_malformed.

A storyboard’s order is the events {"shot": i, "in": 0, "out": duration of i, "transition": {"kind": "cut"}}, one for each position i of order, in its order.

6.2 The timeline

Events run in order. Event i starts at output frame Sᵢ: S₀ = 0 and Sᵢ = Sᵢ₋₁ + Lᵢ₋₁ − dᵢ, and occupies the output frames Sᵢ up to, not including, Sᵢ + Lᵢ. The output has N = Sₘ₋₁ + Lₘ₋₁ frames, m the number of events. A dissolve into event i overlaps the last dᵢ frames of event i − 1 with the first dᵢ of event i.

Output frame f shows frame in + (f − Sᵢ) of event i’s shot for each event i that occupies it: one event, or two in a dissolve. The cuts are S₁, …, Sₘ₋₁: the frames where each event after the first begins to show, cut or dissolved.

7. The framing measure

The framing measure of a subject in a frame of width W and height H is computed from its box (x, y, w, h) and the angle of the view it is drawn from:

A directed class matches when the measure gives it. A directed box matches when it equals the subject’s box member for member; a directed camera window when it equals the frame’s window.

8. The directed output

8.1 The record

The tool that made the output signs the directed output, kind "wai-directed":

membertypemeaning
kindstring"wai-directed"
directionarray1 to 64 link hashes of the direction records it was made under, the storyboard first; none twice
directorsarray1 to 64 keys (32 B hex), the people who directed it; none twice, none the tool’s key
checkstringreplicate or attest
attestationobject or nullnull for replicate; for attest, {"generator", "class"}: a term naming what made the frames, and a term naming the class of method that stated the layout (a tracker, a detector, the generator’s own conditioning)
layersarray0 to 256 layers (§8.2)
clipsarray1 to 256 clips (§8.3)
timelinearray1 to 1024 events (§6.1): the edit as made
outputobject{"width", "height", "frames", "digest", "content_hash"}: the output’s frame size, its number of frames (1 to 2^20), the digest of its frames (§8.4), and the content hash (jwp-receipts §2.1) of the object it was published as, or null
governsarray0 to 1024 entries (§10.1)
issued_atdate-timewhen the tool signed it
signer_pubkey, sig§2: the tool’s key

replicate states that every frame is the render of §9 over the layers; attest that something else made the frames and the layout is the tool’s statement, of the class it names. The record reads only if its timeline does (§6.1).

8.2 Layers

A layer is a picture reference with its source, {"samples", "width", "height", "source"}; no samples digest twice. Its source is one of:

A layer is named by its samples digest wherever a clip or a direction record names a picture.

8.3 Clips

A clip is the layout of every frame of one shot as made, {"frames", "plate", "camera", "subjects", "holds"}; the clips are the storyboard’s shots, in order:

A camera, views or boxes whose length is not frames is record_malformed.

8.4 The frames’ digest

digest = BLAKE3("wai:direction-frames\x01" || D_0 || D_1 || … || D_{N−1})

with Dₖ the samples digest of output frame k, width × height RGB8 (§2), in order. A frame is named by its samples digest, as a frame of a wai.video.int_motion clip is checked by its state.

8.5 Layout rules

Against the storyboard, a directed output whose layout breaks one of these is layout_invalid, or layer_missing where a picture it needs is not one of its layers:

  1. There is one clip per shot of the storyboard.
  2. Each clip’s subjects are subjects of the storyboard, and each view position is one of that subject’s views.
  3. For replicate: each clip’s plate is not null, and is a layer (layer_missing); with no camera, the plate is the frame’s size; each camera window is a rect within the plate; each view drawn is a layer of the size the storyboard states for that view (layer_missing where it is not a layer). For attest: each plate is null.
  4. Each hold’s rects are within the frame; for replicate its source is a layer (layer_missing) of the frame’s size.
  5. Each timeline event names a shot of the storyboard and out is at most its clip’s frames.
  6. The output’s width and height are the storyboard’s, and its frames is the timeline’s N (§6.2).

9. The render

The render is pinned: every byte of every frame it makes is a pure function of the layers and the record, integer throughout.

9.1 A clip’s frame

Frame t of a clip, width W by height H, is drawn in this order:

  1. The plate. With no camera, out(X, Y) = plate(X, Y). With the camera window (cx, cy, cw, ch) of frame t, out(X, Y) = plate(cx + ⌊X · cw / W⌋, cy + ⌊Y · ch / H⌋): the window resampled to the frame by the nearest sample.
  2. The subjects, in the clip’s order. With the box (bx, by, bw, bh) of frame t and the view V of frame t, vw × vh: every pixel (X, Y) of the frame with bx ≤ X < bx + bw and by ≤ Y < by + bh is V(⌊(X − bx) · vw / bw⌋, ⌊(Y − by) · vh / bh⌋): the view scaled to its box by the nearest sample and drawn opaquely, the part off the frame dropped.
  3. The holds, in order: for each hold whose frames include t, every pixel inside each of its rects is the source’s pixel at the same position.

9.2 An output frame

Output frame f that shows one event is that event’s clip frame (§6.2). One that shows events i − 1 and i, in a dissolve of d = dᵢ frames, is a blend of their clip frames A and B: with j = f − Sᵢ + 1 (1 to d), each byte is

out = ⌊(A · (d + 1 − j) + B · j + ⌊(d + 1) / 2⌋) / (d + 1)⌋

so B’s weight rises by 1/(d + 1) each frame and neither picture is ever shown alone inside the dissolve.

10. Governance

10.1 What an element governs

An element (§3) governs the output frames that show what it directed, on the timeline the directed output states:

elementthe output frames it governs
["shot", i]each frame that shows any frame of shot i
["keyframes", e]each frame that shows a frame t of the entry’s shot with t in its keyed frames: from its first key’s t to the shot’s end where it has a track, and otherwise the t of each key that gives a class
["region", j]each frame that shows a frame of the region’s shot from from up to, not including, to
["sequence"]every output frame

Within those frames, a region governs the samples inside its rects, and every other element every sample. A frame that shows two events is governed by what governs either.

The directed output states this in governs: one entry for each element of each record it names, in the order of direction and then of each record’s elements (§3), each {"record", "element", "frames"}: the record’s position in direction, the element’s path and the frame set (§2) it governs, [] for none. An entry that is not that element’s, or not its frame set, is governance_mismatch. So a tool cannot claim for a director frames the director’s choice did not govern, and cannot leave out frames it did.

10.2 The per-frame map

The frame map gives each output frame: the frames it shows, [shot, t] for each event occupying it (§6.2); and directed_by, an object of four members, pixel, frame, shot and sequence, each the positions in directors of the signers of the elements of that level that govern it, ascending, none twice. It shows, frame by frame, which person directed the framing, the timing, the held samples and the order, beside whatever made the frame’s samples: the layers’ sources (§8.2) for replicate, the attested generator for attest.

10.3 The contribution record’s direct act

The contribution record, wai.media.contribution, reserves the act direct for this extension. Each element that governs at least one frame becomes one step of that record’s session:

member of the stepvalue
partythe director: a human party whose key is the element’s record’s signer
actdirect
inputsnone
output, regionnull
params{"record", "element", "frames"}: the direction record’s link hash, the element’s path, and the frame set it governs (§10.1)
checkreplicate when the directed output’s check is replicate, so every check of §12.2 the element has ran on recomputed frames; attest otherwise
signerthe director

Its dependency rule: the step introduces no sample and changes none; it adds the director to directed_by of every sample the element governs (§10.1), in every frame of frames, and leaves made_by as it is. A verifier of the contribution record holding the direction records and the directed output recomputes frames by §10.1 and refuses a step whose frames differ, as §12.2 refuses a governs entry. So the authorship map shows, per frame, that a person directed framing and timing where a model made the samples. The contribution record’s revision of 2026-10-21 maps still pictures only; the step applies, sample by sample, in the revision that maps video frame by frame, and to a still picture as an output of one frame.

11. Mappings

11.1 C2PA actions

For each director with at least one element that governs a frame, an accepted case gives one C2PA statement, {"actions": A}, written in JCS: A is an actions assertion’s actions (C2PA 2.4 §18.15.1), one for each of that director’s elements that governs a frame, in the order of §10.1:

{"action": "c2pa.edited", "changes": C, "description": T}

C2PA 2.4 §18.2.2.4 recommends temporal ranges for media over time. Direction is exact in frames, and a frame’s time at a rate such as 24000/1001 has no exact decimal form, so the statement uses frame ranges; a manifest that also wants times derives them from rate.

Each director’s statement is one actions assertion of the output’s manifest, labelled by C2PA 2.4 §6.4’s rule for several assertions of one type. It is never the first actions assertion, which begins with the manifest’s c2pa.created or c2pa.opened action (C2PA 2.4 §18.15.2): the generation’s, or the contribution record’s statement where there is one. Embedding the statements in a manifest, and signing it, is C2PA’s.

11.2 Identity assertions (informative)

A director may give the output’s manifest an identity assertion (Identity Assertion 1.2 §5.1, label cawg.identity) whose referenced assertions include the actions assertion of §11.1 that holds that director’s actions, which §6.1 there gives as an example of an assertion that lets an actor describe its relationship to the content. A role of §5.1.2 there is the director’s own statement; this extension derives none. The director’s key in the records is an Ed25519 key, and the relation between it and the assertion’s credential is the director’s to state.

11.3 An open timeline interchange format (informative)

A sequence (§6) maps onto OpenTimelineIO’s serialized schemas, release 0.18.1: a Timeline.1 whose tracks is a Stack.1 holding one Track.1 of kind "Video", whose children are, for each event i in order, a Clip.2 whose source_range is a TimeRange.1 from start_time in to a duration of Lᵢ − dᵢ₊₁ frames, each a RationalTime.1 at rate num / den, naming the shot’s clip as its media; and, before each event entered by a dissolve, a Transition.1 of transition_type "SMPTE_Dissolve" with in_offset 0 and out_offset dᵢ frames. The cut point is then Sᵢ, the outgoing clip’s range ends there, and the dissolve draws its last dᵢ frames from past that range, as this extension’s timeline shows them. An edit decision list that records each event’s source in and out points and its record in point (Sᵢ), with a cut or a dissolve of a duration, carries the same values. Neither format carries the framing of §5 or the governance of §10, and neither is signed: they are the edit’s interchange, and the direction records are its evidence.

12. Verification

12.1 Inputs

A verifier is given: the directed output record; the direction records it holds, in a list; the model files it holds, each named by its SHA-256; the pictures it holds, each a buffer named by its samples digest; and a policy of one member:

membervaluesdefaultmeaning
requireattested, exactattestedthe lowest status it accepts (not_exact)

12.2 Steps

The verifier runs these steps and stops at the first refusal, which it reports with its reason and its place: ["output"], ["record", i], ["direction", k], ["layer", i], ["clip", i], ["clip", i, t], ["timeline"], ["timeline", i], ["governs", i] or ["policy"], each i a position in its list (a record’s among the records given, a direction record’s k among direction), and t a frame of a clip.

  1. Reading (§2, §4–§6, §8): the directed output at ["output"], then each record given at ["record", i]: record_malformed, bad_key, bad_signature.
  2. The direction, each link of direction in order at ["direction", k]:
    1. a record given has that link hash (record_unknown);
    2. the first is a storyboard and no other is; each keyframes or sequence record’s storyboard is the first’s link hash (storyboard_mismatch);
    3. its signer is one of directors (signer_not_party);
    4. no second record sets the sequence level, and no keyframes entry directs a shot an earlier record’s entry directs (direction_conflict);
    5. against the storyboard, every shot, subject and angle it names exists; every key’s t is below its shot’s duration; every key has one subject entry per subject of its shot; every region’s to is at most its shot’s duration, its rects are within the frame and its source is the frame’s size; every event’s out is at most its shot’s duration (direction_inconsistent).
  3. The check, at ["output"]: a replicate record with a layer of another generator than wai.generate.spectral (§8.2) is check_mismatch: a float generator’s picture is never claimed exact.
  4. The layout (§8.5): rule 1 at ["output"]; rules 2 to 4 clip by clip at ["clip", i]; rule 5 event by event at ["timeline", i]; rule 6 at ["output"]: layout_invalid, layer_missing.
  5. The layers, for replicate, each in order at ["layer", i]: a generated layer whose model file the verifier does not hold, or a given layer whose buffer it does not hold, is layer_missing; a held buffer that is not width · height · 3 bytes is samples_mismatch; a generated layer whose picture’s samples digest is not samples is regeneration_mismatch.
  6. The frames, for replicate, at ["output"]: the verifier renders every clip frame (§9.1) and every output frame (§9.2) and computes the digest of §8.4; another digest than output.digest is frame_mismatch.
  7. The direction against the layout: each element of each direction record, in the order of §10.1, against the clips and the timeline the directed output states:
    • ["shot", i]: clip i’s frames is the shot’s duration (duration_mismatch, at ["clip", i]); its subjects are the shot’s, in its order (subject_mismatch, at ["clip", i]); each class of the shot’s framing matches the measure (§7) of clip frame 0 (framing_mismatch, at ["clip", i, 0]);
    • ["keyframes", e]: for each keyed frame t of the entry’s shot in ascending order, each subject’s box is its track’s value (§5.2), the camera window is the camera track’s, and, at a key, each class it gives matches the measure (framing_mismatch, at ["clip", s, t], s the shot);
    • ["region", j]: the shot’s clip has a hold with the region’s from, to, rects and source (region_mismatch, at ["clip", s]);
    • ["sequence"]: with the directed events (§6.1), the timeline holds the same shots in the same order (order_mismatch, at ["timeline"]); then, event by event, each starts at its directed frame (cut_mismatch, at ["timeline", i]); then each has its directed transition (transition_mismatch); then its directed in and out (duration_mismatch).
  8. Governance (§10.1), each entry in order at ["governs", i], and a missing entry at the position it would have: governance_mismatch.
  9. Policy: an attest record under require exact is not_exact, at ["policy"].

A sequence level no record sets is not checked: the order is then the tool’s own, and no element governs it.

12.3 Status

The outcome’s status is exact for replicate: the frames recompute, so the layout the checks of step 7 read is what the frames hold, cut for cut and pixel for pixel. It is attested for attest, with the attestation’s generator and class: the same checks ran on what the tool stated, which nothing recomputed. An attest record is never reported exact.

12.4 What an accepted case states

13. Reasons

The codes this extension adds, each with where it is raised:

reasonraised at
record_malformed§2, §3, §4, §5, §6.1, §8, §12.2 step 1
bad_key§2
bad_signature§2
record_unknown§12.2 step 2
storyboard_mismatch§12.2 step 2
signer_not_party§12.2 step 2
direction_conflict§12.2 step 2
direction_inconsistent§12.2 step 2
check_mismatch§8.1, §12.2 step 3
layout_invalid§8.5
layer_missing§8.5, §12.2 step 5
samples_mismatch§12.2 step 5
regeneration_mismatch§8.2, §12.2 step 5
frame_mismatch§8.4, §12.2 step 6
duration_mismatch§4.2, §6.1, §12.2 step 7
subject_mismatch§4.2, §12.2 step 7
framing_mismatch§5, §7, §12.2 step 7
region_mismatch§5.3, §12.2 step 7
order_mismatch§6, §12.2 step 7
cut_mismatch§6.2, §12.2 step 7
transition_mismatch§6.1, §12.2 step 7
governance_mismatch§10.1, §12.2 step 8
not_exact§12.1, §12.3

14. Conformance

live-conformance/direction/ holds the corpus, in one file, vectors.json, written from fixed seeds by wai_direction_vectors gen. It holds the model file of wai.generate.spectral its layers are generated with, the pictures given as they are, the measures (the framing measure of §7 alone: boxes at both sides of every size bound and every column and row bound, past every edge and at the limits of a signed integer, each with the classes it measures), the interpolations (§5.2 alone: each mode, rising and falling, at the keys, between them and with floors below zero, each with its value), and the vectors: each a case of §12.1, its outcome and, accepted, everything §12.4 states; refused, its reason and its place. Its frames are small (64 × 36 pixels at 24 frames a second), so every one recomputes. It has:

A conforming verifier gives every vector the outcome, the reason, the place and the statements the corpus states. wai_direction_vectors verify and the test tests/direction.rs check that the file regenerates byte for byte, that wai-rs gives every vector its outcome, that the corpus refuses with every reason of §13, and that §13 lists exactly the reference’s codes. live-conformance/direction_verify.py is the second implementation, written from this text: it shares no code with wai-rs; it runs the generator in its own arithmetic and checks it first against the generator’s conformance vector (wai-rs/tests/vectors/generate/sha256.json), renders every frame, interpolates every track and measures every box itself, writes every statement and C2PA statement itself, reads records with synthesis’s second implementation’s JSON reader, verifies every signature with WAI’s strict rule (claim-conformance/_ed25519.py) and every link hash with BLAKE3 written from its specification (claim-conformance/_blake3.py); it mutates copies of the corpus and requires every copy to fail; and it drops each of its own checks in turn and requires the corpus to catch the weakened verifier.

15. Security and privacy considerations