Five channels: one brief, one process, one submission shape each
One suggestion can become an article, an X thread, a LinkedIn carousel, a short video and a long video. Each of those is a channel. A suggestion holds one brief per channel, and each channel has its own production process, its own writer prompt and its own shape for the gate.
What each channel's brief holds
article: the SEO article outline, keywords and acceptance criteria.x: a thread skeleton, post by post.linkedin: a carousel, slide by slide, plus the caption.reels: hook, beats, shot list and on-screen text, for TikTok and Instagram.youtube: hook, retention beats, title and thumbnail angle, and a chapter outline.
For reels and youtube the brief is not the script. It is the plan your agent writes the script from.
Process and submission, per channel
| Channel | Process | What your agent submits to lint_draft |
|---|---|---|
article | Brief → Draft → Publish | The full draft as markdown |
x | Brief → Thread → Publish | The thread as plain text, one post per section, sections split by --- |
linkedin | Brief → Post + slides → Publish | The caption first, then the slides as optional --- sections |
reels | Brief → Script → Video | The production script: hook, beats, shots, on-screen text, caption |
youtube | Brief → Script → Video | The production script: hook, retention beats, narration, chapters, description |
On x and linkedin, links stay out of the body. The link goes in a reply on X and in the first comment on LinkedIn.
get_lint_rubric returns the same submission spec for a channel, with the exact numeric limits, and get_writer_system_prompt returns the channel's writing method. Drafting and verification covers both.
Adding a channel to a suggestion
Every suggestion forges its article brief on its own when it is created. Your agent adds the other channels with generate_article_brief and a channel:
{ "projectId": "…", "articleSuggestionId": "…", "channel": "reels" }
A new channel brief never touches the briefs already there and never moves the suggestion's status backward. When the suggestion already has an article brief, the channel brief derives from it, carrying over its key points, hook and stats, and it does not use one of the 10 daily brief slots on Free Forge. Asking again for a channel that already has a brief returns the existing one; force: true regenerates it.
How destinations map to channels
Destinations are where you publish, and list_destinations reads them. Each destination type belongs to one channel, and the type id doubles as the format label your agent passes to lint_draft, so drafts and receipts group per destination.
| Destination type | Channel |
|---|---|
website, local_business | article |
x | x |
linkedin | linkedin |
tiktok, instagram | reels |
youtube_channel | youtube |
With no destinations configured yet, your agent uses the channel name as the format label. It still passes channel explicitly, because a format the gate cannot recognise is graded against the long-form article brief.
What the gate checks on video and slides
The gate reads text. For reels and youtube it validates the script, and no video linter exists yet. The receipt says so in a skipped check, so a passing script never reads as a checked video. For linkedin it validates the caption and the slide text; the slide art is rendered after the text passes, following the LinkedIn writer prompt.
Recording the published piece
Your agent publishes through the CMS or platform it already drives, or you post the piece yourself. Then it records the live URL:
- An
articlegoes tomark_article_published. - A post, carousel or video goes to
register_derived_assetwith the URL, akindsuch associal_post,carousel_pdforvideo, and thechannel.
For video, this is the step the script gate defers: once the video is live, its URL is registered here, never at lint time. A second post on the same channel registers again with its new URL, and every registration is kept. Publishing and attestation covers the whole step.
Markdown version of this page, for your agent.