Skip to main content
A project is one video. Every brief you give Ralphy becomes a project — a directory under workspace/projects/<id>/ with a brief, prompts, assets, a render, and three append-only logs. Projects are first-class: they have a registry, a lifecycle, a versioning policy, and they are the unit the CLI mutates. Everything else (brands, personas, refs, templates) attaches to a project.

Project IDs

A project ID is {context}-{NNN} — a kebab-case context tag plus a three-digit ordinal. Examples:
  • coffee-shop-001
  • nothing-hp1-001
  • analog-horror-fridge-001
  • noski-people-001
  • playdate-pixel-001
The context tag should encode the brief, not the output. coffee-shop-001 is a project about a coffee shop — whether the final video is 9:16 or 16:9, English or Russian, 8 seconds or 60. The ordinal increments per context: when you make a second video for the same coffee shop, the next ID is coffee-shop-002. The ID lands in two places:
  • The on-disk path: workspace/projects/coffee-shop-001/.
  • The global registry: ~/.ralphy/projects.json maps coffee-shop-001<absolute workspace path>. This is how ralphy project show <id> works across multiple repo checkouts.
ralphy new <context> is the canonical way to create a project — it picks the next available ordinal, scaffolds the directory, and writes the registry entry.

The on-disk layout

workspace/projects/coffee-shop-001/
├── BRIEF.md                # the captured brief, written during intake
├── prompts.json            # resolved per-scene prompts
├── asset-manifest.json     # slot → file pointer table
├── STORYBOARD.md            # human-readable beat list
├── POSTMORTEM.md            # legacy single-file format (old projects)
├── postmortem/              # new 6-file split (new projects)
│   ├── 01-chat-history.md
│   ├── 02-lessons.md
│   ├── 03-bugs.md
│   ├── 04-models-cost.md
│   ├── 05-workflow-fixes.md
│   └── 06-summary.md
├── assets/
│   ├── scene-01-bg.png
│   ├── scene-01-bg.v1.png   # auto-archived on regen
│   ├── scene-01-clip.mp4
│   ├── voiceover-en.mp3
│   ├── music-bed.mp3
│   └── uploaded/             # user-supplied refs the agent pulled in
│       ├── product-photo.png
│       └── gameplay-loop.mp4
├── render/
│   ├── final.mp4
│   └── final.v1.mp4
└── logs/
    ├── generations.jsonl     # every model call (append-only)
    ├── user-prompts.jsonl    # every user prompt (append-only)
    └── user-assets.jsonl     # every user-uploaded ref (append-only)
The files break into three groups. Authored, edited in place. BRIEF.md, prompts.json, asset-manifest.json, STORYBOARD.md. These describe the project’s intent and pointer-state. They are updated in place by ralphy verbs — the manifest is a pointer table, so updating the pointer to point at <slot>.v2.png does not destroy <slot>.v1.png (the actual file is still on disk). Append-only, never rewritten. logs/generations.jsonl, logs/user-prompts.jsonl, logs/user-assets.jsonl. See /concepts/generation-log for the schemas. These are the audit trail. Read-and-rewrite to tidy is a defect; the postmortems and cross-session memory all assume the logs are complete. Produced, never overwritten. Everything under assets/ and render/. Regenerating scene-01-bg.png first archives the existing file to scene-01-bg.v1.png (then .v2, .v3, …) and then writes the new one. This is enforced at the file-system level by ralphy generate since commit 753d2f7 (2026-05-19). --force-overwrite opts into legacy destructive behavior.

Lifecycle

A project moves through five stages. The agent’s role at each stage is in docs/playbooks/.
1

Intake

The user drops a brief. The agent runs docs/playbooks/intake.md: 3-5 clarifying questions (target language, aspect, brand, duration, hard “no”s), draft a plan in chat, wait for user “go.” BRIEF.md is written when the user signs off. No paid generation happens before this step completes (AGENTS.md invariant — intake protocol).
2

Scenario

The scenarist playbook turns the brief into a scene-by-scene scenario — hook, beats, VO lines, on-screen text, suggested aspect, suggested register. The scenario lives in prompts.json and the human-readable form in STORYBOARD.md. The scoreScenario quality gate runs here; two consecutive failures stop the run.
3

