Infrastructure Part 2: Every Monday at 06:00. 100% built with AI.
By July 2026, we were done with WordPress. By then, Johan's newsletter Tech Insights had gone out every Monday at 06:00 for two years straight, reaching over 3,000 subscribers. Today, the newsletter is powered by an engine we built ourselves. A setup that reads hand-written markdown, builds the website and the email from the same source, and fires it all off in a single API request.
In Part 1, we explained how the main website left WordPress. Tech Insights made the same leap a week later. This article covers the second half of the migration—the part where mistakes actually land in someone's inbox. This is the story of how we built a subscriber database from scratch, how we handle consent, and how we engineered a system that sends the email exactly once. Completely without a safety net.
- Subscribers, email and LinkedIn
- 3,000 +
- Issues so far
- 106
- Commits in six days
- 102
- Safety tests
- 78
- API request per send
- 1
- Tracking pixels
- 0
01
The streak that can't be broken
Tech Insights started in the summer of 2024. Like most newsletters on a custom domain, it began as a WordPress site with a mailing plugin. It worked, and it cost money. Yearly fees for plugins handling backups, SEO, file uploads, and the actual sending. Every single week meant the exact same manual routine: create a post in the admin panel, paste the text from markdown files, watch an image upload crash, upload the image one more time, and hit send.
That routine held for two years. When we started the rebuild, the streak was up to 105 issues — one every week since July 2024. The entire newsletter rests on that streak. It builds expectations. Whatever replaced WordPress had to deliver on Monday. Every Monday, without exception.
In July, we saw a way out. Our sibling site tokentek.ai left WordPress for Astro first (that move is its own case), and this site followed a week later. Static build, content in git, and a server that pulls the code and publishes itself. But the website was the easy part for Tech Insights. A broken homepage can be rebuilt and published in a couple of minutes; by Tuesday, everyone has forgotten about it. The tricky half was the subscriber list and the send. That part has a property the web lacks: its most important action cannot be undone.
02
Sent is sent
If you mess up on the web, you just republish the page and the mistake is gone. A send gone wrong cannot be saved. If you send twice, the entire list gets a duplicate in their inbox. If you send to someone who has unsubscribed, you break a promise, and the law cares. If you send to half the list, you have no reliable way to reach the other half. And if next week's issue leaks on the site on Saturday, the release is ruined before it even happens.
That is why we built the engine backwards. We started from the worst-case scenario. Everything up to the send must be undoable: the import, the build, the preview, the test email, even the decision to send. Only one line is irreversible: the second that Postmark — the service talking to the world's email servers — accepts the campaign. Up until that point, we can roll back. After that, nothing is allowed to send that issue again.
Drawing that line perfectly took us six days. The first version was finished in one day.
03
An engine in a day
The first commit landed on Wednesday, July 15 at 10:14. It was written by Claude Fable 5 in Claude Code. It contained the Astro site, the entire back catalog converted from Obsidian with optimized images, a publish gate hiding future-dated posts, an email renderer, PHP code for double opt-in signups, and a deploy script following the same pattern as the sibling site. Later that evening, unsubscribe handling was done. We had a news feed the sibling site could read, and a sync of Postmark's suppression list for addresses that bounced or reported spam. Fifteen commits, day one.
Once the initial code was in place, we put GPT-5.6 in Codex to work reviewing the security of what Fable had written. First a broad pass, then rounds of fixes visible in our git history: thirteen, then nine, then seven. Each fix closed a small window in time where two events could collide, which could have led to a reader getting the wrong content.
For example, a rebuild right in the middle of a send could mix the subject line of an older draft with the text of a newer one. We reproduced the worst window with a test list. An interrupted send resumed right after the site was rebuilt. The result? A single campaign went out in two versions. Five hundred test addresses got subject and text A; number five hundred and one got subject and text B. The system recorded the send as a complete success. No real reader noticed a thing, but the tests proved that our fixes were only shrinking the windows.
After two days, we realized it wasn't about patching the code anymore. We had to build on a much sturdier foundation to completely eliminate the risk of these race conditions.
04
One file owns the truth
On July 17, we introduced a SQLite database as the core of the system. A single file. It is readable from both PHP and Node, it handles transactions, and it locks itself. The database sits outside the folder visitors can access, with permissions strictly limited to the owner. Both environments refuse to start if the file permissions are wrong.
Everything the newsletter needs to remember lives there: subscribers, confirmation tokens saved only as hashes, rate limiters stopping abuse, campaign statuses, and the history of every issue ever sent. This is also where every update Postmark sends about an address is saved: an unsubscribe, a spam complaint, or an address that stopped working. All of this arrives through a single, secure front door. The database updates are short, and no write is held open while we wait for the network. The database never locks up because of a slow connection.
The most important detail of the design is the separation of powers. SQLite owns consent: does the person want the email? Postmark owns deliverability: is it even possible to send it there? A subscriber gets the newsletter only when both say yes. Neither of them is allowed to overwrite the other's decision. If an address permanently fails (a "hard bounce"), delivery stops, but it doesn't change the consent record. An old confirmation link can never override a fresh unsubscribe. Every 24 hours, a script compares the two, cleans out expired invitations, checks the database health, and saves a verified backup. We keep 35 daily copies, and one per month for a year.
Consent also has a front door. We gave it the same care.
05
Two steps in, one click out
Subscribing takes two steps: you enter your address on the web and click a link in an email. That click starts the subscription directly — no extra page, no extra confirmation button. We put a lot of effort into the security around that link. It is signed, it only works for a single click, it dies after 48 hours, and the server only saves a fingerprint (a hash) of the token. Even if the database leaks, a confirmation cannot be faked. If a corporate antivirus scans the link, it sees a valid page, but it doesn't start the subscription. Only a real visit from a browser does that.
Our system gives the exact same response whether the address is new, already exists, or is invalid. You cannot fish for subscribers. Invisible honeypot fields that bots fill out but humans don't see, and rate limits for both addresses and IP numbers, keep the garbage out.
Leaving, on the other hand, takes just one click. At the bottom of every email is a link from Postmark. One click on it ends the subscription instantly. No login, no extra steps. The asymmetry is the point: two steps in to avoid mistakes, one click out because the person who wants to leave has already made up their mind. The engine's only job is to permanently record that decision and never argue back.
When we moved the list from the old WordPress plugin, we applied the same logic to the import. It didn't wake up anyone who had unsubscribed, and if the import hit a broken address, it stopped entirely rather than loading a partial list. The doors were built. What was left was the content itself, and the moment we fire it off.
06
Record first, send later
What lands in the inbox is built at the same time as the website, from the exact same text file. Our code generates a clean, single-column HTML document that works in email clients. All design is baked right into the elements (inlined CSS), and we include a plain-text version. We don't force a background or text color, which means the recipient's native dark mode works exactly as they are used to. If the text is too long, it gets cut off at the end and points to the web, keeping the email under 90 kilobytes. Gmail clips anything over roughly 102 kilobytes, which risks hiding the unsubscribe link at the bottom. We have zero tracking in the email: no hidden pixels, no tracking links. The engine knows what Postmark delivered, but not a thing about what readers do next.
The sending step is where we structurally eliminated the risk of errors. When the campaign is prepared, a fingerprint (a hash) of the exact HTML and text going out is saved. Before the sender starts, it verifies that hash. Then it records the intent to send in the database: which issue, the payload, how many people will get it, and a receipt of the exact list. Only then does it send. One single, massive request to Postmark's Bulk API, containing the email body and the full list of recipients. No loop sending a small batch at a time. No temporary file remembering where a crashed program left off.
Either Postmark accepts the request and we track it via an ID, or it fails in one of two ways. If we get a flat no, we can fix the problem and tell the system to try again, but that requires a human pressing a button. If the answer is ambiguous — like a server timeout or the network dropping — everything stops. The entire send freezes until someone checks the database against Postmark's logs. The tool we built for that reconciliation is extremely pedantic. It checks the request ID, subject line, recipient count, and timestamp before accepting Postmark's status as the truth.
There is no "send immediately" command. The database strictly limits campaigns to one (1) run per issue. We didn't just patch the race conditions we found — we structurally eliminated them.
07
A simulated Postmark to rehearse against
You don't test this kind of thing against real email. Instead, our tests set up a completely fresh environment for every run: a temporary folder deleted afterward, a local database, a pre-built draft, and a mock version of Postmark's server. Four programs run concurrently against the same database to prove the database locks actually do their job under pressure. The tests never touch our real servers or passwords. They run in the CI pipeline on every code change, and once more on the server right before deployment.
The suite contains 78 test cases. They are more like fire drills than regular unit tests. We simulate two people clicking a confirmation link at the exact same time — the token activates only once. We test what happens if status messages from Postmark arrive out of order, so an old decision doesn't overwrite a new one. We prove that once an issue has been cleared to send, exactly those reviewed bytes are sent — even if the source code changes afterward. A half-finished signup is never thrown out until the timer actually expires. And the bug that sent two different texts to the same list? It remains permanently in the test suite, just to prove it can never happen again.
Those drills are what made it possible for us to compress a whole week's manual work into a few keystrokes.
08
Armed
The Sunday routine is now driven by a terminal panel we start with two letters: tj. The panel compares the code we have with the latest draft from Johan's Obsidian. It displays the versions locally, on GitHub, and on the server, and refreshes every ten seconds. Options that aren't available are grayed out with a clear explanation, so there is no guessing why.
[i] import the newest issue from the vault, commit only that issue, and upload it
[l] build and toggle the background local preview
[t] send the checked candidate to one remembered test address
[a] arm/disarm the checked revision for Monday 06:00
[u] unsubscribe one reader locally and at Postmark
[c] copy the current issue as rich HTML for LinkedIn
This is what a Sunday evening looks like now. Johan finishes the text in Obsidian. He presses [i]. The machine imports the text, shrinks the images, commits the change, pushes it to the server, and waits for a receipt. The draft is now on the server, reviewed and ready, but hidden from the world. [l] opens a preview on the screen. [t] fires a test email to a saved address — the exact code going out, via the same servers, but without being recorded in the database.
Then comes the critical step. Johan presses [a]. The command arms the revision — and its unique hash — for Monday 06:00. What we load the machine with is literally the exact bytes going out. If anything changes before Monday, like fixing a typo and redeploying, the machine disarms itself. Nothing sends until Johan actively chooses to arm the new version. Another press on [a] disarms the release. And the machine can't just forget about it: if the clock strikes 06:00 and three hours pass without a send going out, the alarm sounds.
Johan closes the lid. A draft is armed. The machine handles the rest.
09
Monday 06:00
At 06:00, the server wakes up. First, the update runs: tests execute and the site is built twice. The hidden build contains the new issue and the emails. The public build only shows the history of previous issues. The gate that hid future-dated posts no longer exists — it was replaced by a rule that lets the send itself decide what is visible. The risk of the site leaking the content early is gone, because the file simply isn't in the public build.
Then the sender steps in. It verifies that the code it's running is the exact version Johan armed yesterday. It reconciles the list with Postmark one last time, clears out anyone who left, records the decision to send, and fires the API request. When Postmark says "yes," the database notes the issue as sent. The site rebuilds in five seconds and goes live. Only when the posts are up on the web does the sender start tracking the delivery. Anyone who opens the email at 06:01 clicks a link to a site that is already working.
If anything goes wrong, the process stops. An alarm is emailed out, and the old site remains online. For three hours after that, a routine check runs every fifteen minutes. It can fix a dropped publish step or resume tracking a send, but the system itself stops it from accidentally firing a brand new email. Failed sends only restart when a human presses the button, and if it's completely stuck, everything halts until we take a look.
After breakfast, Johan does one last thing: [c] copies the entire issue as rich HTML with embedded images, ready to be pasted into LinkedIn.
The first morning the machine ran its course completely without adult supervision was July 20.
10
Three Mondays later
The email we armed that first Sunday opened with the words "Goodbye Wordpress!" The very first thing the machine did was wave goodbye to its own predecessor. At 06:00 the server updated, the request was accepted, the web updated, and the entire list got the issue in their inbox. Then it went up on LinkedIn. Week 30 is in the archive.
That was three weeks ago now. Two more Mondays have passed without a single bump. The human role has shrunk to what it always should have been: write the text, press four keys, go to sleep. The yearly subscription for the WordPress plugins is canceled. The hour-long routine of manual handling is gone. What's left is the cost per email at Postmark, and a small codebase we own from end to end. We let Claude Fable 5 write the engine. We let GPT-5.6 review the safety. We stress-tested everything against a local mock server. And the newsletter is still written by hand.
It is a model that works for any process where the critical moment cannot be undone. Invoice runs, customer mailings, payroll. Put the responsibility for state in one single place (the database). Make arming an active decision tied to exact bytes. Record the intent before you step out onto the network, and stop the machine at the slightest doubt instead of guessing. Rehearse mistakes on a clone. Then Mondays are boring, exactly as they should be.
Have a process that must run exactly once?
The engine firing off Tech Insights was built in six days. We reviewed it until every window was closed. We design and build machinery around irreversible processes: with clear ownership, strict arming rules, and safeguards that pull the emergency brake when something looks wrong. Does your organization have its own Monday 06:00? Get in touch.