June 8, 2026 · 5 min read

A content pipeline that can't go off-brand

I do not trust an AI to remember the legal disclaimer, so I do not ask it to. Deterministic code enforces the non-negotiables before any reviewer reads the draft. That is what makes unattended publishing safe to leave alone.

Here is the rule I will not bend: I do not ask a language model to be responsible for the things that have to be exactly right. Creative phrasing, yes. The legally required disclaimer, no. An AI that is good at rewording is, by the same skill, good at rewording your disclaimer into something warmer and shorter that no longer says the thing the law requires it to say. It will not even know it did anything wrong. So in my publishing pipeline, the model never gets the chance.

Let me take the whole thing apart, because the structure is the interesting part and it is reusable for any business that wants to automate content without a person babysitting every post.

The pipeline has four roles. A Planner figures out what the piece should be and gathers the real material it needs. A Writer drafts it. A Reviewer reads the draft and either approves it or sends it back with notes, and the Writer and Reviewer loop like that for up to three rounds. When the Reviewer approves, a Publisher posts it. On the surface this looks like a small newsroom: a desk editor, a writer, a copy editor, and someone who hits publish. It runs on a schedule with nobody watching.

The trick that makes it safe to leave alone is one step you would not expect, and it sits between the Writer and the Reviewer.

Before the Reviewer ever sees the draft, ordinary code runs over it and rewrites the parts that are not allowed to vary. If the Writer produced a disclaimer, that disclaimer is thrown away and the exact, approved disclaimer text is put back in its place. Brand elements that have one correct form are normalized to that form. Only then does the Reviewer read it. This matters because of a subtle failure I kept hitting when I trusted the model to self-check: the Reviewer would read a paraphrased disclaimer, find it reasonable, and approve it. Two language models agreeing that a softened legal line "looks fine" is not compliance. It is two confident colleagues making the same mistake. By canonicalizing first, the Reviewer is always reading the real, required text, so its approval means something.

The hard rules sit in code, not in the prompt. There is a compliance check that verifies, mechanically, that the required disclaimer tokens are present, that retired brand phrases I no longer use are absent, that the length fits the channel, and that nothing slipped into a phrasing I have decided not to use. These are pass-or-fail checks written in plain code. A prompt instruction like "always include the disclaimer" is a request. A code check that refuses to publish without it is a rule. The model lives inside the rules and gets all the creative latitude it wants there, but it cannot vote itself out of them.

One more piece holds it together across services, because I run more than one of these. The social publisher and the blog writer are separate programs, but the brand definition is not duplicated in each. The colors, the fonts, the approved voice phrases, the exact disclaimer text all live in one shared library. Each service copies that library in when it deploys. So when I change a rule, I change it once. The next time each service deploys, they all pick up the new rule together. There is no version where the blog says one thing and the social account says a slightly older thing because I updated one and forgot the other.

What does this buy in practice? It makes unattended automation actually safe to leave unattended. The reason most businesses keep a person in the loop on every published post is fear, and the fear is reasonable: the cost of one off-brand or non-compliant post going out automatically is high enough that the supervision feels mandatory. This design removes the specific failures that justify the fear. A missing disclaimer cannot happen. A paraphrased disclaimer cannot happen. A retired phrase cannot go out. Those are not risks I am managing carefully. They are outcomes the code does not permit.

The general idea travels well beyond my product. Any time you want to automate something that produces external output, sort the requirements into two piles. The pile that benefits from judgment and phrasing, hand to the model. The pile that has exactly one correct form and a real cost if it is wrong, enforce in code, before any model gets a vote. The mistake I see people make is putting both piles in the prompt and hoping. The version that you can actually leave running while you sleep is the one where the non-negotiables were never the model's job in the first place.

If you want automated content that you can leave running without holding your breath, that is the kind of system I build. Start at /services.

Want this kind of work in your business?

See the service that fits, or book a 30-minute call and tell me what you're working on.