Prompts and assets

The art-director playbook resolves scenes into model-specific prompts and runs the generation verbs: ralphy generate image, ralphy generate video, ralphy generate voiceover, ralphy generate music, ralphy generate sfx. Each produced file is a slot in asset-manifest.json. Each call is an entry in generations.jsonl. Quality gates (scoreImage, scoreVideo) run per asset.
4

Composition and render

The editor playbook authors the HyperFrames composition (workspace/projects/<id>/index.html) and runs ralphy render <project> to produce render/final.mp4. Captions, transitions, audio mix, and color grade are all editor-stage. A re-render archives the previous mp4 to final.v1.mp4.
5

Postmortem

Once the user signs off on the cut (or the project is abandoned), the /postmortem skill writes the 6-file split under postmortem/. The lessons file is what the next project’s agent reads at session start (see docs/playbooks/meta.md rule 1). This is where most of the institutional knowledge in the codebase actually accumulates.
A project does not have to walk all five stages. A quick batch project (“make 10 variants of the same hook”) collapses intake into one line and skips the postmortem. A research-only project (/researcher https://tiktok.com/...) lands under workspace/research/<slug>/ and never becomes a video at all.

The project registry

~/.ralphy/projects.json is the global registry. It maps project-id → absolute workspace path, plus a few metadata fields (created-at, last-touched-at, status). ralphy project list reads this. ralphy project show <id> resolves the path and prints the manifest. The registry is additive. Creating a new project appends to the registry. Wiping workspace/ does not clear the registry — you can have entries pointing at projects that no longer exist on disk. ralphy project list flags these. ralphy project delete <id> removes both the directory and the registry entry; that is the only safe way to forget a project. Two consequences worth knowing:
  • You can have two ugc-cli checkouts on the same machine. Both register projects against the same global registry. ralphy project show coffee-shop-001 resolves to whichever checkout owns it.
  • Projects survive a workspace wipe if you dumped them to a profile. ralphy profile install <nick> restores workspace/projects/<id>/ from the profile dump under profiles/<nick>/.

The append-only philosophy

Every artifact under workspace/projects/<id>/ is append-only or version-archived. The rules (from AGENTS.md invariant #13):
  • Regen creates a new version, never overwrites. ralphy generate ... against a slot that already has a file auto-archives the existing file to <slot>.v{N}.<ext> before writing. Pass --force-overwrite only when the user explicitly asks for legacy destructive behavior.
  • No rm, fs.rm, fs.unlink, fs.rename-over-existing inside a project directory unless the user said the words “delete / remove / clean / wipe” pointing at that artifact.
  • The three JSONL logs are append-only by definition. Never truncate, rewrite, or filter in place. Read-and-rewrite to “tidy” is a defect.
  • Failed and rejected generations stay on disk. The gen-log + manifest reasoning across sessions depends on the failed artifacts still being there.
  • If the user wants a clean slate, they ask for it. Use ralphy project delete <id> (registry-aware) or wait for explicit rm -rf permission scoped to a named path. Never volunteer a cleanup.
Why this matters: across 10 shipped projects’ postmortems, the highest-cost recurring failure was “the agent silently overwrote a working v1 with a broken v2 and lost the good one.” The CLI now prevents that at the file-system level. The asset manifest is the pointer; the disk holds every version. See /concepts/generation-log for the manifest schema and the promote-a-version workflow.

Useful verbs

ralphy new <context>                       # create a new project, picks next ordinal
ralphy project list                        # all known projects (from registry)
ralphy project show <id>                   # full project state (manifest + log summary)
ralphy project timeline <id>               # chronological log view
ralphy project log <id>                    # raw JSONL pretty-printed
ralphy project log-prompt <id> --text ...  # append a user-prompt entry
ralphy project log-asset <id> --source ... # append a user-asset entry
ralphy project delete <id>                 # registry-aware delete (asks for confirmation)
Full verb / flag reference at /cli/project-verbs.
  • Workspace — where projects live alongside brands, refs, and the cache
  • Generation log — the append-only JSONL schemas and the versioning model
  • References — when refs are required before generation
  • Templatesralphy template use <slug> scaffolds a project
  • Producer playbook — end-to-end and batch flows