Most AI content tools are black boxes that output generic posts and pray you do not look under the hood. We built the opposite. The animus-blog-generator pipeline is open source, runs on a cron schedule, and commits finished markdown directly to GitHub. You can read every prompt, every agent definition, and every handoff contract in the launchapp-dev/animus-blog-generator repo. Here is exactly how it works, from topic discovery to committed draft, and what we learned about letting agents ship content without a human babysitter.
The Two Ways a Post Starts
Every post enters the system through one of two doors.
The first is a cron schedule. By default, the pipeline tries to ship twice a week: Tuesday at 8 a.m. and Thursday at 8 a.m. The blog-production workflow wakes up, picks its own topic, gathers sources, writes the draft, optimizes it, generates a featured image, writes social excerpts, and pushes to origin. If you configure Supabase, it also upserts the post to a database. If you do not, git remains the source of truth and the phase skips cleanly.
The second door is a human-approved Linear ticket. The blog-from-ticket workflow checks the ticket status, converts the ticket body into a brief, then runs the exact same content pipeline. When it finishes, it posts a completion comment and optionally moves the ticket to done. A cancellation guard re-checks Linear status before every phase, so a human can kill the job mid-flight.
Ten Phases from Idea to Commit
The scheduled pipeline is relentless. Here is the full chain:
- Topic research. A
content-strategistagent scans Search Console for striking-distance keywords, checks competitor blogs for gaps, and mines Reddit and forums for real questions people are asking. - Research collection. A
content-researchergathers citable sources using Firecrawl, Exa, Tavily, Brave, and Google Maps. - Content writing. A
content-writerrunning Claude Opus 4.6 writescontent/<slug>.mdwith full YAML frontmatter: title, slug, keywords, schema markup, word count, and more. - Commit draft. A bash phase git-commits the file.
- SEO review. An
seo-optimizeraudits keyword density (target 0.5 to 1.5 percent), fixes meta descriptions, adds internal links, pushes readability to grade 8 to 10, and scrubs AI clichés. - Asset generation. An
asset-generatorcalls Replicate to generate a 16:9 WebP featured image using thegoogle/nano-banana-promodel. - Social excerpts. The same agent writes platform-specific social copy to
<slug>.social.md. - Register post. A
register-post-runnerappends the post tocontent/manifest.jsonfor deduplication and internal-link indexing. - Push branch. A bash phase pushes to origin.
- Publish post. An optional command-phase upserts the post into Supabase/PostgREST. If unconfigured, it skips without error.
The ticket-driven variant reuses phases 3 through 10 verbatim after converting the human brief.
Who Does the Work
The pipeline is not a single model with a long prompt. It is a chain of specialized agents, each with its own model, MCP servers, and mission.
content-strategist: Claude Sonnet 4.6, armed with Search Console, Exa, Tavily, Brave, Firecrawl, and a content library. Picks the topic and writes the brief.content-researcher: Claude Sonnet 4.6, same research stack. Gathers the raw material.content-writer: Claude Opus 4.6, the only Opus in the chain. Writes the long-form draft.seo-optimizer: Claude Sonnet 4.6. Audits and fixes SEO in place.asset-generator: Claude Sonnet 4.6. Handles images and social copy.performance-analyst: Claude Sonnet 4.6. Runs weekly refresh analysis.approval-watcher: Claude Haiku 4.5. Polls Linear every 15 minutes for human approvals. This is a deterministic shell script, not an LLM call, so deduplication is exact and the polling costs zero tokens.
There is also an optional discovery loop. Every morning at 7 a.m., a transcript-collector and idea-strategist ingest meeting transcripts, propose 3 to 5 blog angles, validate them against SEO and competitor data, and create Linear issues at status ready. A human edits, approves, and the ticket-driven pipeline takes over.
How We Keep Quality from Drifting
Handing a content pipeline to agents is only safe if the guardrails are explicit.
The central contract is business-context.yaml. Every content agent reads it before writing. It defines the niche, the audience, the tone, banned words, and competitive differentiators. If an agent drifts, it drifts against a document it literally just ingested.
Best practices live in .animus/skills/: content-strategy.md, ai-seo.md, content-humanizer.md, seo-audit.md, schema-markup.md, and social-content.md. These are not loose guidelines. They are skill files the agent loads as part of its context.
Phase handoffs are enforced by output contracts. If content-writing omits the slug field, register-post cannot run and the workflow fails fast. There is no implicit ambient state. Every downstream dependency is declared.
A content-library MCP server acts as a bring-your-own knowledge brain for brand positions and established facts. If it is absent, agents fall back to content/manifest.json plus external research. The library and transcript integrations ship as no-op command: "true" stubs so the YAML compiles before any secrets are configured.
Lessons from Shipping Without a Human in the Room
We have been running this long enough to earn a few scars. These are the design decisions that matter:
- Schedules ship disabled by default. Every cron trigger starts with
enabled: false. You must explicitly flip it after loading your.env. This prevents a fresh clone from burning through API credits before you know what happened. - Git is the source of truth.
content/manifest.jsonis checked in. Database publishing is an opt-in downstream target. This makes the pipeline auditable, offline-capable, and trivial to roll back. - You must compile workflows to disk. Any change to a YAML file must be followed by
animus workflow config compile. The daemon compiles in-memory on startup, but the runner needs the persisted compiled config. Skip this step and you get "no workflow found for subject." - Human gating happens outside the LLM. The approval watcher is a shell script, not an agent conversation. That keeps it deterministic and free.
- The daemon does not auto-load
.env. You mustsource .envinto the daemon's shell. This prevents secrets from leaking into compiled workflow JSON. - Asset generation is currently a hard requirement in the scheduled pipeline. If you lack a Replicate token, you remove the phase rather than expecting an automatic skip.
What You Should Do Next
If you run a technical blog and you are tired of copy-pasting between research tabs, writing the same meta-description boilerplate, and forgetting to update your internal link index, this pipeline is built for you. Clone launchapp-dev/animus-blog-generator, read the YAML, fill in your .env, and compile the workflows. The hardest part is deciding what you want to say. The agents can handle the rest.
Sources
launchapp-dev/animus-blog-generatorrepo README: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/README.mdanimus-blog-generator/CLAUDE.md: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/CLAUDE.mdanimus-blog-generator/.animus/workflows/custom.yaml: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/.animus/workflows/custom.yamlanimus-blog-generator/.animus/workflows/workflow-blog-production.yaml: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/.animus/workflows/workflow-blog-production.yamlanimus-blog-generator/.animus/workflows/workflow-blog-from-ticket.yaml: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/.animus/workflows/workflow-blog-from-ticket.yamlanimus-blog-generator/MCP-TOOLS.md: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/MCP-TOOLS.mdanimus-blog-generator/docs/integrations/publish-targets/README.md: https://raw.githubusercontent.com/launchapp-dev/animus-blog-generator/main/docs/integrations/publish-targets/README.mdanimus-skillsrepo overview: https://raw.githubusercontent.com/launchapp-dev/animus-skills/refs/heads/main/README.md