Content Studio
A 10-agent content engine that researches trends, drafts in your voice, and publishes across LinkedIn, YouTube, Reddit, Substack, and Hacker News — extensible to new channels. You review and approve the posts that need a human; nothing on a high-risk channel posts on its own.
Overview
Content Studio at /studio is the control-plane view of the content engine that runs in Claude Cowork. The engine drafts; you decide. The drafting work happens in the Content Engine plugin and on a weekly cron; this page is where you review the draft queue, approve the risky posts, and connect your channels.
It clones the "seven AI agents run a YouTube channel" model and generalizes it to multi-channel, founder-GTM demand generation — the content markets your product and routes readers into signup.
The 10 agents
- Scout — scans trends + competitor moves relevant to your ICP and proposes scored angles.
- Strategist — maps each angle to a channel, format, funnel stage, and CTA.
- Writer — drafts in your voice, cloned from your GTM Context Dossier.
- Media — turns scripts into video + thumbnail specs (Remotion) for YouTube.
- Formatter / SEO — reshapes one narrative into each channel's native form.
- Repurposer — slices the weekly pillar into shorts, posts, and threads.
- Compliance / Brand-safety — gates every automated publish; nothing auto-posts past it.
- Publisher — the channel adapters, each in its own publish mode.
- Community / Engagement — drafts replies to comments and mentions.
- Orchestrator — holds the cadence, enforces ban-safe ceilings, and feeds attribution back to Scout.
Every campaign is anchored on a blog pillar
When the engine researches a topic, it doesn't just fire off disconnected posts. It writes a 5-minute-read blog post — the pillar — and then derives the channel posts from it, so everything in a campaign says the same thing in each channel's native shape. The blog is an owned surface (/blog), so it publishes automatically and safely; the channel derivatives land in your queue to review.
Campaigns come in two modes. Trend-led: Scout proposes angles from your positioning and what's moving in your market. SEO-led: a keyword pass proposes the search queries your ICP actually types, and those pillars are written to win the query — it's in the title and subheads, the meta targets it verbatim, and the first paragraph answers the search. SEO-led drafts carry an SEO: query chip in the queue; both modes flow through the same approval gate, so you pick which campaigns run by approving them.
Your real work feeds the queue too: each week the engine turns your most recent won deal into a drafted case study (pillar + LinkedIn version) and recent buyer conversations into a "what buyers actually ask" post. Both are built only from facts you actually have — no invented names, quotes, or numbers — and always arrive as needs approval: customer stories never publish without you.
Publish modes (why nothing gets you banned)
Each channel runs in one of three modes, chosen for how the platform treats automation:
- Auto — LinkedIn (personal). Official API, low risk; publishes after the Compliance gate.
- Draft → approve — YouTube, Reddit, LinkedIn company page. You approve before it posts. The LinkedIn company page posts to your organization's feed via the Community Management API (a separate LinkedIn app from the personal connection, approval-gated). YouTube, Reddit: YouTube uploads the rendered video via the Data API; until the channel clears the YouTube API compliance audit (
YOUTUBE_AUDIT_PASSED=1) every upload is forced private for you to publish from Studio, with an AI-content disclosure in the description. Reddit submits a self-post to a subreddit you pick on the draft (a picker appears on every Reddit draft); it enforces the 90/10 self-promo rule and a hard one-post-per-subreddit-per-week cooldown, so a second post to the same subreddit inside the week is blocked. - Assisted — Substack, Hacker News. No safe write API, so the engine prepares the post and a deep link; you submit it. Hacker News is never automated — automation there bans the account and the domain.
Quality gates (fact-check + scoreboard)
Before a pillar auto-publishes, a fact-check gate scans it for statistics, dollar figures, multipliers, and "studies show"-style citations; anything it can't verify against your own material holds the piece as needs approval with the exact claim and a suggested fix (cite a real source, use your own data, or soften the wording). The gate fails closed — an invented number never publishes on its own. Every pillar also gets a quality score (brand-fit / clarity / hook, hard-grader 0–100) shown as a Q chip on the draft, so you can see quality trend as the engine learns your voice.
Content budget (quotas & governance)
The engine is metered so it can't run away with your AI spend or your posting volume. Each account has a content budget — a cap on how many pieces the engine generates per rolling day and week (defaults: 20/day, 80/week, admin-adjustable). When you're inside the budget, the This week's content budget strip near the top of /studio shows how much you've used and how much is left; when you hit the cap, the engine pauses new drafts and says so — it never silently stops. Generation resumes on its own as the rolling window clears. Ideas that were skipped for budget aren't thrown away; they're picked up the next window. Deployment admins set the default caps (and per-account overrides) — a cap of zero means unlimited.
Underneath, a shared-app governance layer bounds the whole deployment's outbound traffic — the Anthropic calls the build cron makes and the publishes the dispatch cron fires — so one busy window across all accounts can't blow the token budget or trip a platform's rate limit. It's fail-safe: when a cap is reached the work defers to the next scheduled run rather than erroring. The knobs are environment variables (CONTENT_GOV_CAMPAIGNS_PER_MIN, CONTENT_GOV_PUBLISHES_PER_MIN, CONTENT_GOV_WINDOW_SEC) documented for operators in docs/ops-hardening.md.
Goal-based autopilot
Set a monthly goal at the top of /studio — signups, clicks, or revenue. The pace bar shows what attribution has actually measured against straight-line pace for the month (the marker is where you "should" be today), with what each remaining day must average to hit the target. When you fall behind, the engine responds with a known playbook, not a guess: goal-targeted, conversion-stage campaign ideas go to the front of the build queue (extra action-stage content for a signups goal, conviction-stage for revenue), capped so it never spams the queue. The math is deliberately simple enough to check by hand.
Per-draft performance
Every published draft card on /studio shows what that piece actually drove — clicks, signups, and attributed revenue — joined from the same attribution the public /watch board reads (each published CTA is UTM-tagged with the draft's id, and the pipeline follows content → click → signup → paid). Pieces that produced signups carry a "Drove N signups" badge next to their status, so the winners are visible at a glance while you review the queue.
Attribution is honest about sparsity: a freshly published piece reads "No attributed clicks yet" until UTM-tagged traffic actually lands — you'll never see zeros pretending to be data. Use the Sort → Performance option in the queue's filter row to rank drafts by signups first, then revenue, then clicks; drafts with nothing attributed (and unpublished drafts) stay in newest-first order below the performers. /watch remains the public proof board; this is the operator's working view of the same numbers.
Channel compare
Below the goal bar, the Channel performance — last 30 days card compares every channel that published a piece in the window: pieces published, clicks, signups, attributed revenue, and the conversion signal (signups ÷ clicks, shown only when clicks landed). Channels are ranked the way the revenue-first optimizer ranks winners — revenue first, then signups, then clicks — so the channel that deserves the next campaign sits on top. It reads the same attribution as /watch and the per-draft cards; nothing new is tracked.
One rationale line under the table says why the engine is leaning where it's leaning. When the optimizer (the weekly metrics-rollup) has stored a note, you see its own reasoning, tagged Optimizer; until it has, the line is computed deterministically from the same 30-day metrics and tagged Signal — e.g. "prioritizing linkedin — 3.2× conversion vs reddit last 30d". Sparsity stays honest here too: a channel with pieces but no attributed traffic reads "published 3, no attributed traffic yet", and the card says so when nothing has published in the window at all.
Channel token health & reconnect
Every connected channel on the strip at the top of /studio carries a token-health pill so an expired login never hides inside a stray publish error. The state is classified from what the engine already stores — the token's expiry (where the provider reports it), the last token-refresh error, and the most recent publish outcome on that channel — with no new polling: Healthy (fresh token or a successful publish in the last two weeks), Reconnect soon (the token expires within three days), Needs reconnect (expired), Publish failing (the last publish bounced on authentication), or Unverified — an honest state for providers that report no expiry and haven't published yet, so a green pill never overstates what we actually know.
When a channel needs attention, a Reconnect action appears on its pill. For channels with a web login (LinkedIn, LinkedIn company, YouTube, Reddit, X, Threads) it opens the same connect flow Settings → Connect uses, in a popup, and the strip refreshes the moment it succeeds. For channels whose token arrives another way (Bluesky, Dev.to, Hashnode — API-key providers), it copies a paste-ready instruction to reconnect in Cowork or add a fresh key in Settings, since there's no web handshake to open. Owned and assisted channels (blog, Substack, Hacker News) hold no credential and show Ready.
Failed-publish recovery: when a draft failed because of authentication, its card spells out the fix instead of a raw error — a Reconnect <channel> action next to a Retry publish button. Retry re-queues the piece through the normal dispatch (the compliance gate still runs before anything goes live), so once you've reconnected, one click puts it back in line. A failure that wasn't a login problem (a rate limit, a content issue) says so honestly — a reconnect wouldn't fix it, so none is offered.
Draft history & versioning
Every draft on /studio keeps an append-only history of every body it has ever had. The History button on a draft card opens it: each version shows when it was written and by whom — Engine (the pipeline drafted it), You (a manual edit), or AI edit. Compare to current puts any older version side-by-side with the current body, so you can see exactly what changed before you approve.
Unpublished drafts get an Edit button: change the body and Save as new version — the previous body stays in history, nothing is overwritten. Published (and failed) drafts are immutable: what actually went out is part of the record, so iterating on a published piece means repurposing it into a new draft. History keeps the last 20 versions per draft; older versions are pruned as new ones land, and the drawer says so — truncation is never silent.
Revise with instructions turns approve/reject into a conversation: type what should change ("tighten the hook, cut the last paragraph, make the CTA softer") into the box at the top of the History drawer and the AI applies it server-side, saving the result as a new AI edit version — the body it revised stays one row below in history, one Compare to current click away. The endpoint runs behind your studio entitlement, is metered like the other studio AI surfaces (and respects the admin kill-switch on /admin/agent-costs), and says so honestly when the deployment has no Anthropic key — manual Edit always works.
Calendar + campaigns
The Next two weeks grid on /studio shows what's queued to publish, day by day; any pending slot can be moved with its inline date picker (published/failed history stays put). Below it, Campaigns shows each campaign the way it's built: one blog pillar plus the channel posts derived from it, with each derivative's channel and status at a glance.
Team & agency mode
The Operators section on /studio lets you grant a teammate or agency access to run your studio. Approvers can do everything you can operationally — approve, schedule, reschedule. Drafters can create and edit, but every transition toward a publish is enforced server-side to an approver or you: a drafter clicking Approve gets a clear "approver required" answer. Agencies work multi-brand: an operator granted access by several founders switches client workspaces from the picker at the top of /studio — the draft queue and calendar follow the selected client, and each client's own license covers their studio.
Engagement — replies to your comments
Once a post is live, the engine watches for comments on it and drafts replies in your voice (LinkedIn first). They land in the Engagement section of /studio for you to edit and Send — or Skip. Each draft is marked "auto-send ok" or "needs you"; high-risk channels (Reddit, Hacker News) always require a human and never auto-send. A reply you send posts back to the platform as a comment. Runs on the content-engage-poll cron; needs the channel connected + an Anthropic key (it no-ops cleanly without one).
Warm leads from content — engagement becomes pipeline
Every like and comment on a published piece is captured and scored against your ICP dossier (industries, buyer titles, buying triggers). Engagers who clear the warm bar become prospects on /prospects automatically — tagged with the piece that drew them and the reason they fit — and each gets a short drafted note that references what they engaged with (and responds to their comment when they left one).
The Warm leads from content section of /studio lists them hot-first: the engager, their fit score and reason, the piece, their comment, and the editable draft. Copy draft for a platform DM, Send as email (you supply the address — social engagers rarely come with one), Snooze, or Dismiss. Draft-only by design: nothing is ever sent without your click. Runs on the hourly content-warm-leads cron; needs an Anthropic key (engagements simply wait, unscored, without one).
Engine status (deployment owners)
Admins see an Engine status strip at the top of /studio — a live, per-capability readiness check (migrations, Anthropic, PostHog, Resend, LinkedIn, cron, entitlement). Each capability is green when the thing it gates on is actually present, amber when a value still needs setting (with the exact action), and red when a probe fails. The same status is available as JSON at /api/studio/health (admin- or cron-authed).
To flip the whole "safe path" live in one command, run npm run content-studio:golive -- --email=you@co.com. It applies the database migrations, grants the content-engine entitlement to that user, validates every go-live environment variable, fires the content pipeline (Scout → Build → Dispatch → Attribution), and prints the readiness report. The handful of steps only a human can do — pasting third-party API keys, verifying the Resend sending domain, creating the LinkedIn app — are flagged MANUAL with the exact value to set.
How to use it
- Finish onboarding so the engine has your voice (your GTM Context Dossier).
- Connect the channels you want in Cowork (LinkedIn connects with the self-serve "Share on LinkedIn" permission — no approval). On /studio, set each channel's publish mode; the strip shows which are connected.
- Let the weekly cadence build the queue. Review drafts, Approve the ones that need a human, Schedule what's ready.
- Watch what converts — the Orchestrator attributes signups back to the pieces that drove them, and /watch shows real platform numbers per connected channel (YouTube views + likes, Reddit ups + comments, LinkedIn likes + comments) merged with the PostHog click/signup attribution — plus revenue attributed per piece: signups are followed through to what they actually paid (Stripe), and the optimizer ranks winning angles by revenue first, not reach.
- Every Monday a founder digest email recaps the week: what shipped, what converted (including revenue), warm leads your content produced, and the recommended next moves. Weeks with nothing to report send nothing.
Channels on the strip now include X (Twitter), Bluesky, Threads, Dev.to, and Hashnode alongside LinkedIn, YouTube, Reddit, Substack, and Hacker News. X needs a paid developer app; Threads needs Meta app review; Bluesky connects with a handle + app password; Dev.to and Hashnode connect with an API key. Each activates the moment its credential lands — adding the next channel is still a single adapter file.