Open format · take/1.0 · draft

The .take format

A file that records how a generated video was actually made: every attempt, in order, with what changed between them and why each one was discarded.

take/1.0 application/vnd.rizzgen.take+json Spec & schema CC0 1.0 Tools MIT

Why a file at all

Generation tools store outputs. A folder of MP4s tells you what survived and nothing about how you got there — which model, which prompt, which of the eleven attempts, and what was wrong with the other ten.

.take stores the lineage: the tree of takes behind a finished cut. Three things follow that a folder cannot support.

  • Replay. Re-run any take from the file alone.
  • Fork. Start from someone else's take with the recipe loaded, instead of a blank prompt.
  • Analysis. Count attempts to an acceptable result, per model, per failure mode.

It is not an edit decision list, not a delivery format and not a container for media. It describes generation lineage and nothing else. A .take file sits alongside an EDL; it does not replace one.

Prior art

Nothing here is the first attempt to write down how a piece of film came together. The practice is older than the tools, and .take is narrower than all of its neighbours.

  • The script supervisor's notes. Every take numbered and given a verdict: NG with a reason why, a hold, or the circled take — the one the director wants printed. Attempts, verdicts, reasons, exactly one keeper. This format is that page, for generation.
  • EDL, AAF, FCPXML, OpenTimelineIO. Editorial interchange. They describe the finished timeline — which source, which timecode, which transition — which is to say they describe what survived.
  • ShotGrid, ftrack, Kitsu. Production tracking does record versioned attempts with review statuses and notes, and is the closest living relative. But it is a service you log into rather than a file you can hand someone, and it tracks artist submissions rather than the recipe behind each attempt.
  • C2PA / Content Credentials. A signed manifest that travels with a delivered asset, declaring which model produced it and what has happened to it since. Complementary rather than competing: C2PA explains the file that shipped; .take explains the nine that did not.

So: is this an EDL? No. An EDL has one entry per slot in the finished cut. A .take file has one entry per attempt, and most of those attempts are not in the cut — that is the entire point of keeping them.

The shape of a document

{
      "format":   "take/1.0",
      "project":  { "id", "title", "created_at", "default_branch" },
      "assets":   [ referenced images and audio, by name and hash ],
      "shots":    [ one slot in the finished piece ],
      "branches": [ a named line of development, forked from a take ],
      "takes":    [ one generation attempt, success or failure ],
      "timeline": { branch: { shot: take } }
    }
Take
One generation attempt. Success or failure — both are takes, and the failures are most of the value.
Shot
One slot in the finished piece. Many takes compete for one shot.
Lineage
The parent chain. parent names the take this one was derived from.
Branch
A named line of development forked from a specific take.
Keeper
A take listed in the timeline. From the script supervisor's practice of circling the take the director wants printed.

What the schema cannot say

The schema covers shapes. These five rules are the format, and a reader has to enforce them itself.

  • Lineage has no cycles. The parent relation is a DAG; a cyclic document is rejected, not repaired.
  • Exactly one root branch, and it is the default. Two roots make “where does this cut come from” unanswerable.
  • A timeline take belongs to the shot it is listed under, and to a branch that exists.
  • inputs_hash is RFC 8785 (JCS) over inputs, so key order in the file cannot change the hash. Recompute it; do not trust it.
  • Verdicts are recomputed, never read. keeper > rejected > superseded > pending. A take in the cut is the keeper whatever label somebody typed on it earlier, and supersession is scoped to one shot — a child on a different shot is continuity conditioning, not a replacement.

Treat a .take file as untrusted

It arrives in a Discord, a handoff or a pull request. Before doing anything else, a reader should:

  • bound the input — 10 MB and 10,000 takes — before any graph work;
  • reject duplicate JSON members. {"seed":1,"seed":2} means different things to different parsers, and a document that means two things is not a document;
  • reject non-finite numbers and nesting past 64 levels;
  • never dereference a URI from the document. A uri in someone else's file is an SSRF vector. The reference reader fetches nothing; the viewer has no network access at all.

Privacy, and the limits of replay

A .take file carries prompts, model choices, reference names and rejection notes. Prompts routinely contain client names, unreleased product details and candid notes.

  • Exporters should let an author redact fields, and should mark a redaction rather than silently omitting it — a reader must be able to tell an empty prompt from a withheld one.
  • Cost is optional and opt-in. A file with no cost is not a file that cost nothing.
  • A fork copies inputs and lineage, not output media. Copying someone else's rendered video into your project is a licensing problem, not a feature.

Replay is best effort. Providers deprecate and silently re-tune model versions, so a pinned seed will not always reproduce, and some providers accept no seed at all. A seed of null means the take is not replayable — it is deliberately not filled in with something plausible. A replaying reader must not claim a take was reproduced unless inputs.seed and model.provider_version are both present.

Two flavours of the same document

Both are valid take/1.0. They differ in what the author is willing to hand over, and a reader has to expect either.

  • An owner export is the whole record: output.uri on every finished take, a uri on every asset, seeds, provider versions. The URIs are content-addressed (cas://sha256/…), so they identify bytes rather than locate them — a reader still needs the store they came from. minimal, ladder and branched below are this flavour.
  • A published document, served from /t/<slug>.take, is input-only: prompts, models, reference names, verdicts and lineage. No take carries output at all, every asset uri is null, and every seed is null. Each take instead carries a redactions array saying so in words. public.take below is this flavour, and is generated by the endpoint rather than written by hand.

Write your reader for the published flavour first. It is the one you will meet, because it is the one a public link hands out. Treat output as absent unless present, and read redactions before concluding that a missing field means the document is broken. The original ids survive as source_take, so a published file can always be lined up against the page it came from.

Tools

A reference reader, a command line tool and a single-file viewer, in one repository. No dependencies, no build step, no install. Node 18+ for the CLI, any current browser for the viewer.

git clone https://github.com/rizzgen/take-format
cd take-format

node cli/take.mjs validate examples/public.take
node cli/take.mjs ladder   examples/ladder.take shot_01
node cli/take.mjs stats    examples/branched.take --branch ending/calm

validate checks structure, the graph rules above and every declared inputs_hash. ladder prints one shot's attempts with what changed at each step. lib/take.mjs is the same reader as a module, with no CLI wrapped around it.

Examples

  • minimal.take — the smallest valid document: one shot, one take.
  • ladder.take — one shot, five attempts, including a safety refusal, with the note on each one that was thrown away.
  • branched.take — the same shot carried onto a second branch, so two cuts can be compared.
  • public.take — the same film as ladder.take as the public endpoint serves it: no output media, no seeds, asset URIs null, redactions on every take. Build against this one.

Licence

The specification text, the JSON Schema and the examples are dedicated to the public domain under CC0 1.0. The reader, CLI and viewer are MIT licensed.

The format is given away deliberately. Implement it, extend it, embed it or fork it — no permission, no attribution, no licensee.