Contents

Document kinds

Every document says what it is in its kind and is checked against its JSON Schema in schemas/v1/. A Show Pack's documents live at fixed paths, so a file's name says what it is. Generated from the schemas and the show's file conventions.

In a Show Pack (23)

Bible

bible/bible.json · schemas/v1/bible.schema.json

The series bible: canon that is not owned by a single character, set or episode. Lore, relationships, running gags, tone rules, character arcs and open story threads. Every entry has a kind-prefixed id so the writers' room, director and continuity log can cite it. Character personalities live in each CharacterInstance's persona; world rules live in the ThemeSpec. The bible is read by every AI stage and forms part of the cached prompt prefix, so keep entries short and specific.

CharacterPattern

patterns/characters/<slug>.character-pattern.json · schemas/v1/character-pattern.schema.json

A parametric, seedable generator of CharacterInstances. Distributions address instance fields by JSON Pointer (e.g. /body/heightCm), so the pattern stays small, every instance field can be varied without changing this schema, and the same pointers are used for locks and single-attribute variations ('same crew, but vary only /head/hair/style'). Sampling order: fixed -> params -> archetype params -> rules -> costume -> palette -> persona -> voice; each step draws from a seed derived from the instance seed and the step's pointer, so adding a rule never reshuffles unrelated attributes.

CharacterInstance

cast/<slug>.character.json · schemas/v1/character.schema.json

One specific character: a fully resolved design (no ranges, no randomness) plus persona and voice. The engine's versioned character builder turns this into a rig-ready 2D cutout (Skeleton2D + named parts from the rig template) that can be drawn at any head/body yaw, and into a model sheet. Usually produced by sampling a CharacterPattern, then edited and locked by the user.

ClipInstance

clips/<slug>.clip.json · schemas/v1/clip.schema.json

Footage the show plays on a screen: its frames and its sound frozen in assets/ (Tier 2), each pinned by its hash, with the record of where it was cut. Lives at clips/<slug>.clip.json and is clip.<slug>. Made from a CutwrightClip by `reelwright asset import-clip` or the import_clip tool, never by hand. A screen cue (EpisodeIR 1.49) plays it on a set element frame for frame: on frame n of the cue the screen shows frame n − start, and its sound plays from the element.

CommentThread

comments/<slug>.thread.json · schemas/v1/comment.schema.json

A conversation about the work, pinned where it is about (docs/design/m13-shared-shows.md, "Comments"): a script's lines, a timeline frame or shot, a document, or the show. One per file, comments/<slug>.thread.json, so comments travel with the show and work on a show on your computer too. The session daemon writes them (comments.*); they are never a change set, and no model reads them unless someone asks Claude with them in view. On the web service each comment names its author; on the desktop a comment with no author is the show's owner's.

Continuity

bible/continuity/<slug>.continuity.json · schemas/v1/continuity.schema.json

What one episode established, with evidence. Written after an episode is approved (proposed by the showrunner, confirmed by the user) and read by the writers' room for every later episode, so the show never contradicts itself: facts, persistent state changes (a prop broke, a character learned something), gags used and threads touched.

EpisodeIR

episodes/<slug>/<slug>.episode.json · schemas/v1/episode.schema.json

The director's episode: for each scene, a continuous PERFORMANCE (cues: lines, moves, looks, gestures, sounds) and, separately, its COVERAGE (shots that cut over that performance). Timing is relative (cue after cue, cue with cue) because audio lengths are unknown until voices exist; the core resolves it deterministically into a frame-exact Timeline. Changing a shot never changes the performance, and changing a line's delivery re-times the shots that anchor to it. See docs/adr/0006.

FXPattern

patterns/fx/<slug>.fx-pattern.json · schemas/v1/fx-pattern.schema.json

A seedable generator of FxInstances for one FX family: a template effect plus pointer-addressed rules that vary it (e.g. /emitters/0/burst, /emitters/0/speedMps/max). Each sampled instance gets its own seed, so two sparks from the same pattern never look identical.

FxInstance

fx/<slug>.fx.json · schemas/v1/fx.schema.json

One effect (sparks, smoke, steam, beams, streaks, weather, shockwaves, glows) as a pure function of time, so any frame renders alone and the timeline can scrub. There is no simulation state: particle i of an emitter is born at a time given by its index (startSec + i / rate, or startSec for a burst); its random attributes come from pcg_hash(seed, emitter index, i); its position is closed-form ballistic motion with linear drag and gravity. No collisions. Times are seconds from the effect's start; curves and color ramps run over normalized time (particle life for particles, the emitter's active span otherwise).

GestureLibrary

gestures/<slug>.gestures.json · schemas/v1/gesture-library.schema.json

