Patterns and Riffs
Two product concepts that coexist in every pipeline:
- Pattern — the reusable structure the AI extracts from an input (hook, tone, format, triggers).
- Riff — the new draft the AI generates grounded in one or more patterns, in your voice, without copying content.
How is a pattern decoded?
When a pipeline processes an input (post, URL, paste), the chosen LLM extracts four dimensions:
| Dimension | What it captures | Example |
|---|---|---|
| hook | The opener's shape — what makes someone keep reading. | numbered-list + stake, contrarian opener, story-arc opener, question opener |
| tone | The author's voice. | confessional, operational, analytical, contrarian, narrative |
| format | The physical structure. | single post, 5-post thread, 2-post reply chain |
| triggers | Rhetorical / numeric elements that drive engagement. | dollar-amount, time-anchor, personal-loss, nobody-says-this |
These fields are persisted in the structured artifact and form the basis for riffing later.
How does riffing work?
A riff takes a pattern + the operator's input (voice profile, specific instructions) and generates prose in the operator's voice while respecting the pattern's structure.
It is not a copy. The LLM has explicit instructions to:
- Keep the shape of the hook (numbered, contrarian, etc.).
- Keep the tone within the requested range.
- Change content completely — topics, examples, metrics.
- Use the voice profile (operator's linguistic traits) if available.
Genealogy and refinement
Every artifact preserves its genealogical tree via parent_id. When you trigger a refinement (shorter, change_tone, etc.), a child artifact is created with:
parent_artifact
├── child_a · action=shorter
│ └── grandchild_a1 · action=change_tone (target=punchy)
└── child_b · action=match_voice
You can navigate the entire tree from the UI or by requesting the artifact://{id} resource via MCP.
Multi-source riff (synthesis) — roadmap
:::caution Roadmap
Today each riff takes one source post. The multi-source synthesis with citation markers described below is not implemented yet: in taxonomy.ts the multi-source combinations are marked as supported: false.
:::
Future idea: when a pipeline has multi-source, the riff will combine patterns from multiple inputs and generate a draft with citations:
Input 1: @growth_dr post about pricing
Input 2: @bootstrap_fi post about 4 decisions
Input 3: blog URL about pricing anatomy
→ "Most founders obsess over their pricing page [3]. The teams that
scaled fastest skipped them — until they couldn't [1] [2]…"
The [1] [2] [3] markers will reference each source's post_id / url. In the meantime, the only way to combine inputs is to trigger a brief with multiple source_post_ids (up to 50) from the Agent API, which synthesizes prose but without citation markers.
Voice model — roadmap
:::caution Roadmap
There is no persistent voice profile yet. The operator's voice enters today as style_reference (free text, ≤4000 chars) that the agent passes explicitly on every call to the MCP tool start_draft or on every match_voice refinement. There is no Settings → Voice UI nor an API endpoint to save the profile.
:::
The product intent is to support a voice profile per operator with:
- Samples of the operator's own text (3–10 paragraphs).
- Opt-in traits: do you use contractions? Swear words? First-person plural?
- Default preferred tones per pipeline.
Meanwhile, the recommended pattern is to keep your voice samples in a local file (or in an agent memory you have at hand) and pass them as style_reference when you trigger a draft.
Edit and publish
After generation, the operator can:
- Accept the draft as-is (
publish_artifact). - Edit it inline (override
final_text). - Trigger a refinement for a child variant.
- Archive it without publishing.
Any publication requires human confirmation — Whet does not auto-publish.
See also
- Pipelines — the container that defines which sources feed riffs.
- Operators — the role that operates refinement loops and publishing.
- MCP · refine_post — the prompt template that guides refinement via agents.