Why agent-made videos don't break: Ozor's three scene checks
When an AI assistant builds a video with Ozor, it writes real code: one React component per scene. Models write good code most of the time, and confidently wrong code some of the time: an icon that does not exist, an import from the wrong place, a property read on data that is not there. In a web app that is a bug report. In a video it is a black frame in the middle of your launch. So every scene an agent sends to Ozor goes through three checks before it is saved, voiced or charged, and none of them involve AI.
Quick Answer
Ozor checks every agent-written scene three ways before saving it: parse (the TSX compiles), rules (only Ozor's shared library, real icons and easings, no clock or random APIs, readable text) and render (its first, middle and last frames render in the same engine that exports the MP4). A failing scene is not saved or charged; the agent gets the exact error and fixes only that scene. The checks are deterministic, not AI.
In this guide
A scene is a function of the frame
An Ozor scene is a React component that receives the current frame number, the canvas size, its duration and its data, and returns what that frame looks like. It is rendered once per frame at 30 fps: in the editor preview, in the frame previews an agent asks for, and in the export that produces the MP4, possibly in a different order and on a different machine each time.
That one design choice explains most of the rules. If anything depends on wall-clock time, a random number or a CSS transition, frame 120 in the preview and frame 120 in the export will not match, and the video stutters or flickers. So everything that moves has to be computed from the frame number alone:
import { React, getProgress, ease, lerp } from '/shared-lib';
export const Scene = ({ width, height, frame, durationSec = 3, data }) => {
const p = getProgress(frame, 6, 18, ease.outExpo); // 0 → 1 over frames 6–24
const drift = Math.sin(frame / 40) * 12; // ambient motion, still pure
return (
<div style={{ width, height, background: data?.brand?.colors?.background || '#0E1116' }}>
<h1 style={{ opacity: p, transform: `translateY(${lerp(40, 0, p) + drift}px)` }}>
{data?.headline || 'Ship the story'}
</h1>
</div>
);
};Agents learn this from the scene guide they read at the start of every conversation. The checks make sure they actually followed it.
The three checks
They run in order, and the render check only runs when the code could possibly work.
It compiles parse
The scene's TSX compiles. There is exactly one export named Scene, and the file ends where it should.
Typical failures · Unbalanced braces, a ${} placeholder outside a template string, a second export.
It follows the renderer's rules rules
Imports come only from Ozor's shared library and only use names it exports. Every identifier is declared. Icon names exist in Lucide. Easings are real. No wall-clock APIs, CSS transitions, external URLs or unsupported animation features. No text under 13px.
Typical failures · import from 'framer-motion', an easing that does not exist, an icon name the model made up, Math.random().
It actually renders render
The first, middle and last frames render in Ozor's video renderer, the same engine that exports the MP4, with the scene's real data, your brand kit and its duration.
Typical failures · "Cannot read properties of undefined" from unguarded data, "x is not a function", or frames that come out as a single flat color because nothing is visible.
The render check is the one that catches what code review misses. It renders the scene with the real data the agent passed and your real brand kit, at the real aspect ratio, so a headline that only exists in the agent's head or a brand color read without a fallback shows up as a crash now instead of a black frame later. It also catches the quiet failure: a scene that runs fine but draws nothing visible.
Ozor AI
Let your agent build it, safely
Every scene checked before it is saved. Connect Ozor to Claude or ChatGPT and try it free.
Try Ozor FreeWhat happens when a check fails
Nothing is saved, nothing is voiced, and no credit is spent. The agent gets back a short, specific message it can act on:
Not saved: fix this and call add_scene again.
failed check: rules
✗ [unknown-icon] `ChartGrowth` is not an icon in the renderer's lucide bundle,
so `Icons.ChartGrowth` is undefined and the scene fails at first render.Because videos are built one scene at a time, only the broken scene goes back and forth; the agent does not resend the whole video, which keeps your assistant's token use down. From your side, a failed check usually looks like nothing at all: the progress line for that scene arrives a few seconds later.
There is one escape hatch. For quality warnings the agent has genuinely tried to fix, like a frame that is blank on purpose, it may pass force=true. Anything that would crash the render or break the editor is never accepted, forced or not.
Beyond "it renders": does it look right?
Passing the checks means a scene works. Whether it is good is a design question, and Ozor gives the agent two tools for that. preview_scene renders the entrance, middle and exit frames (or up to four frames the agent picks) and returns them as images, so a model that can see can look at its own work and fix a cramped layout or unreadable contrast. validate_scene runs the three checks on draft code without saving anything, which is handy while iterating on one hard scene.
The scene guide carries the taste: motion that never freezes, staggered entrances, movement still going at the cut, text at least 22px for anything that matters, real content as the hero instead of icons. And the final judge is you, in the editor, where any scene can be changed by asking.
Why no AI in the checks
It would be easy to have a second model review every scene. We chose not to. A compiler, a rule checker and a real render give the same answer every time, finish in seconds, and cost nothing in tokens. They also answer the questions that matter for a video file (will it compile, will it render, will the export match the preview) with certainty instead of an opinion.
It is also what keeps the connector cheap. Ozor does not run a language model to build these videos at all; your assistant writes the code on your AI plan, and Ozor charges one credit per video (up to ten narrations) for the parts it adds. More on that split in Videos for agents.
Frequently asked questions
Does Ozor use AI to check the scenes an agent writes?
No. The three checks are deterministic: a compiler, a rule checker over the code, and a real render of three frames in the same engine that exports the MP4. That makes them fast, repeatable and cheap, and it means the result does not depend on a second model's opinion. Judging whether a scene looks good is left to the agent (with preview_scene) and to you.
What happens when a scene fails a check?
Nothing is saved, voiced or charged. The agent gets a short answer naming the scene, the check that failed and the exact error, such as a line and column for a parse error or the JavaScript error for a render crash. It fixes that one scene and sends it again; the scenes that passed are not resent.
Why can't scenes use Math.random() or Date.now()?
Because a scene is rendered one frame at a time, in any order, possibly on different machines. If a value depends on the clock or a random number, frame 120 in the preview and frame 120 in the export would differ, and the video would flicker. Every animated value has to be a pure function of the frame number. Agents that need randomness use a seeded function instead.
Can an agent skip a check?
Only for quality warnings it has already tried to fix, such as a frame that is blank on purpose, by passing force=true. Errors that would crash the render or break the editor (parse errors, bad imports, render crashes) are never accepted. If the renderer is briefly unreachable, the scene is saved with render marked skipped, and the export renders every scene again anyway.
Can I run the checks without saving anything?
Yes. validate_scene runs the same three checks on a piece of scene code and saves nothing, and it is free. preview_scene goes further and returns rendered frames as images. Both are useful when an agent is iterating on a single tricky scene.
Ozor AI
Videos your agent can't break
Connect Ozor to your assistant. 6 free credits, no card.
Try Ozor FreeWritten by Mintii Labs · Ozor founders · Oct 26, 2026
Series
Videos for Agents
- 1Videos for agentsHow AI assistants make real videos with Ozor.
- 2Make videos with ClaudeConnect Ozor to Claude in a minute and ask for a video.
- 3Make videos in ChatGPTAdd Ozor as a ChatGPT connector with developer mode.
- 4Videos from Claude Code, Cursor & CodexRelease notes, PR demos and docs videos from your repo.
- 515 videos your agent can makePrompts and scene types, from KPI recaps to launch teasers.
- 6Why agent-made videos don't breakThe three checks every scene passes before it is saved.