Gestures for one rig template, shipped with Reelwright (engine/addons/reelwright/library/) or a show's own (gestures/<slug>.gestures.json, schemaVersion 1.3; 1.4 adds a gesture's handShape and intensity), laid over Reelwright's by id: a show's gesture of the same id replaces Reelwright's for that show, any other is added to it. The core reads names, durations and stroke times to schedule gestures (a word-anchored gesture is placed so its stroke lands on the word); the engine reads the tracks and layers them additively on top of the current posture, scaled by intensity.

GraphicInstance

graphics/<slug>.graphic.json · schemas/v1/graphic.schema.json

One in-world graphic: a sign, label, screen, logo, poster or decal for an invented in-world brand. It is a flat list of layout blocks on a canvas, drawn in order, with text in the show's in-world language and fonts taken from the StyleSpec's typography. Animated screens are pure functions of time (seconds since the graphic appeared, modulo loopSec): radar sweeps, scrolling readouts, blinking warnings, typewriter text. Never reproduce real brands or logos.

GraphicsPattern

patterns/graphics/<slug>.graphics-pattern.json · schemas/v1/graphics-pattern.schema.json

A seedable generator of GraphicInstances for one graphics family (hazard labels, scanner screens, company logos). A template layout plus text pools in the show's in-world voice: any {{pool_id}} token in a template text or readout line is replaced by a weighted draw from that pool. Pointer-addressed rules vary everything else (sizes, colors, blink rates).

SetKit

kits/<slug>.kit.json · schemas/v1/kit.schema.json

A kit of set pieces: parametric recipes, and models and pictures brought in, that a show's sets and set patterns build from, browsed in the set explorer's library. A piece is named everywhere as kit.<kit name>.<piece id>, where the kit's id is kit.<kit name>. Reelwright ships a library of kits (engine/addons/reelwright/library/kits); a show keeps its own in kits/ (the pieces made in the piece maker, and the models and art it brought in). A set copies the recipe of every piece it uses into its own pieces, so a kit changing never changes a set built from it (docs/adr/0007).

ShowMemory

bible/memory.json · schemas/v1/memory.schema.json

What the show remembers of everything written so far (docs/design/m10-show-memory.md): the story so far, each character's voice, the running gags and callbacks with every time they played, the tone and house style the scripts keep, the world facts and the open threads. One per show, at bible/memory.json. The bible and the theme hold what the show intends (its rules); continuity logs hold what each episode put on screen, with evidence; memory is the writers' notebook distilled from the episodes, small dated entries each with its sources, read by every writer within a token budget. A remember pass proposes it after an episode is directed; the person edits, pins, locks, retires and forgets entries.

EpisodeOutline

episodes/<slug>/writers-room/<slug>.outline.json · schemas/v1/outline.schema.json

The writers' room's plan for one episode: premise and logline, then beats, then scenes, each settled at a checkpoint the human approves before the next is written, and then the screenplay. Every character, set and prop in it is one the show has or one it describes for the missing-asset pass to make. Lives at episodes/<slug>/writers-room/<slug>.outline.json.

PropPattern

patterns/props/<slug>.prop-pattern.json · schemas/v1/prop-pattern.schema.json

A seedable generator of PropInstances for one prop family: a base recipe, ranges for its params, weighted structural variants, palette rules and holding metadata. Sampling order: variant -> param ranges -> palette -> wear, each from a seed derived by name path. A grip named as one of the recipe's grip anchors is placed where that anchor is at the sampled params, so a hand holds it right at any size. Its name and its tags are the words a script's thing is matched by (a lantern, a mobile for a phone).

PropInstance

props/<slug>.prop.json · schemas/v1/prop.schema.json

One specific prop, fully resolved and self-contained: its own 3D recipe with resolved param values, palette, holding metadata and states. The engine builds it from its recipe in the style of the set (docs/design/m6-props.md): standing on a place, or held, its grip at the hand the character card drew, upright in the holder's facing.

SetPattern

patterns/sets/<slug>.set-pattern.json · schemas/v1/set-pattern.schema.json

A seedable generator of SetInstances for one family of locations. It carries (1) a modular kit: parametric piece recipes (data, not engine code, so new pieces need no new engine code); (2) a layout grammar: room shell, zones in normalized room coordinates, placement and adjacency rules, walkway clearance; (3) dressing rules; and (4) rules that generate the director's staging data: marks, entrances, walk paths, camera setups and lighting presets. Room coordinates: x runs 0 (left wall) to 1 (right wall), z runs 0 (back wall, upstage) to 1 (front, downstage, the open fourth wall), both as seen from the default audience view.

SetInstance

sets/<slug>.set.json · schemas/v1/set.schema.json

One location, fully resolved. Sets live in 3D stage space (meters, +Y up, -Z is 'upstage' away from the default audience view) so staging, camera placement and film-grammar checks are real geometry; the StyleSpec decides whether it renders flat, cel-shaded or painterly. Characters are 2D cutouts placed on marks as camera-facing cards (see docs/adr/0004).

ShowManifest

show.json · schemas/v1/show.schema.json

