# Projects

A project is a folder; this is every file in it and who writes it.

A project is a folder anywhere on disk holding one video: the brief, the storyboard, one file per scene, the renders, and the output. Agents read and write these files and nothing else; the daemon's planner reads them to decide what comes next. The cast, the objects, and anything specific to one video live here, never in a style.

rapid lists projects from its project folders: `~/rapid` (where new videos go) plus any added with [`rapid projects add <dir>`](/docs/cli#rapid-projects). Each folder directly inside one is a project, titled by its brief's first heading. The screening page's jobs page lists them with their jobs and starts new videos in them.

## The layout

```text
brief.md                        what the video is, in your words
rapid.lock                      the style and format it uses, pinned
storyboard.json                 the storyboarder's plan: system, assets, scenes
storyboard.md                   the same, readable: what you approve
assets/                         pictures, logos, clips, models, and the track the video uses
assets/<track>.music.json       the track's map, from rapid listen
assets/<track>.music.png        a picture of the map
shots/<id>.json                 a Blender shot's recipe
scenes/<id>.html                each scene, an HTML scene
reviews/<id>-k<try>.json        a reviewer's review of a scene's key frame
reviews/<id>-r<round>.json      a reviewer's review of one round
reviews/storyboard-d<n>.json    the director's direction of the storyboard, look n
reviews/video-r<n>.json          the director's direction of the joined video, look n
reviews/shot-<id>-k<try>.json   a reviewer's review of a shot's key stills
renders/<id>/key-k<try>.png     a scene's key frame, a still at meta.key
renders/<id>/key-k<try>.checks.json  the key frame's code checks
renders/<id>/key-k<try>.html    the scene file as that try left it
renders/<id>/r<round>.mp4       a scene's render for that round
renders/<id>/r<round>.boxes.json   element boxes, per frame
renders/<id>/r<round>.cues.json    the scene's cues
renders/<id>/r<round>.checks.json  the code checks' result: { pass, marks }
renders/<id>/r<round>.sheet.png    the contact sheet at the review times
renders/<id>/r<round>.micro.png    frames 0.3 s either side of its key and marked moments
renders/<id>/r<round>.html      the scene file as that round left it
renders/video-d<n>.sheet.png     the video sheet the director reads
renders/shots/<id>/             a Blender shot: stills/, a folder of frames per pass, <pass>.webm, manifest.json
renders/<id>/marks.json         your marks on the scene, which every build reads first
renders/picture.mp4             the accepted scenes joined
renders/mix.wav                 the video's sound
video.mp4                        the video
video-phone.mp4                  its phone copy
.rapid/film-<job>.json          a video job's settings
.rapid/film-<job>.choices.json  what the job chose without you
.rapid/look/                    a look drafted by rapid style extract, which the video job finishes and pins
```

Only `video.mp4` and `video-phone.mp4` are meant to leave the folder; the rest is working files.

## brief.md

Plain Markdown: the length, who speaks, what it's for, what must not appear. The `rapid-brief` skill writes it under fixed headings (Intent, Audience, The one thing, Must show, Never, Length and format, …). Its first `# heading` is the job's title; without one, the folder's name.

## storyboard.json

A `Storyboard` (`contracts/src/film.ts`), written by `rapid-storyboarder` or by hand. When it exists, the storyboard step is skipped.

| Field | Type | Notes |
|---|---|---|
| `title` | string, 1–200 | |
| `logline` | string, up to 4000 | what the video is and how it should feel; default `""` |
| `system` | `FilmSystem` | `spine` (what runs through every scene), `score` (`{ token, job }` per colour), `moves` (`{ move, scenes }`: each big move and the only scenes it appears in), `rules` (house rules); each defaults empty |
| `assets` | array of `Asset` | `{ path, what, kind?, status }`: `path` under `assets/`; `kind` `photo`, `clip`, `screenshot`, `logo`, `drawing`, `audio`, or `other` (a `screenshot` is reference, never shown as it is); `status` `have` or `missing` (a stand-in is drawn until it arrives); default `[]` |
| `rhythm` | `{ shape, beat?, bpm?, notes }` | optional; the scenes' lengths as one shape, cut to a grid of `beat` seconds |
| `music` | `{ path, from }` | optional; the track the video is cut to and where in it the video starts, in seconds, default 0. Its map is `<path>.music.json`. See [music](/docs/music) |
| `shots` | array of `{ recipe, scenes }` | the Blender shots the video renders and the scenes that show them, default `[]`. See [Blender shots](/docs/blender-shots) |
| `redesign` | array of `{ source, becomes, scenes }` | each section of a source interface and the one video element it becomes; default `[]` |
| `generated` | array of `{ kind, what, scenes }` | visuals drawn where photos are thin (`field`, `diagram`, `chart`, `crops`, …); default `[]` |
| `scenes` | array of `StoryScene`, 1–60 | in order |

`StoryScene`:

| Field | Type | Notes |
|---|---|---|
| `id` | id | `a-z`, `0-9`, `-`, up to 64, starting with a letter or digit; names `scenes/<id>.html` |
| `title` | string, 1–120 | |
| `place`, `clock` | strings, up to 80 and 20 | optional; the place and clock lines drawn over the scene |
| `lines` | array of `Line` | `{ who, name?, text }`: `who` `speaker`, `assistant`, or `guest`; `name` (up to 40) a guest's first name; `text` 1–1000; default `[]` |
| `materializes` | string, up to 2000 | what appears because of what was said; default `""` |
| `hero` | string, up to 1000 | the one visual the scene is remembered by; default `""` |
| `key` | `KeyFrame` | optional; `frame` (what fills it, colours as tokens or hex, sizes in px), `at` (seconds), `type` (`{ text, kit, px, width }` per line, from `rapid measure`), `assets`, `lower` (what fills the lower half) |
| `enter` | `{ kind, notes }` | optional; how it comes in over the scene before; `kind` is a meta enter kind |
| `primary` | string, up to 120 | optional; the scene's one primary move |
| `camera` | `{ move, notes, why? }` | optional; the scene's main move: `push`, `pull`, `pan`, `tilt`, `roll`, `parallax`, `reframe`, `rack`, `vertigo`, or `none` (with `why`). A quick move (`snap`, `crash`, `whip`, `shake`) is a beat's hit: say where it lands in `notes` |
| `secondary` | array of `{ motion, notes }` | what moves while the hero holds; default `[]` |
| `layout`, `scale` | strings | optional; the layout slot and what fills the frame |
| `breath` | boolean | optional; the one scene allowed type alone on its field |
| `out` | `Transition` | optional; the join into the next scene: `{ kind, dur, ease?, dir?, el?, at?, color?, params?, notes }`. `kind` is `cut` (the default) or one of the join's [named moves](/docs/transitions); the element moves `match`, `held-object`, `mosaic-dive`, `glyph-swallow`, and `lens-portal` need `el`. All but `cut` and `match` overlap at least 0.1 s |
| `beats` | array of `Beat`, at least 1 | `{ shot, dur, notes }`: `shot` a word of the shot vocabulary (`field`, `voice`, `reply`, `file`, `type`, …) |
| `dur` | seconds | the estimate; the scene's own timings set its real length |

The director's plan checks (a primary move, a camera, a layout slot, a scale, a transition out, variation between neighbours) read these fields; see [the job graph](/docs/the-job-graph#the-planner-grows-the-graph).

The demo's storyboard:

```json
{
  "title": "A two-scene demo",
  "logline": "An idea lands as type, then a card carries it off.",
  "scenes": [
    { "id": "idea", "title": "make it out loud", "lines": [], "hero": "the words landing one by one",
      "beats": [{ "shot": "type", "dur": 2.6, "notes": "word by word" }, { "shot": "type", "dur": 0.6, "notes": "exit left" }],
      "dur": 3.2 },
    { "id": "card", "title": "the brief leaves", "lines": [], "hero": "the card arriving and leaving",
      "beats": [{ "shot": "file", "dur": 3, "notes": "in from the right, out to the left" }], "dur": 3 }
  ]
}
```

## storyboard.md and assets/

`storyboard.md` is the storyboard in prose: the system, the assets, and each scene's key frame and hand-off. It is what you approve. `assets/` holds what you give the video (pictures, logos, clips, a 3D model, a track); the storyboarder lists each in `assets` and marks what is missing. Scenes reach it as `../assets/…`.

When `assets/` comes from a page (`rapid style extract <url> --assets assets`), it also holds `assets.json` (every kept file, with where it came from), `screens/` (every screen of the scrolled page), and `contact.png` (the kept files in one labelled grid). See [keeping a page's assets](/docs/extracting-a-style#keeping-a-pages-assets).

## scenes/

One HTML scene per storyboard scene, named by its id. A scene here is served from the project, so `../assets/…` resolves. A scene file that exists when the job starts is rendered as it is, not built, unless `--rebuild`. See [writing scenes](/docs/writing-scenes).

## rapid.lock

The packages the project pins, by version and hash, so the video renders the same later whatever the style became. Written by `rapid style use` and `rapid format use`. See [the lockfile](/docs/style-json#the-lockfile).

## reviews/ and renders/

Written by the graph's nodes, one set per scene per round: `r1`, then `r2` for a revised scene, and so on; a note after the video numbers its rounds after the earlier ones, so nothing is overwritten. Key frames come first, `k1`, `k2`, …; the meta's `"key": seconds` names the moment. See [review](/docs/review).

## .rapid/

`.rapid/film-<job>.json` holds the job's settings (style, format, review, keys, director, stops, rounds, the resolved package folders); a restarted daemon's planner reads it and carries on. `.rapid/film-<job>.choices.json` records each choice made without you. A video made in a look keeps the draft in `.rapid/look/` (the `rapid-brief` skill puts it there) and each check of it in `.rapid/look-<k>-t<n>.checks.json`; once a check passes, the look is pinned in `rapid.lock` at a version stamped with its contents.
