Case study
Riff — AI growth triage
Paste a raw growth idea — a tweet, a Discord message, a news link, a half-formed thought — and Riff hands back a finished marketing brief: classified, measured, planned, and drafted, in seconds. No forms, no project board. You just describe the idea.
Leading indicators
Impressions · engagement rate · watch-through %
North-Star metric
Sign-ups from UTM’d links → activated users
First draft
v2 ships today. Here’s the 60-second tour of what changed — and why your build times just dropped…
The problem
Growth teams at developer-tools companies drown in ideas. They arrive constantly and from everywhere — a founder’s tweet, a Discord message, an AI-news headline, a “we should blog about this.” They pile up and get lost, and the few that survive still need someone to answer the same questions every time: Is this worth doing? For which audience? How would we even measure it? — and then actually write the first draft.
That triage-and-first-draft work is the real bottleneck between “good idea” and “shipped.” Most tools attack the wrong end of it: they give you another board to maintain, not the work itself.
The core design decision
The output is a brief, not a database row. Riff doesn’t try to be a project manager or a CMS. It produces the one artifact a marketer actually needs to act on: a structured brief that says what this is, who it’s for, how you’ll know it worked, the plan to ship it, and a first draft — rendered right in the app, with one-tap Copy brief (as markdown) so it can live wherever the team already works.
This one decision — the brief is the product — is what kept the tool from sprawling into yet another system nobody adopts. The intelligence lives in the triage and the writing, not in a destination.
The clever part: metrics that are conditional on marketing type
A brief is only useful if it answers “how would we know this is working?” — and the honest answer is that you can’t measure an event the way you measure a tweet. So the AI first classifies each idea into a marketing type, then — conditional on that type — selects the metrics that actually apply:
| Marketing type | Leading indicator (know early) | North-Star metric (the real win) |
|---|---|---|
| Events | registrations, check-ins | attributed sign-ups → activated users |
| Social & Video | impressions, engagement rate, watch-through % | sign-ups from UTM’d links |
| Content | pageviews, read-through, repo stars | organic sign-ups + activated developers |
| Community | new members, messages per active member | paid conversions from the community |
Every North-Star metric ladders to the same real goal — activated, paying users — while vanity metrics (impressions, follower counts) are explicitly tagged as leading indicators, never goals. That leading-vs-lagging split is the whole answer to “are we on the right track?”: the leading indicators go green first, days before the outcome lands.
AI-native architecture (not AI-bolted-on)
The interesting engineering is in how the model is used — structurally and sparingly, not as a magic black box:
- Structured outputs for the classification. A raw idea → a strict JSON schema (category, funnel stage, effort, marketing type, the three metrics, a goal, a plan) using the model’s structured-output mode — so a live demo can’t produce a malformed classification on stage.
- The AI selects from a taxonomy; it doesn’t invent one. The metrics framework — which leading indicator and North-Star metric belong to which marketing type — lives in plain, unit-friendly TypeScript. The model chooses from that catalog and tailors the specifics to the idea. Judgment where it’s needed; deterministic structure where it isn’t.
- Right-sized model calls. One call classifies (fast, low reasoning effort); a second drafts the actual asset (more effort). Nothing more.
- A single shared vocabulary. Categories, formats, funnel stages, KPIs, audience voices, and the per-type metrics all live in one taxonomy module that drives the prompt, the output schema, and the UI at once — so the whole app stays internally consistent from one edit.
- House-style enforced on every draft. A voice layer (developer audience, concrete over hype, no claims beyond the source, a banned-hype-word list) is injected into every drafting prompt, with two audience registers (accessible/dev-first vs deep/technical). Designed so a memory layer could later learn each writer’s real voice.
Engineering notes
- Shape: Next.js 16 (App Router; middleware is now
proxy.ts) + React 19 — one page, one API route (/api/submitdoes classify → draft server-side). - Security: the Anthropic API key never leaves the server; the browser only ever calls
/api/submit. A password gate (proxy.ts) fronts the whole app. - No database by design: each brief is a live session artifact, and the Copy-brief export means the output lives wherever the user wants — not locked inside the tool.
- Ships continuously: push to
main→ Vercel auto-deploys.
How it was built
The whole thing was designed and built through conversational iteration with an AI coding agent (Claude Code) — and the iteration is itself the interesting part:
- Cutting scope was the design work. It started as a Notion-style Kanban board with a dense sortable table, inline editing, and an export button — and each round of “this is too much” removed something: the board, then a spreadsheet backend, then a Notion integration, then the sheet again. The clarifying realization was that the destination never mattered; the brief did. The final product is smaller than the first version and far stronger for it.
- Product judgment stayed human. The decisions that mattered — kill the board, make the brief the deliverable, keep the metrics conditional on marketing type, keep the AI out of the taxonomy, ship a self-contained app instead of an integration — were product calls made through the work, with the agent as an extremely fast implementer and thinking partner.
It’s a working demonstration of building a real, shipped product with AI as the development environment — and of using AI deliberately inside the product, only where it earns its place.
What’s next
A memory layer so drafts learn each writer’s voice over time (the “learns your team’s voice” the app already gestures at), and an optional one-click push of a finished brief into whatever tracker a team already uses — kept deliberately as an export, never a lock-in.
Try the live demo — or email me for the password.