The obvious way to generate a social post is to ask an image model for one. It is also the way you get warped headlines, a logo with an extra letter, and a storefront that does not exist. Image models are painters, not typesetters, and they will happily invent whatever the prompt implies.
SocialKit's v2 engine is built on a refusal: the image model never touches words, and the language model never touches pixels.
Deciding is a pipeline, not a prompt
A post starts as a brief distilled from the business context: the goal, the audience, the one message, and the proof that backs it. Deterministic gates kill vague briefs before anything renders. Then come candidate angles, filtered by a swap test: if the same line works with a competitor's name on it, it is not an angle, it is filler. Only then does the model write the copy, a hook of three to seven words and a platform-native caption.
Format falls out of the content. A number wants a stat card. A testimonial wants a quote card. A real moment wants a photo hook. Real brand photos lead the imagery; when the pool is spent, the image model paints a name-free, text-free atmospheric scene, and nothing more.
The render is code
Every visual decision lands in a serializable spec: the layout archetype, the frame geometry, the typography, the palette, the words. A real layout engine composites it in the Worker. That is the whole trick behind clean type: the text layer is code, so warped glyphs are structurally impossible, and the same spec produces the same PNG byte for byte. Each post renders true 4:5 and 9:16 masters as separate renders, not crops.

A judge with veto power
Before a post returns, a vision judge reads the render. Four gates come first: specificity (the swap test again, now on the finished post), truth (every claim backed by proof), visual integrity (the on-image text is read back off the pixels and compared to the approved copy), and owner pride (would the owner recognize their business in two seconds and sign it). Eleven weighted dimensions produce the score, but the gates are absolute.
If any gate fails, the post does not ship. No numeric score can argue with a gate.
Below the bar, the engine revises itself, and the revision is surgical: only the weakest stage re-runs while everything else holds. The loop is bounded, and a no-regression floor guarantees a fix never ships something worse than it started with. When a user later edits the post and dictates exact words, their words win; the judge still runs, and its dissent is recorded instead of obeyed.
Why determinism wins
Because the spec is the design, an edit is a diff. Fix the headline and the photo, frame, and palette hold verbatim. Reload the spec next quarter and get the same pixels. Hand it to the revise endpoint with a sentence of feedback and get back a refined post instead of a re-roll. Generation you cannot replay is a slot machine; generation you can replay is a system.
The full pipeline, the gates, the dimensions, and the variety system are documented at socialkit.sh/engine. The API that runs it is one call.