magosox
Automates a brand's social content — it picks the topic, writes the copy, produces the graphics and publishes
magosox produces a brand's social media content and puts it online on its own. At the times it's been given it decides what to talk about, writes the copy, turns it into graphics and publishes: nobody has to open anything. The hard part isn't the publishing — the hard part is keeping a recognisable voice while doing it. An automated post that sounds like an automated post is worth nothing, and that's exactly where this project puts its effort.
## The brand context is data, not code
What makes a post recognisable — the voice, the way it addresses the reader, the things the brand knows and the things it deliberately doesn't say, along with the stock of topics — lives inside the product in magosox, not in the source code. It's written and corrected from the interface, and a change applies from the next post onwards, with no release. Everything else follows from that: taking on a new brand is configuration rather than development, and each brand carries its own context without touching the others.
## Structure the prose, don't shred it
The quality of a post doesn't come from an architecture. It comes from about a thousand well-written words. That distinction sounds obvious, and almost every system of this kind misses it: it shreds those words into columns — tone, formality, useEmoji: false — and reassembles them, producing worse instructions than the ones it started from. In magosox the voice rules are rows holding text rendered verbatim, line breaks and indentation included. The system only knows when to inject them, in what order, and under which heading: it structures the scope, the weight and the placement of the prose, never the prose itself. So that work on the engine can't quietly change the voice, a regression test recompiles the prompt from those rows and compares it, character by character, against a frozen reference.
## A ledger instead of a query
To keep the feed from repeating itself, the system has to know what was talked about recently. The obvious move is to derive that from the published posts, and it doesn't hold. The window counts posts, not days, and more than one post can go out on the same day: no chronological sort can put them in order. Then there are the one-off posts written on request, which reference no topic in the catalogue and so could never be foreign keys. So anti-repetition is an append-only ledger with a sequence number of its own. A scheduled post burns its topic immediately and hands it back if publishing fails — a lifecycle a post's status couldn't represent without lying.
## Limits announced, limits enforced
Every text surface has two different numbers: the one announced to the model and the one the check actually enforces. A title might be announced at 55 characters and rejected only at 65, while the correction message still says 55. That margin of roughly 18% is what keeps the retry rate near zero, and it weighs more than it sounds: the second attempt produces, on average, worse copy than the first. Collapsing the two into a single column means either flooding the correction loop or letting every title grow by 18%.
## From idea to published post
The pipeline runs unattended, at the times the calendar sets, and each step leaves a trail you can read back:
## The interface
The admin is where the brand context actually gets edited, without anyone going near a repository. Sign-in is passwordless, by email code; there's no registration, accounts are seeded from the terminal.
## Tech stack
The approach to configuration is worth a note: environment variables are the only way to configure the service before the database exists, so they stay. From the first boot onwards, though, the stored value wins, and the interface shows which of the two is winning. Changing a model key at three in the morning shouldn't require server access.
magosox has been in production since 1 August 2026, publishing unattended on the cadence it's been given. Before it went live the history of content already published was loaded in as well, so that anti-repetition had a memory from day one instead of having to build one up over weeks.