shipped@di-atomic/video-director · v0.1.0 · beta

Your 60-second video is 57 seconds.

Transitions overlap the shots either side of them, so a plan whose clip lengths add up to sixty renders fifty-seven seconds of video and three seconds of black. Nothing errors. video-director turns a script into a shot list your renderer accepts unmodified: it solves for content rather than for the raw sum, quantizes generated clips to the lengths models actually produce, and names the engine on every row.

For anyone whose agent makes video — and who has watched a render succeed, come back the right file size, and still be wrong.

A dark chalkboard showing one long horizontal bar. The long left portion is filled with white chalk hatching and labelled 57s CONTENT; a short stub at the right end is outlined in gold and left empty, labelled 3s BLACK.
Built by Di-Atomic Marketing & compliance agency Measured on real renders, not inferred 7-language team Clients incl. ONYX Radiance, Pamit Group
3.0sof black a naive 60-second plan ships, unannounced
16.7%of a control render that came back pure black
12 of 12adversarial shot lists rejected, including an empty one
4verifiers that print PASS or FAIL with numbers
Installopvs-skills install @di-atomic/video-director

Then say: “turn this script into a shot list” or “why does my video end in black?”.

Why the plan a person writes is the plan that fails

What a hand-written shot list does
want 60s, so pick clips that add to 60
8 + 8 + 8 + 8 + 8 + 10 + 10 = 60
send it to the renderer

→ six cuts overlap; where did 3s go?
→ 10s is not a length veo3 makes
→ is a row a shot, or a whole post?
→ transition left at the default (a crossfade)
→ nothing errors, so nobody checks

(ship it, find out later)

Every one of those is silent. The render succeeds, the file is the right size, and the last three seconds are black.

What video-director produces
mode     REQUIRED, no default, rejected if absent
engine   named on every row, never inferred
len      only a length the model actually makes
content  sum(len) − (n−1) × transition_seconds
target   solved for content, so 8×6 + 15 = 63
seam     axis, direction and speed per cut
default  a defaulted transition is counted
gate     4 verifiers, before a clip is bought

A plan you can check before you pay for it, because the arithmetic that produced it is printed alongside it.

A render that succeeds is not a render that is right.

Every row names how its asset is made, and the type follows

aiA generated clip. Capped at 5 to 15 seconds, and only on a length the model natively produces.
avatarA lipsync take. Driven by the length of the line it speaks.
screenA real screen recording. Any length, and elastic, so it absorbs the remainder.
motionA composition with props. Any length, and where a title card or logo hold costs no generation.
typeWhat the renderer does with a finished asset. Derived from the engine, never chosen by hand.

What you actually get

🧮

Arithmetic that accounts for overlap

Transitions overlap their neighbours, so content = sum(len) − (n−1) × transition_seconds. Seven clips totalling sixty seconds with six half-second cuts render fifty-seven. The planner solves for content, and the verifier prints the black tail you would have shipped.

🎛️

Durations quantized to what models make

veo3 returns eight seconds. sora2 returns ten or fifteen. No model honours a request for 6.3. So in an all-generated package you close a gap by changing the shot count, not by stretching a clip — and in a mixed one, the slack goes on a screen or motion row.

✂️

Cuts you can check before rendering

The schema defaults transition to fade, a crossfade carries nothing across the cut, and the craft rule forbids crossfades — so accepting the default is itself the defect. Seams are graded in the renderer’s own transition vocabulary, on the plan, with no animation library shipped.

One 60-second short, planned and gated

> "turn this script into a 60-second short"

  mode ........... single_video   (asked, never guessed)
  aspect ......... 9:16  fps 30

  FIRST ATTEMPT — the plan a person writes
  8 + 8 + 8 + 8 + 8 + 10 + 10 = 60

  verify-shot-list.mjs --target 60
    shot 6: len 10s is NOT native for veo3 (native: 8s)
    content 57.00s misses target 60s by 3.00s
    black tail a naive sum would ship: 3.00s
    solve for sum len = 60 + 3.00 = 63.00s
  RESULT ......... FAIL (2 violations)

  CORRECTED
  8 × 6 + 15 = 63
    n = 7,  overlap = 6 × 0.5 = 3.0
    content = 60.00s

  verify-shot-list.mjs ............ PASS
  verify-projectability.mjs ....... PASS  0 unmapped fields
  verify-seam-ledger.mjs .......... PASS  0 defaulted transitions
  verify-prompt-grammar.mjs ....... PASS

  → handed to media-generator: 7 rows, 0 edits

Checking a plan is free. Rendering it is not. So the whole list is graded before a single clip is generated — and the gate reports the black tail even on a PASS, as a reminder of what the raw sum would have cost.

Two constraints, and they are coupled

A dark chalkboard showing exactly two white chalk rectangles side by side, overlapping slightly, with the narrow overlapping sliver filled solid gold. Labelled ONE CUT above and 0.5s below, with x 6 = 3.0s in the lower right.
Every cut subtracts. The overlap is real time removed from the finished video. Six half-second cuts cost three seconds, and the renderer fills the gap with black rather than complaining.
A dark chalkboard showing four upright blocks in a row of increasing width, the first three outlined in white chalk and labelled 8s, 10s and 15s, the fourth outlined in gold with a white chalk X drawn across it and labelled 6.3s.
You cannot ask for the length you are missing. Generated clips come in fixed native sizes, so hitting a target is a small search over shot counts rather than a subtraction.

What it will tell you it cannot do

  • It renders nothing. It decides and composes. Generation goes to media-generator, screen capture to a recorder, compositing to the renderer. This produces the one document all three read.
  • No duration solver ships in v0.1.0. The procedure for hitting a stubborn target is written down, but you run it. A 45-second target has exactly one solution in the space, and a person will not find it by trial and error.
  • Tutorial pacing is not gated. The tutorial recipe is reasoned from first principles, because the prompt corpus is short-form only and holds zero tutorial prior art. Its structure is checked; its rhythm has no exemplars to be graded against.
  • Captions and background music do not currently arrive. The receiving worker forwards them untranslated, so they are stripped. The shot list emits them anyway and never claims they work.
  • Music does not duck under the voiceover. The field is declared three times and read zero times; two renders that differ only in that setting are byte-identical.
  • It will not guess the mode. Nothing in a script says whether a row is a shot or a whole post. If you did not say, it asks rather than assumes.
Why this exists

I got tired of renders that succeeded and were still wrong.

video-director is one skill in the system behind Di-Atomic — the marketing and compliance agency that runs cognitoAI, SpiderIQ and OPVS. If you want video produced on a pipeline that checks its own arithmetic, in any of our seven languages and including regulated categories, that is the day job.

Book a 30-min call with Di-Atomic

Just want the skill? Get @di-atomic/video-director free.