A production-grade, multi-brand AI publishing system: topic extractors feeding a queue, three genuinely distinct AI personas writing in enforced voices, self-scoring quality gates, and scheduled auto-publishing to Ghost CMS. Designed to run what a publication's staff does, operated by one person.
A real publication needs writers, editors, an SEO person, and a publishing schedule. A solo operator gets none of that, and the obvious shortcut (one AI prompt writing generic articles) produces exactly the sameness readers smell instantly. The goal was the hard version: multiple distinct voices, automated topic discovery, quality control that rejects slop, and a posting cadence that runs whether or not anyone is at the desk.
A multi-brand Python engine where every component takes a brand as its first parameter and brands live entirely as data: voice, personas, series frameworks, and affiliate products in JSON, never hardcoded. Extractors (Polymarket prediction markets, Google News RSS, a transcript watch-folder) feed a SQLite topics queue. A queue processor routes topics to Claude with persona-specific prompts, weighted by each persona's affinity keywords. Output passes a quality gate: Claude scores its own work 1 to 5, a refusal detector catches voice violations, and fuzzy matching kills duplicate topics. Articles then publish to Ghost CMS through the Admin API with JWT auth, persona-based author assignment, SEO metadata, affiliate links, and a 5-per-day limiter across optimal posting windows. A Flask dashboard ran the whole thing without touching a terminal. Seven launchd jobs kept it on schedule, from every five minutes to monthly.
The hard problem was never generation, it was sameness. Distinct voices required structure, not adjectives: affinity keywords that bias which persona gets which topic, ban-lists of AI tells enforced by a detector, and worked example openers per series so the model imitates specifics instead of vibes. The second lesson was about leverage: building this taught me that the durable asset isn't the running system, it's the captured method. When I later rebuilt content production as a recipe engine, this system's persona definitions, scoring rubric, and brand-as-data philosophy transferred almost intact, which is the whole argument for writing your machinery down.