Root of a Show Pack (show.json). A Show Pack is a directory that holds every spec for one series and is designed to be its own git repository. Documents are found by naming convention (<slug>.<kind>.json under their folder), so this manifest stays small: identity, delivery format, which theme and style are active, and non-secret provider settings. API keys never go here.

SoundRecipe

audio/sfx/<slug>.sound.json · schemas/v1/sound.schema.json

A sound effect described as layers of tones, tone sequences and filtered noise, which the core synthesizes into the same bytes on every machine. Lives at audio/sfx/<slug>.sound.json and is the sound sfx.<slug>, exactly as audio/sfx/<slug>.flac would be; the audio is derived into .reelwright/cache/sfx/, so the recipe is what is proposed, reviewed and approved. Times are seconds from the start of the sound.

StyleSpec

styles/<slug>.style.json · schemas/v1/style.schema.json

How the show LOOKS and MOVES: line, shading, color, texture, timing, motion principles, camera language, post-processing and design transforms. Every field maps to a shader uniform, material parameter, animation parameter or solver weight in the engine, so swapping the active StyleSpec re-renders the whole show without touching story data. Pixel-sized values are given at a 1080-line reference (Px1080) and scale with output resolution.

ThemeSpec

theme/<slug>.theme.json · schemas/v1/theme.schema.json

What world the show lives in: setting, genre, tone, world rules, and the catalog of things that exist in it (set types, costume families, prop families, graphics and FX). A theme says WHAT exists; a StyleSpec says how it LOOKS; patterns say how to GENERATE it.

Between the core and the engine, and shipped with Reelwright (8)

Capture

schemas/v1/capture.schema.json

A performance a camera watched while a take was recorded (docs/design/perf-capture.md): keys of the rig's own channels, the head's turn, where the eyes look and the face's fields, in seconds into the take. Kept beside the take as audio/takes/<sha256>.capture.json, source material as the recording is. No picture, no video and no face points are kept. A line plays it only where its EpisodeIR names it (LineCue.capture).

ChangeSet

schemas/v1/changeset.schema.json

A proposed, reviewable change to a Show Pack. Every tool that changes anything, whether driven by the showrunner or the user, produces one. Nothing touches the show until it is approved. Operations carry the base hash of the file they change, so a proposal made against an older version is marked stale instead of overwriting newer work. Undo applies a new change set that is the inverse of an applied one; history is never rewritten. Change sets live in .reelwright/changes/ (and, when the show is a git repo, applied ones become commits). Unlike show documents, a ChangeSet has its own lifecycle `status` instead of meta.status.

CutwrightClip

schemas/v1/cutwright-clip.schema.json

A clip of edited footage Cutwright hands to Reelwright (clip.json, beside its frames/ and its sound): Cutwright's `clip` export, cut from its sources by word ids. `reelwright asset import-clip <dir>` (or the import_clip tool) checks every file against its hash, freezes the frames and the sound into the show's assets/ with this provenance, and writes a ClipInstance (clips/<slug>.clip.json) that a screen cue plays. Reelwright reads it; it never writes one.

FrameExport

schemas/v1/frame-export.schema.json

A render handed to another program as numbered PNG frames and WAV stems, with what it needs to trust and place them: the release and engine that drew it, the Timeline it played, its range, size and alpha, every frame's file and SHA-256, and the stems trimmed to the range at the mix's gain. reelwright render writes it to <out>/frame-export.json when it delivers png_frames; a render that delivers only frames and stems (--deliver png_frames,stems_wav) encodes no H.264. Every file is named relative to the folder this document is in.

PartLibrary

schemas/v1/part-library.schema.json

What a character part library draws, shipped with Reelwright (engine/addons/reelwright/library/<id>.parts.json). A CharacterInstance names its library in rig.partLibrary. For each field listed here the engine draws a value in `draws` as itself, a value in `fallbacks` as the value it names, and anything else as `default` (or skips it when there is no default), with a warning; fields not listed are drawn as written. The core reads the same file to warn, when a pattern or character is written, about values the library would not draw as written.

RenderJob

schemas/v1/render-job.schema.json

A self-contained request from the core to the engine. It embeds every resolved document the engine needs, so a job directory alone reproduces its output. The engine writes images into output.dir and a RenderResult to output.dir/result.json. Jobs are ephemeral (they live in .reelwright/jobs/); they are never specs.

RenderResult

schemas/v1/render-result.schema.json

What the engine reports after a RenderJob (output.dir/result.json). The core trusts nothing it cannot check: it verifies every listed file and hash before encoding.

Timeline

schemas/v1/timeline.schema.json

The compiled, frame-exact form of an EpisodeIR: the only thing the engine plays. Written only by the core compiler; never hand-edited (edit the EpisodeIR instead). Every value is resolved: frames not seconds, world points not targets, explicit seeds. Frame ranges are half-open [startFrame, endFrame). Keyframed channels interpolate from each key to the next using the key's `ease`; the last key holds. The engine evaluates any frame independently (docs/adr/0002).