I built a gate to stop my own posts
Last week I went around my own release gate. Every post that week went out without it.
The gate is the fourth box I've opened on my one-person team of AI tools. It's the last thing a piece is meant to get past before it's scheduled. If you're just joining: every Monday this newsletter opens one box on that team's org chart and shows how it's set up, something it really made, what went wrong, and a template you can copy.
The job, in one sentence
Stop anything from going out that states a number I can't source, breaks my voice rules, or points at something that doesn't exist.
The setup
The gate is a set of checks that runs before anything is released. A note at the top of the script that runs it before launch says every check is there because that thing actually broke once.
If a post has a number that isn't in my facts file (the list of numbers I can prove), it stops. Same for a banned phrase or an em dash, a post with no passed review, a file that changed after review, an image nobody made, or a video link the upload never wrote down. A blocked piece holds, and the run says why.
The rule underneath it: no automated check can approve anything. Checks find problems and prove the pieces agree with each other. I approve what goes out, on the exact file. If a file changes after I've said yes, it goes back to held until I say yes again.
It runs by itself now. Three times a day from Friday to Monday, the job that schedules my week runs the gate first. If there's a hold, that job schedules nothing from that week.
What it actually produced
This is the gate's verdict on last week, the week that skipped it. I ran it last night, after the posts had already gone out. Three of its lines:
HELD
- issue central question does not match the selected theme option
- the Editor's Letter is not ready
- release gate: undeclared ready flip: ...first-comment.md
(only manifest primaries may carry status: ready)
All of that is paperwork, because the record it's reading was put together after the fact. The gate stopped there and never read a post, so none of those lines says a post was wrong. My read is it would have held anyway, since that week had no recorded quality review.
What broke
Three of those first.
A video link typed by hand. On August 3, launch copy for an episode carried a video link typed in by hand, hours before the upload ran and produced the real one. Every LinkedIn post for that episode pointed at it. The gate caught it before publishing. Now only the record the upload itself writes can supply a video link.
My do-not-state list got read as approved. An old claim about one of my projects overstated the real figure, so it went on my do-not-state list. The gate was reading that list as a list of approved numbers, so when I tested it, the false claim passed. The first fix didn't work either: a bug meant the new check matched nothing while reporting it had loaded fine. The commit that fixed it says it plainly: a gate that can't fail its own test isn't a gate.
A green light that checked nothing. Two posts sat in the queue waiting on an image that was never made, and those slots were lost. The check I added for missing images then reported green while inspecting zero files, because it was looking in a folder layout I'd stopped using.
So when I fixed that check, I made it fail first, on an image that didn't exist, before I trusted its pass.
Then last week's posts. I read each one and said yes in a chat, and the week went straight into the schedule, most of it through a different tool. That road never touches the gate. The gate lives inside the job that runs Friday to Monday, and I'd gone in ahead of it.
Nothing flagged it until last Monday, after that week's newsletter had gone live. The job that records how each post did refused the week, because the file that should have listed the posts didn't exist.
I approved every post. But my reading was the only check those posts got, and the gate exists to back up my reading.
I haven't closed that road yet. The fix goes at the last step: no tool can schedule anything unless its file has a recorded pass.
Copy this
ROLE: Gate (blocks, never approves)
JOB (one sentence):
Before anything is scheduled, check it against my rules and block it if it fails.
INPUTS (the only places it may read):
- The finished piece
- My facts file (the only numbers I can state) and my do-not-state list
- My voice rules
- The real record of anything it links to
CHECKS (each one exists because it broke once):
- Every number is in the facts file
- No banned words or phrases
- Every link matches something that exists
- Nothing changed after it was reviewed
OUTPUT:
- Pass, or held with the exact reason
LIMITS (it may never):
- Approve anything
- Let a held piece ship "just this once" without my explicit exception
- Pass a check it hasn't proven can fail (feed it one wrong number first)
APPROVALS:
- A pass releases nothing. My yes has to be on the exact file too.
If I were setting this up again, I'd add one line under limits: list every way a piece can reach the public, and put the gate on all of them.
Shipped this week
- My assistant now runs as a full app on an Android phone, and I've built its own screen for the car.
- The page where I approve replies now shows the words each one is answering, with a link to the original, right above my draft.
Next issue, next Monday: the voice and the presenter. If someone passed this along, you can sign up for my email at mpthaker.xyz.