Concepts¶
The ideas that shape Keryx, and the reasoning behind each.
Why the authoring loop is human-in-the-loop¶
A reel is built in stages that iterate independently: distil the post into a storyboard, render a silent draft to check pacing, generate voice, generate music, generate card art, assemble, then compose the social copy.
The stages are separate because generation is non-deterministic and expensive. A voice-over take that reads a word wrong, an illustration with a stray letter in it, a music bed that fights the narration — each is a small fix, and each would be prohibitively slow if fixing it meant regenerating the whole reel. So every stage produces N candidate takes and you promote one; the promoted take is the committed input the assembly consumes, and re-rolling one line leaves every other selection untouched.
That is also why nothing auto-publishes. Taste is the point of the loop, and a generated artefact that nobody looked at is not something you want on a public account.
Why the storyboard is the single creative seed¶
The storyboard is an ordered JSON array of cards, and it is the only file that
describes what the reel says. Each card carries the on-screen text, a separate vo
narration, palette roles, an optional scene prompt for generated art, and resolved
media.
Keeping the on-screen words and the narration as separate fields is deliberate. On screen you want a tight distillation that reads in two seconds; spoken you want a fuller sentence, possibly with pauses and phonetic respellings the renderer must never draw. Collapsing them into one field would force one of the two to be wrong.
Why themes are configuration rather than code¶
Palette, fonts, card treatment, illustration style, music tone and voice settings all live in configuration, identified by a keyword.
Two things follow from that, and both were the reason. A run of reels sharing one hard coded look is monotonous, and varying it should not require a release. And a second brand — or somebody else's project entirely — should be new configuration, not a fork.
It is also why no themes ship in the binary. A style library baked into a reusable tool would mean every install inherits one project's taste, and changing that taste would mean cutting a release. So a fresh install has an empty catalog and says so.
→ Themes
Why every backend sits behind an interface¶
Image, video, voice, music and rendering each have a narrow Go interface, and the concrete adapter is chosen from configuration at construction. No call site names a vendor; requests carry Keryx's intent — a prompt and an aspect, narration text and clone settings, a timeline of segments — and each adapter maps that to its own API.
The immediate payoff is not vendor choice, which barely exists yet: it is testability.
Because every backend is an interface, the deterministic core — timing maths, text
wrapping, theme resolution, the posting ledger — is unit-tested with no network, no
ffmpeg and no API keys.
Why posting has an approval gate¶
Each platform's social set moves draft → approved → posted, with an optional
schedule per outlet. Posting refuses anything not approved.
This exists because the unattended path is real: a scheduled CI pipeline runs
keryx post due with credentials, on its own. Without an explicit human approval
recorded in the repo, a mistake in a storyboard becomes a public post nobody chose to
make. Approval is the point where a person takes responsibility, and it is recorded in
git alongside what was approved.
Why Keryx keeps no state of its own¶
There is no Keryx database, no per-project cache outside the workspace, and no server. The owning project's git repo is the store, and it is also the concurrency boundary: two people editing the same reel conflict the way two people editing the same file conflict, with a tool they already know.
The cost is that large media in git is awkward, which is what the configurable object store is for — the workspace keeps the authored state and a manifest, and the blobs live in S3, GCS, Azure or a local directory.
The benefit is that a reel is reproducible from committed inputs. When every selected
asset is also locked, reel build says so, and that claim is checkable by anyone
with the repo.