At 12:37 UTC on October 9, Wayne, our founder, read a DM the Twitter doer had sent from his X account 35 minutes earlier. The Twitter doer is the AI worker that runs that account. Wayne's verdict, dictated: "Much shorter, too complicated." Then: "We can just ask Claude Code Opus 5.5 the question: Is this simple to understand?"
The chief of staff, the AI worker he dictates to, asked it and got five reasons the DM wasn't. At 12:39 Wayne turned that into a rule: "Find a way so that the tweet automatically self-reviews itself. It's a checklist before sending, and it has to say yes to all of them."
At 12:42, three and a half minutes later, it was committed: twitter/self_review.py, 109 lines. In between, at 12:40, he'd added: "let's add the self-review like this to all the socials, including WhatsApp. Sometimes it's also too complicated what we send." WhatsApp's review was committed at 12:49, LinkedIn's at 13:06.
Wayne didn't send a memo asking the workers to write more clearly. The rule became a check in code that refuses to send.
The seven questions
The chief of staff's five reasons became seven questions, in one tuple:
CHECKLIST = (
"Would a stranger reading it cold understand it in one read, without reading it twice?",
"Does it say one thing, not two ideas or a reminder plus a pitch?",
"Is it short: no sentence or phrase in it that adds nothing to the point?",
"Plain words only: no jargon, acronym or idiom a busy salesperson wouldn't say out loud (B2B, API and U.S. are fine)?",
"At most one number (a link doesn't count)?",
"Can nothing in it be read two ways (no fuzzy phrase like 'stayed with me')?",
"Does the point come in its first sentence, not after a setup the reader has to hold in mind?",
)
"Stayed with me" is from the DM that started it.
How it works
- Every sender asks first. On X,
post.py,engage.pyandbrowser.pywon't send a post, reply, quote or DM until the review says yes. On LinkedIn it'sanswer.py, and on WhatsApp the outbox, which won't approve a message. - One call to Claude per text. It runs
claude -pwith--model claude-opus-5-5 --output-format json --max-turns 1, on our Claude subscription rather than an API key. The prompt asks for a yes or a no on each question: "Be strict: yes only when it is plainly true; a no says why in a few words." The answer comes back as JSON. - It fails closed. A no, a missing answer, a timeout or a crash all count as a no:
try:
found = ask(text, kind)
except (OSError, ValueError, KeyError, TypeError, subprocess.SubprocessError) as error:
return [f"self-review failed, nothing goes unreviewed: {str(error)[:200]}"]
- Each text is reviewed once. The answer is kept under a hash of the kind of message, the text and the checklist, so a dry run's yes holds for the real send. Change one question and every text gets reviewed again.
- One checklist for every channel. LinkedIn's and WhatsApp's reviews read
CHECKLISTout of X's file with Python'sast, without importing it (importing would pull in X's code). All three ask the same seven questions. - Cold means different things. On X, a tweet is read by a stranger scrolling by. On LinkedIn, a reply or a DM is read along with the post it answers. On WhatsApp, the review gets the chat so far, and "cold" in question 1 means "this person, reading it there, not a stranger."
What it refused in its first three hours
When it arrived, 10 posts were queued for X, each one written and checked against the Twitter doer's earlier rules. The review said no to all 10.
By 15:50 UTC on October 9, it had read 83 texts for X, drafts and rewrites included: 49 posts, 30 DMs and 4 quotes. It said yes to 24 of them and no to 59. Only 11 of the 49 posts passed.
These are the questions behind those 59 nos (most texts failed more than one):
| Question | Texts it refused |
|---|---|
| 6. Nothing read two ways | 51 |
| 1. Understood cold, in one read | 31 |
| 3. Short, nothing that adds nothing | 25 |
| 7. The point first | 23 |
| 4. Plain words | 18 |
| 5. At most one number | 14 |
| 2. One thing | 8 |
On LinkedIn it said no to all 5 posts that were ready to go. The free-list doer, the AI worker that runs Wayne's LinkedIn, rewrote each one to three lines and one number, and the review then said yes to all 5.
The first text it read was the DM that started it all: 293 characters, and a no on all 7 questions. It had already gone out, so the chief of staff rewrote it as a test: three rewrites in 50 seconds. The one that passed has 111 characters: "50M U.S. B2B contacts, free, for your cofounder's prospecting:", then the link.
Two posts, draft by draft
The post written to be pinned on Wayne's X account took three drafts in 93 seconds:
| Draft | The review's no |
|---|---|
| "one file with every U.S. B2B contact I have: 43.6M people with titles and LinkedIn URLs, 6.7M companies. my AI employees checked 3,000 of them against LinkedIn [...]" | Four numbers. And "'my AI employees' could mean AI agents or staff who work on AI" |
| "50M U.S. B2B contacts in one file, rebuilt every month by my AI agents. the newest one: [link]" | "'the newest one' could mean the newest file or the newest AI agent" |
| "50M U.S. B2B contacts in one file, rebuilt every month by my AI agents. the newest file is always at this link: [link]" | None: yes to all 7 |
Another post took seven drafts in three minutes. It's about one of our free lists: in its first pull, 804 founders and CEOs listed the same employer, a LinkedIn page called "Stealth Startup", and the worker that builds our lists took them out. The first draft got 7 nos and the second got one. From the third on, they kept failing question 6 for the same reason: was taking them out right or wrong? The last four:
| Draft | The review's no |
|---|---|
| "my AI agent removed 804 founders from my lead lists: each one's employer was "Stealth Startup", which isn't a real company." | "Unclear if removal was smart cleanup or agent mistake" |
| "804 founders in my lead lists gave a fake employer, "Stealth Startup", so my AI agent rightly removed them." | "'rightly' may read as sarcasm" |
| "my AI agent removed 804 founders from my lead lists because their only employer was a placeholder page called "Stealth Startup"." | "Unclear if removing them was a smart filter or a costly mistake" |
| "my AI agent keeps 804 founders out of my lead lists: their only employer is a LinkedIn page called "Stealth Startup", so there's no company to sell to." | None: yes to all 7 |
Calling the removal right didn't settle it. What settled it was saying why it matters to the reader: there's no company to sell to.
Where it stops
- It judges how a text reads, not whether it's true. Facts have their own checks. Anything a worker says about Datacircle comes word for word from one file of approved sentences,
golden.md, and a post whose numbers can move is counted again in the 6 hours before it goes out. - It reads one message at a time. The second tweet of a thread, read on its own, starts with an "it" that refers to nothing. On October 9, both threads waiting in the X queue got a no on question 1 for every tweet after the first. It's filed as a ticket for the Twitter doer, like everything else here.
- It's strict by design. 59 nos out of 83 is the point: without it, the 10 posts it refused on day one would all have gone out as they were.
The rest of how we run a team of AI workers is in How we scale a team of AI workers. And the free file, in its one approved sentence:
Free: 10M+ U.S. B2B leads, as a flat file. Download it at datacircle.dev.