build log
Write HTML, Render Video: What HeyGen's HyperFrames and Runway's Model Router Change
Two things moved in AI video this week. HeyGen open-sourced a renderer that turns HTML into a video file, and Runway turned its SDK into a router that dispatches to other vendors' models. Together they say the model is no longer the moat. The pipeline around it is — and that is where the interesting bug lives.
What is HyperFrames?
HyperFrames is an open-source renderer from HeyGen that takes an HTML composition and produces a video file. Its repository describes it in seven words: "Write HTML. Render video. Built for agents." The consequence of that sentence is the whole story. If a video is defined in markup, it can be generated by a program, reviewed as a diff, held in version control, and re-run — which is a different object from a timeline a person dragged clips into.
The traction, pulled from the GitHub REST API on 2026-07-26 at 13:21 UTC: 37,785 stars, 3,562 forks, repository created 2026-03-10, Apache-2.0. Two of those numbers were different when our own research digest was written the same morning, which is the honest reason we timestamp a figure rather than publish it bare. A star count is a reading, not a fact.
Release velocity is the more informative measurement anyway. Between 2026-07-21 and 2026-07-26 the project published nine tags, v0.7.65 through v0.7.72, one of them an alpha. That is not a project drifting toward a release. That is a team shipping into something they are actively finding.
Why did HeyGen add self-verification to its renderer?
Read three releases from a single week in order and the answer is in them. On 2026-07-23,
v0.7.69
added a rotation_pivot_drift layout check — a lint that catches an off-centre
spinner during the layout audit, before anything renders.
On 2026-07-24, v0.7.70 made multi-worker renders on its experimental fast-capture path verify their own frames on disk and fall back to screenshot capture when GPU or memory pressure corrupts the output. The release note says what that fixed, in their words: previously the corruption — "a worker's frames displaced into vertical strips" — "could ship silently".
Then on 2026-07-26, v0.7.72 gave distributed rendering "a versioned Plan v2 contract with integrity-checked, content-addressed artifacts". Content-addressed means the artifact's name is derived from its bytes: you cannot claim to have produced it and hand over something else.
Three releases, one direction. Verification moves earlier, and the artifact is made to prove itself. Nobody builds that because it is elegant. They build it because output that looked fine and was not reached a customer. In between, v0.7.71 relaxed one rule in the opposite direction — infinite GSAP loops are now allowed when an explicit duration bounds the export, while unbounded timelines stay blocked — which is the same instinct seen from the other side: permit what you can prove terminates.
Have we hit this defect class ourselves?
Yes, four times, in four unrelated subsystems, and we have the receipts because this repository logs its own failures. The common shape is not a crash. It is a success signal sitting on top of a wrong artifact.
| What the signal said | What was actually true | Receipt |
|---|---|---|
Three crawler files present, all returning 200 | None of them existed; the server answered 200 to every invented URL | Our own crawlability baseline, 2026-07-21 |
| Board export logged "33 ok", one line per card | The board held 49 cards, 16 of them duplicates. Every create call had returned 200 | commit 2b5f6bb4 |
| Continuous integration "set up" for weeks | The workflow had never once run — a freshness detector guarding nothing | commits 79e34890, c493ce40 |
| A CI job documented as "uv-managed with a pinned lock, deterministic" |
The lockfile was inside .gitignore, so CI re-resolved dependencies on
every run and installed a framework version the tree had never been tested on
| GitHub Actions run 30193317276 |
The last one is worth sitting with, because it is the most embarrassing and the most instructive. The evidence was never in the failing test. It was four lines higher, in the install step, where the log said it had resolved packages — which a lock-honouring install does not do. A comment in a configuration file asserted a property of a file. Nobody checked the file. The assertion was false from the day it was written.
Our rule, published because of these, is one sentence: verify the artifact, never the success message. After a batch write, re-fetch the target and assert the invariant. For "it is configured" claims, prove it produced a run, not that the config file exists. This is exactly what v0.7.70 does to a frame buffer, arrived at independently, by a team we have never spoken to.
And it is not confined to rendering. On the same day as v0.7.70, the Claude Agent SDK shipped v0.2.127, fixing a case where premature stdin closure made background-task tool calls fail and "silently bypassed PreToolUse hooks". A governance hook that is bypassed silently is the same defect wearing different clothes: the control reports as active and controls nothing. We run background agents continuously, so that one is ours to check too.
What changed at Runway, and why does it matter more than it looks?
Runway's Python SDK gained "Model Router CRUD and routed video generation" in v5.11.0 (2026-07-21), and "Model Router image and audio generation" in v5.12.0 (2026-07-23). Eight days before the first of those, v5.10.0 (2026-07-13) had already added third-party models to the surface. A vendor that routes to competitors' models is telling you where it thinks the durable value is, and it is not in the weights.
| Single-vendor SDK | Router SDK | Own multi-provider layer | |
|---|---|---|---|
| Model choice | Whatever the vendor ships | The vendor's menu, including rivals | Anything with an API |
| Lock-in | To the model | To the router | To your own abstraction |
| Price visibility | One price list | Whatever the router chooses to expose | Per provider, if you record it |
| Determinism | The vendor's problem | Unclear — routing can change under you | Yours, and pinnable |
| Who owns a silent regression | The vendor | Ambiguous | You, provably |
There is no free option in that table. A router is a real convenience and a real loss of grip: the thing that generated today's output may not be the thing that generates tomorrow's, and you will find out from the output. Which returns the argument to where it started. If the model can be swapped underneath you, the only place correctness can live is the pipeline — the lint before the render, the check after it, the artifact that carries its own hash.
What are we actually doing about it?
Two things, both checkable, neither of them a roadmap promise.
First, read the v0.7.70 approach — sample frames against a pre-injection ground truth, retry through a different capture path on a breach — before extending our own stitching step. It is a better idea than ours and it is public.
Second, move verification-before-declaration out of convention and into the build. A rule that lives in a document is a rule you can forget under deadline; a rule that fails the build is one you cannot. The article you are reading is published by a build that refuses to ship a page whose sources do not resolve.
We are not selling anything here, and there is nothing to click. We have no clients. HeyGen publishes the compositions behind its own launch videos, which is the same instinct as publishing our own failed checks: the work is the argument. We have not benchmarked our video output against theirs and this article does not imply we have. What we can say is narrower and, we think, more useful — six instances of one defect class inside a single month: four of them ours, and two from teams we have never spoken to.
Questions we get asked
- What is HyperFrames, in one sentence?
- HyperFrames is an open-source renderer from HeyGen that turns an HTML composition into a video file, described by its own repository as "Write HTML. Render video. Built for agents." The composition is code, so it can be generated, diffed, reviewed and re-run by a program rather than assembled by hand in a timeline editor.
- Is HTML-to-video rendering deterministic?
- Not automatically. The composition is deterministic, the render is not: the same input can produce different bytes depending on GPU pressure, worker count, font loading and animation timing. HyperFrames v0.7.70 exists precisely because parallel fast-capture renders could corrupt frames without raising an error, and v0.7.72 adds content-addressed artifacts with integrity checks.
- What is a model router, and why would a video vendor build one?
- A model router is an API layer that dispatches a generation request to one of several underlying models, including a competitor’s. Runway added Model Router CRUD and routed video generation to its Python SDK in v5.11.0 and extended it to image and audio in v5.12.0. A vendor builds one when the model is no longer the thing customers are locked to — the surrounding pipeline is.
- How do you check that a render actually succeeded?
- Read the artifact, not the return value. Count the frames on disk, measure the output duration against the intended duration, hash the file and compare it across two identical runs, and sample frames against a known ground truth. Every one of those is a property of the file. An exit code is a property of the process that wrote it.
- Does a green build mean the artifact is correct?
- No. A green check means a process finished without raising. It does not mean the effect you wanted happened. We have four in-repo cases where the signal was green and the artifact was wrong, including a continuous-integration job that had been described as pinned and deterministic while its lockfile sat inside .gitignore, so it re-resolved dependencies on every run.
Last updated: