Video Engine (HyperFrames)
RoboCo can author and post short marketing videos for the company's X (Twitter) and TikTok accounts — a release announcement, a feature spotlight, or an on-demand CEO request — voiced as the Head of Marketing and rendered by a credential-free video-renderer sidecar (HyperFrames). It never posts anything on its own: every clip is held in the Video Post Queue on the panel's Social page for you to preview, edit, approve, or reject.
The engine is off by default, and even armed it does nothing until the authoring task completes, the render sidecar returns MP4s, and you approve the held draft.
What it does
Three independent triggers feed the same authoring → render → held-draft pipeline:
- Release videos are event-driven: a release publish fires the video-on-release trigger — gated by
ROBOCO_VIDEO_ON_RELEASEindependently of the master switch. - Feature-spotlight videos fire when the CEO approves a feature-spotlight draft that requests one — gated by
ROBOCO_VIDEO_ON_SPOTLIGHT. - On-demand is the CEO's escape hatch:
POST /api/video/requestopens an authoring task directly, independent of the two automatic triggers. - Authoring is a normal, assigned UX/UI task (balanced across the two ux-devs), not a held draft — the dev builds a HyperFrames HTML composition under
motion/compositions/<id>/(onevertical.html+ onesquare.htmlcarrying the render params), proposes its composition id + per-platform captions via the team-gatedpropose_videodo-tool, and ships it through the standard commit/PR/QA/doc/review lifecycle. - The render loop (
ROBOCO_VIDEO_RENDER_INTERVAL_SECONDS) tars the mergedmotion/source and POSTs it to a credential-freevideo-renderersidecar, which renders both the 9:16 and 1:1 MP4 cuts via HyperFrames (agent-authored HTML in headless Chrome + systemffmpeg) and streams the bytes back. MP4s persist underROBOCO_VIDEO_OUTPUT_DIR(bind-mounted in all three compose files so renders survive container recreation) — the sidecar never writes to disk. - The held draft is owned by the Secretary (
confirmed_by_human=False), the same held-artifact pattern the X engine uses — skipped by every dispatcher, acted on only through the CEO's approve/reject. - Posting is idempotent — approving an already-posted draft is a no-op, never a double-post.
Even fully armed, a clip sits in the queue until you explicitly approve it — optionally editing the per-platform captions first.
Rejecting with a reason re-authors the composition
Rejecting a draft always cancels it — it's never posted. But a non-blank rejection reason opens a fresh authoring task (best-effort, never fails the reject itself) that carries your feedback verbatim plus a pointer to revise the existing composition in place, rather than starting from a blank brief. A blank rejection is a plain cancel with no follow-up. This is the same reject-with-feedback shape the X engine uses for its own held drafts.
The panel-demo kit
Compositions aren't limited to text cards. The in-repo motion/kit/ ships a reusable, pk--namespaced set of building blocks that recreate the control panel itself inside a HyperFrames composition — frame chrome, a task card, status pills with an enter/exit swap, team/priority chips, a notification toast, a character-by-character typing reveal with a blinking caret, and a cursor sprite with a click pulse. Its color tokens are lifted straight from the panel's own dark theme, so kit output reads as the real product rather than an approximation of it.
The kit ships with a reference composition, panel-demo (12s, both cuts): a task title types into the intake box, the card materializes, the cursor glides in and clicks, the status pill flips to completed, and a toast slides in. It's the demo register — a UX/UI dev authoring a video can now simulate an actual product interaction instead of defaulting to a text card. Authoring guidance for the kit lives in motion/kit/README.md; the project-wide composition design bar is in motion/README.md.
Authoring quality is held to a catalog-grade design bar: motion/README.md carries spacing, pacing, and anti-generic-tells rules grounded in vendored HyperFrames craft references, backed by an in-repo catalog vocabulary index the dev checks before inventing a new visual pattern. You don't author videos yourself, so none of this changes what you see in the queue — it's quality bar for the devs building the compositions.
Bounds on origination
| Setting | Default | Meaning |
|---|---|---|
ROBOCO_VIDEO_MAX_OPEN_POSTS | 5 | Rolling cap on concurrently-open video tasks (authoring plus held post drafts combined); the engine opens nothing more past it. |
ROBOCO_VIDEO_RENDER_INTERVAL_SECONDS | 120 | Seconds between render-loop passes (scans completed authoring tasks with an unrendered composition). |
ROBOCO_VIDEO_RENDER_TIMEOUT_SECONDS | 600 | Deadline for one render pass on the sidecar. |
ROBOCO_VIDEO_REQUEST_TIMEOUT_SECONDS | 30 | Per-request timeout for outbound video-engine HTTP calls. |
Required configuration
| Setting | Where it lives | Notes |
|---|---|---|
ROBOCO_VIDEO_ENGINE_ENABLED | Environment / panel flag | Master switch. Off ⇒ no authoring task is ever opened. |
ROBOCO_VIDEO_ON_RELEASE | Environment / panel flag | Sub-switch for the release-publish trigger. |
ROBOCO_VIDEO_ON_SPOTLIGHT | Environment / panel flag | Sub-switch for the feature-spotlight trigger. |
ROBOCO_VIDEO_RENDERER_BASE_URL | Environment (default http://roboco-video-renderer:3001) | Base URL of the video-renderer sidecar. |
ROBOCO_VIDEO_OUTPUT_DIR | Environment (default /data/video-renders) | Where rendered MP4s are written. Bind-mounted in all three compose files. |
| TikTok OAuth2 secrets | Settings → TikTok Credentials card in the panel | Fernet-encrypted at rest, alongside the existing X credentials. Write-only. |
TikTok's OAuth2 secrets are never read from environment variables — they live only in the database, encrypted the same way a project's git token is. Set them from Settings → TikTok Credentials. X credentials (if you want videos posted to X) are the same four OAuth 1.0a secrets the X engine already uses.
Enable it
Settings → Feature Flags carries "Video engine", plus the two sub-switches "Video on release" and "Video on spotlight". Then scroll to the TikTok Credentials card (same Settings page) and enter the OAuth2 secrets; the X engine's existing credentials card covers the X side.
The feature flags persist in the settings store and apply on the next backend restart. Credentials take effect as soon as they're saved — no restart needed for those.
See the environment reference for the full flag list.
What changes when it's on
- A release publish, an approved spotlight that requests a video, or the CEO's on-demand
POST /api/video/requestopens an assigned UX/UI authoring task that builds amotion/composition. - Once the authoring task completes, the render loop renders the 9:16 and 1:1 MP4 cuts and materializes a held
video_postdraft, visible in the Video Post Queue on the Social page with a 9:16/1:1 cut switch. - The CEO previews (an authenticated blob fetch that carries
X-Agent-ID/X-Agent-Role), edits, approves, or rejects each draft. Approving posts the selected cut to X (native video) and/or TikTok (inbox upload) under a heartbeat-renewed lock. - With no TikTok credentials stored, the TikTok leg is a no-op; with no X credentials, the X leg is a no-op; with no sidecar reachable, the render loop degrades gracefully. Every unconfigured leg is a no-op, never a crash.
Next
→ X (Twitter) engine — the held-draft marketing engine this mirrors and extends. → Social — where the Video Post Queue and on-demand request live. → Settings — where the TikTok credentials card lives. → back to Optional subsystems.