Sequences for Slack — Project Story
The spark
Every launch dies the same quiet death. Someone writes a great release brief in a Slack channel — the feature, the why, the one number that matters — and then nothing moves. A launch video would be perfect, but making one means exporting the brief, briefing a designer, waiting two days, and by then the moment's gone.
So the idea was simple: what if the brief never had to leave Slack? You type /sequences, describe the launch, and a real animated MP4 shows up in the channel a minute later. The channel is the studio.
The catch is that "AI makes a video" usually means a video that looks like AI made it — floaty easing, text drifting while you read it, five things moving and none meaning anything. I didn't want a slot machine. I wanted taste.
How it's built
Sequences is a Bolt + Socket Mode app in TypeScript, but the interesting part is the split-brain design. Two separate intelligences, kept strictly apart:
- A context bot that only gathers truth — OpenAI's Responses API through Slack's hosted MCP, acting as the user who invoked it. It reads the channel, pulls real facts, and never touches a pixel.
- Luna (
gpt-5.6-luna, high reasoning), the author. It owns concept, art direction, camera, motion, and pacing, and returns the film as HTML/CSS/SVG plus a paused, seekable animation timeline.
The rule that became the whole architecture:
Luna owns taste. The host owns truth.
A run is an assembly line where each stage distrusts the last: the host builds a hashed, permission-scoped fact envelope; Luna returns a single schema-constrained bundle; the host re-validates from scratch in a real headless browser, then renders — thumbnails first, MP4 moments later.
The film is a seekable timeline, not a pre-baked video, because the render is a pure function of time. Frame $i$ is just
$$t_i = \frac{i}{\text{fps}}, \qquad \text{frame}_i = f(t_i),$$
and the host proves in a browser that seeking to the same $t$ always gives the same result — which is what lets me sample clean frames and catch a broken animation before paying for an encode.
What I learned
- A green report is not a good video. You can't unit-test taste — you have to look at the frames. So I built a hand-authored golden demo as the bar and measured against it, not against a passing JSON blob.
- Motion has grammar. A gesture wants anticipation → action → settle → hold; a film gets exactly one energy peak; copy holds still while it's meant to be read. I encoded these as advisories Luna could see, not rules that overwrote its choices.
- Security forces good design. The worker's infra denies the sandbox the model's tools need, so Luna runs completely tool-less — evidence in, one envelope out, any tool event is a hard failure. The wall became the cleanest trust boundary in the system.
The challenges
- Author, not committee. An earlier version was a pipeline of models — planner, normalizer, critic, repair ladder — and it felt designed by committee, because it was. Collapsing it into one Luna thread that owns the whole arc was a scary rewrite.
- Never hide a real defect. The tempting failure mode is papering over a bug by bumping retries or softening a gate. My hard rule: preserve the rejected artifact, reproduce it without a model call, fix the lowest layer, add a regression test.
- Slack is a harsh room. Background work can't crash the process, media needs the right upload path, private channels need an invite, user content must be escaped. A hundred unglamorous details separate "works on my machine" from "works in someone's workspace."
Where it landed
You describe a launch in a channel, and a genuinely watchable, intentional film shows up next to it — grounded in your real facts and reproducible frame-for-frame. The brief never had to leave the room.
That's the whole thing. Kill the gap between shipping something and showing it.
Built With
- bolt-for-javascript
- css
- docker
- html
- hyperframes
- javascript
- railway
- slack-block-kit
- typescript


Log in or sign up for Devpost to join the conversation.