Review & Export
Nothing renders until a human has approved it. The platform has two human-in-the-loop gates during generation, a QA review pass in the editor, and an on-demand render/export step. This page covers the review process and the rendering capabilities.
Human-in-the-loop gates
The Director workflow suspends for human approval twice. The UI for both lives in web/src/components/DirectorPanel.tsx.
Gate 1 — Storyboard
After ANALYZE, the run suspends and the proposed storyboard is shown:
- What's shown: scene count, the narrative, the anchor blueprint, and a runner badge (
llmorstub) so you know whether AI or the deterministic stub produced it - What you can do:
- Edit any scene's intent (free text)
- Swap a scene's template (
SceneTypePicker) and see its beat badge - Remove a scene
- Add notes and Regenerate (re-run ANALYZE with your feedback)
- Approve / Build to proceed
- Dirty tracking: editing flips the action to "Build edited storyboard"
The decision is sent via POST /api/director/:runId/resolve:
| Decision | Effect |
|---|---|
approve |
WRITE → ASSEMBLE → returns the ResolvedIR |
edit |
Adopt the edited storyboard, then proceed as approve |
reject |
Re-ANALYZE with notes → revised storyboard |
Gate 2 — Content
After ASSEMBLE, the document opens in a content review:
- Per-scene: edit template params (via
PropEditor) and the voiceover (editable script text + Regenerate audio) - Edits update the
ResolvedIRimmediately - Actions: Regenerate from brief (fresh content from the same intake), New brief, or Approve & open in editor
Review phase (QA pass)
In the editor, the Review tab (web/src/components/ReviewPanel.tsx) is a deterministic QA report — no LLM, no render. For every scene it checks:
- Template validity —
requireModule(templateId).schema.safeParse(props)(are the props valid for the template?) - Duration — is the scene length sane?
- Voiceover — is narration present where expected?
- Aspect support — does the template support the document's aspect?
It rolls these into a readiness summary; clicking a scene jumps back to Edit to fix it. This is the last check before delivery.
Deliver phase (render & export)
The Deliver tab (web/src/components/DeliverPanel.tsx) renders the document to MP4:
- Live progress on the document's native aspect (16:9 / 9:16 / 1:1)
- One-click aspect variants — render the same document in other supported aspects
- Session render history with download links
How rendering works
Export is in-process, via @remotion/renderer in web/src/app/api/director/export/route.ts:
sequenceDiagram
participant UI as DeliverPanel
participant API as /api/director/export
participant R as Remotion renderer
UI->>API: POST { ir } → jobId
API->>R: ensureBrowser() + selectComposition("StudioDoc") + renderMedia({ inputProps: ir })
R->>R: headless Chromium renders VideoDocument(ir) → MP4
R-->>API: write storage/renders/<id>.mp4
UI->>API: GET ?jobId (poll)
API-->>UI: { progress } … then { url }
- Composition: the generic
StudioDoccomposition (registered inweb/remotion/Root.tsx) renders the live document;inputPropscarry theResolvedIR - Same component as preview:
renderMediarenders the sameVideoDocument.tsxthe editor previews — preview and export cannot drift - Asset access: the render's Chromium fetches logical asset paths from
/api/mediausingASSET_BASE_URL(defaulthttp://127.0.0.1:3000); the render bundle is served onREMOTION_RENDER_PORT(default3333, must differ from Next's3000) - Asset pruning: missing audio/image/video
srcvalues are dropped so a placeholder doesn't break the render - Job model: an in-memory job map tracks progress; the client polls
GET ?jobId. (Jobs are per-process — a restart clears in-flight jobs; finished MP4s persist on disk.) - Output: MP4 under
storage/renders/, downloadable via/api/media
Render settings
- fps: 30 (from the document dimensions)
- Resolution: from aspect — 1920×1080 (16:9), 1080×1920 (9:16), 1080×1080 (1:1)
- Codec: H.264 MP4 (Remotion default)
Saving the project
Independently of rendering, the document itself can be saved to the server document store via POST /api/director/docs and reloaded later — so a video can be revisited and re-exported without regenerating. See Library & Media.