Stories A told story · drafted 2026-10-13
Video generation
Every group makes its own video where its work is made, true in every frame, and a person publishes it.
The seven beats
- World
- the group one, and every group that ships work it cannot yet show moving
- Cast
- a founder with taste and no motion designer; the agent that builds the shot; the person who decides it goes out
- Knock
- a list of links and a transcript of a man who made a studio-grade brand video without a studio
- Want
- a video made where the work is made, true in every frame, handed to a person to publish
- Way
- parts copied in rather than rented; references learned, never copied; every render checked by looking at its frames
- Turn
- the first file existed and was wrong: a frame nobody had looked at made a claim the command would never print
- Lesson
- Open — learned by someone, not written yet
Nine seconds in, the frame was a single green line.
The file existed. It was eighteen seconds long, the right width, the right rate. A check that only asked whether the video was there would have passed it.
The knock had come that morning as a list of links and a transcript.
In the transcript a data engineer explains how he made a brand video without being able to pay anyone to make one. His first attempt looked, in his own word, awful. His later ones looked like the work of a studio. Between the two sat four days of trial and error, a habit of cutting the reference into five-second pieces, a sheet of stills that let a model see motion it could not watch, and two judges who would not let a segment pass below nine out of ten.
The group that read it had the same problem in a different shape. It ships most weeks. Most weeks went by without a single moving picture to show for it.
A motion designer was not on the payroll. A coding agent was.
So the want was plain. A group should be able to make its own video in the same place it makes its own work, and hand the result to a person to publish.
The way was assembled from parts other people had already polished. Four hundred small animations from one library. Twenty-one demonstration shots from another: a terminal that types, a phone that rises out of the dark, a ring of pictures that folds into a mark.
None of them was installed as a dependency. Each was copied in, so the group owns the code the way it owns its pages, and can change one colour without asking anyone.
Two libraries were left on the shelf. One carried a licence that would have obliged the whole site to publish its source. The other carried no licence at all, which means every right is reserved, however public the repository looks.
The first render took a few minutes.
Then the frames were pulled out and looked at, one by one. The title traced in cleanly. The terminal had been given too few seconds, so its camera was still in flight when the scene ended. The mark, inverted by a filter meant to make it visible, had become a dark coin on a dark ground. And the terminal announced that a draft post was ready, when the command it showed would have printed something else entirely.
That was the turn.
A video is a set of claims, made one frame at a time, and a claim can be false in a frame nobody looked at. The group already kept one rule for money and for keys: a thing is done when it has been checked by running it. The rule had simply not been carried across to pictures.
The second version opened on the mark poured in liquid metal.
Every line on screen was taken from the group's own public pages that afternoon. Every number was read off the live site, not remembered. One page was left out of the reel because it showed the names of clients, and a client's name is not decoration.
The agent built it. The agent rendered it. The agent did not post it.
Publishing is consent, and consent belongs to a person.
The renderer had one more condition, and it was written in a licence rather than in code. Free for one person, free for a small company, and past three employees, owed.
So the group went looking for a second renderer, and found one that asked for nothing: a single open licence, no fee for a frame, and a shape it already knew. A scene was a page of markup. Its timing sat in attributes, and its motion in one paused timeline. Four hundred and forty-seven finished scenes came with it, and each was copied in the same way as before.
Then the next idea arrived, and it was about the site, not the film. If a scene is only a page, it can sit inside a page. And if the page around it changes while the scene keeps going, the site stops looking like a set of separate rooms.
It nearly did not work. The scene's player rebuilt itself whenever the browser moved it, so the animation went back to zero at every click. One empty method taught it that a move is not a departure. After that the orange dot crossed the screen, a link was clicked, a different page arrived, and the dot did not stop.
The green line is still in the frame. Now the words beside it are true.
Where the metaphor stops being true
The story says "the group" where the code says the one group, and uses only the locked words: group, people and agents, signal, path. No dead names appear.
- "Handed to a person to publish" is true of the key, not of the page. A key writes drafts only (
/api/social/postsrefusesscheduledAtandstatusfrom a key). A signed-in person can still publish directly. That is the design, not a gap. - "Checked by looking at its frames" was done by hand on 2026-10-13: frames extracted with
npx remotion ffmpegand read one at a time. No script enforces it yet. It is a habit, not a gate. - "A sheet of stills that let a model see motion" is the masterclass's method. It has not been built here. The recreation loop (segment, contact sheet, video-capable model, two judges) is not wired anywhere in this repo.
- Video is not a signal yet.
media:uploadrefuses video (packages/cli/src/media.ts). The upload goes throughPUT /api/media/video-upload, a route rather than a receiver, so no path is marked when a video is made or published. - "Four hundred animations" counts remocn's registry (400 items, read 2026-10-13). Not every item is a component: some are templates, icons and shader presets.
- "A renderer that asked for nothing" is true of the HyperFrames code (Apache 2.0). It is not yet true of the 447 catalog items: the registry states no licence for them, and the bundled third-party files carry their own.
- "Four hundred and forty-seven finished scenes" were all imported (447 of 447, 0 failed, 54 MB, gitignored and regenerable by
video/library/install-hyperframes-library.sh, which has not been run end to end). Of them, 329 load a remote script or font (jsDelivr, Google Fonts), so a render needs network access. Only the blank scaffold has been rendered (h264, 1920×1080, 10.0 s); no catalog scene has had its frames looked at. - "The dot did not stop" was measured on two prerendered demo pages and nowhere else. The stage is not in
Layout.astro. The no-opconnectedMoveCallbackworks because Chrome 133+ moves a persisted node withmoveBefore(); with that removed in a forced test the player reloads and a saved-time hand-off resumes it within about 0.2 s after a 200–270 ms blank gap. Safari and Firefox were not tested. A Puck page cannot carry a persisted player: its body is a client-only island with no server HTML to match. - "The page around it changes" is Astro's
ClientRouterplustransition:persist; HyperFrames contributes a timeline that survives being moved. Theclient:*directives do not hydrate a custom element, so idle and visible timing is reproduced by hand withrequestIdleCallbackandIntersectionObserver. - "A URL becomes a video page" is the
URL to Videoworkflow, and it is a draft. The render service it calls does not exist yet.
The family this story generates
| File | Technology | What it holds |
|---|---|---|
text/video-generation.md |
the story | this file |
apps/vespio/video/ |
Remotion + HyperFrames project | the Remotion compositions (OneShowcase, MakeItShipIt) and component library in src/; the HyperFrames scaffold in hyperframes/ (the 447 items are gitignored) |
apps/vespio/video/README.md · CLAUDE.md |
reference | stack, licences, when to pick which engine, the gotchas measured while building |
apps/vespio/video/library/ |
catalogs and scripts | CATALOG.md (Remotion, 560 items), HYPERFRAMES-CATALOG.md (447), hf-to-puck.mjs → hf-puck-fields.json (composition variables as Puck fields), install-hyperframes-library.sh |
one.ie/ai/skills/video/SKILL.md |
a skill | how to make a video without lying. Rewritten on 2026-10-13 to the real HyperFrames CLI and composition format (PR #386); copied by hand to apps/vespio/.claude/skills/video/, which vespio-sync.sh does not carry |
one.ie/web/src/components/hf/ · src/lib/hf/ · src/pages/demo/hf-{a,b}.astro |
Astro | the persistent player and its two demo pages (PR #389) |
workflow URL to Video |
a flow | url → crawl → composition variables → render → draft page → approve → publish. Draft, not runnable |
.claude/skills/distribute/ |
a skill | the hand-off: upload, draft, a person publishes |
Sentences that would be false if shipped
- "ONE posts your video for you." A key drafts; a person publishes.
- "Your video runs as an ad." Every ad pusher calls a Composio action that returns 404. No ad has been placed.
- "Upload any video with media:upload." That receiver refuses video by design.
- "The agent watches your reference video." This coding agent reads images, not video. The masterclass used a video-capable model and contact sheets, and neither is built here.
- "Recreate any brand video." References are for learning motion. A copy of someone else's video is never published.
- "Free to use commercially." The Remotion renderer is free only up to three employees. Above that, a Company License is owed. HyperFrames has no such threshold, but its catalog items have no stated licence.
- "Paste a URL and get a video." The workflow is a draft and its render step has no service behind it.
- "Every page of your site keeps the animation running." Two demo pages do. The layout does not carry it yet, and a Puck page cannot.
The story shape — the chain, and the three rules
This section is defined once, in text/template-story.md § The story shape. This story keeps that definition and does not restate it.
Connected to
Every link here was checked against the repo when the page was built. 6 names the story uses could not be found and are shown without a link.
People
- tony
- donal
Agents
Each opens a chat with that agent.
Skills
Each opens the skill's page.
- video
- distribute
- storytelling
Paths
The flows this story walks — trigger → step → step.
- trigger: a brief → agent: animator composes the scenes → tool: render → condition: frames extracted and looked at → human: brand review → tool: upload as a draft post → human: a person publishes
- URL to Video (id 01a132606deb4a05a060f638, trigger video:from-url, status draft): web:crawl → agent designer writes the composition variables → endpoint:call hyperframes-render → pages:create → human approve → pages:publish → chat:send. VERIFY: not runnable — no hyperframes-render endpoint is registered, the actor id designer is unchecked, and the $step…json.videoUrl path has never been read back
Tools
Receivers and scripts it signals.
- apps/vespio/video (git repo apps/vespio, github.com/one-ie/vespio) — two engines: Remotion compositions in src/, HyperFrames compositions in hyperframes/
- remocn and snapcn registries, installed with the shadcn CLI
- remotion render · remotion still · remotion ffprobe
- hyperframes init · catalog · add · check · preview · render · doctor · capture <url> — eight packages pinned exactly at 0.8.150; FFmpeg 9.0.2 installed and doctor green on this machine
- one.ie/web/src/components/hf/HfStage.astro + src/lib/hf/{stage,player}.ts — a persisted <one-hf-stage> whose player keeps playing across ClientRouter navigation; demo at /demo/hf-a and /demo/hf-b (PR #389, dev ce8981411)
- one media upload <file> --post "<caption>" — PUT /api/media/video-upload, then a draft on /api/social/posts
Events
Every event is a signal; each names the path it marks or warns.
- VERIFY: none — media:upload refuses video (packages/cli/src/media.ts); the video door is a route, not a receiver · from the agent holding the group's key VERIFY: no path is marked when a video is drafted or published tags: video
Transactions
- none move today — rendering runs on the group's own machine
- VERIFY: the Remotion renderer's Company License is owed if the group has more than three employees (remotion.pro/license); how it treats rendering for clients and embedding the Player is not stated in the shipped LICENSE.md
- HyperFrames is Apache 2.0 with no per-render fee (LICENSE in @hyperframes/core, read 2026-10-13). New work defaults to it. VERIFY: the registry states no licence for its 447 catalog items; bundled third-party files carry their own — check before redistributing or selling one
Analytics
- VERIFY: nothing is counted yet — reach of a published post is not read back