AI transformation · Agent governance · Production reliability
At a glance
Why this problem is hard right now
At 09:38 every morning a cron job wakes an AI agent. By the time anyone opens their inbox the research is done, the sources are checked and a brief has gone out. Nobody watched it happen.
That is the easy half to demonstrate and the hard half to trust, and the gap between those two is where most enterprise AI programmes are currently stuck. Organisations have no shortage of models that write a good draft in a chat window. What they do not have is a model that can be left alone on a schedule for six months without producing something that embarrasses them.
The failure modes that matter here are not modelling failures. They are operations failures, and they are boring in a way that demos never surface. The agent repeats a story it already sent on Tuesday. A credential expires and the send fails quietly. The job never fires at all, which is the failure nobody notices for a week because nothing arrives to notice. Something reaches a customer list that no human ever approved.
Every one of those is a governance problem wearing an engineering costume. That is why AI pilots stall at the demo stage: the demo proves the model can do the task, and proves nothing at all about whether the organisation can let it.
The situation
The client publishes to two audiences with very different risk profiles.
Internally, the team needed to stay current on a field that moves weekly, without anyone spending their morning reading. That meant a daily brief and a Sunday roundup, both to staff.
Externally, they wanted a bi-weekly edition going to an opted-in subscriber list. Real people, real inboxes, a real brand attached.
The third one carried effectively all of the risk, and the instruction on it was explicit and dated: every send to that list is approved by a person, every time. No exceptions, no automation that could be triggered by adding a contact, no drip sequence that fires on its own.
So the brief was awkward in a useful way. The system had to be autonomous enough to be worth running at all, and fenced tightly enough that the one path with brand exposure could never fire without a human hand on it. Those two requirements pull in opposite directions, and resolving that tension is the actual work.
What organisations in this position usually get wrong
The common mistake is to treat the whole thing as one system with one reliability standard, then try to make the model trustworthy enough to carry the riskiest part of it.
That approach fails in a specific way. Teams write longer and longer prompts, adding rules each time something goes wrong, until the prompt becomes a policy document that nobody has tested and the model still occasionally ignores. Instructions to a model are requests. They are not guarantees, and they degrade quietly as the context fills.
The second mistake is trusting a system that cannot report its own failure. A scheduled AI job that succeeds ninety-five percent of the time looks healthy right up until the week it does not run, and if the only signal of health is “an email arrived” then silence is indistinguishable from a quiet morning.
The third is putting marketing mail and internal mail down the same pipe because it is simpler. It is simpler, and it puts subscriber consent inside your own application code, where it does not belong and where an engineer who has never read a privacy statute is now responsible for it.
How we approached it
We split the system along the line where the reliability requirement changes. Research is non-deterministic by nature, so a headless agent does that. Delivery has to be correct every single time, so ordinary Python does that.
The agent researches, then writes a structured file in a fixed schema, and stops. It has no send capability at all. Separate orchestrators pick that file up and handle the archive write, the render, the CSS inlining, the delivery and the heartbeat. The unpredictable half of the system physically cannot touch the half that has to be right.
That separation is the whole design, and everything else follows from it.
We took the calendar away from the model. Issue numbers and publication dates belong to the orchestrators, not the agent. An agent permitted to choose its own issue number will eventually choose the wrong one, and the way you find out is a subscriber replying to ask why they received issue fourteen twice.
We gave the agents a shared memory. Every published item lands in an archive database. Before the daily agent researches anything it reads the last five days and rules out what it has already covered. Then a deterministic dedup pass runs afterwards regardless, as a backstop, because the instruction to the model was a request. The Sunday roundup reads seven days out of that same archive to rank its picks, so the weekly is built from what the daily actually found rather than from a second independent trawl.
We made silence noisy. Any exception emails an alert and exits non-zero. Separately, a second cron runs roughly an hour behind each scheduled send, at 10:30 after the daily and 17:45 after the weekly, and does nothing except check that a heartbeat was written. That catches the failure class the job itself cannot possibly report, because a job that never started cannot raise an alarm about not starting.
We put five independent gates in front of the subscriber list. Sending is disabled by default. Four further conditions each force a dry run on their own, so any single misconfiguration degrades to a no-op rather than to an unintended send. The scheduled job renders, stages a draft, and emails a preview. A person opens that draft in the mail platform and clicks send. There are no automations on the list, no welcome sequence, no drip.
We kept the marketing claims out of the model’s reach. Course names, prices and links come from a single source file rather than from whatever the agent wrote. Agent copy that drifts off the approved wording gets canonicalised or stripped before it renders.
The call we had to make
We ran marketing mail and transactional mail down completely separate paths, which is more plumbing than a newsletter appears to need.
Internal briefs go over transactional SMTP. The subscriber edition goes through a campaign API, so unsubscribes and suppression are handled by the platform that is legally built to handle them. One shared path would have been faster to build and would have parked subscriber consent inside our own code. We were not willing to own that.
We also changed email providers mid-build. The original relay content-blocked the larger weekly edition and rejected it outright. The alternative was to trim the newsletter until the relay accepted it, which would have meant letting an infrastructure limitation quietly set editorial policy. We changed the relay instead.
What the engagement could not fix
The system is only as current as the sources it can reach. Where a story lives behind a login or on a platform that blocks automated readers, the agent cannot see it, and no amount of prompt work changes that.
We also cannot claim the briefs are exhaustive. They are sourced, deduplicated and checked, and the agent is instructed to resolve any social-media signal back to a primary source before it can be included. That is a floor on quality, not a guarantee of coverage.
And the human gate on the outbound edition is a real cost, not just a safety feature. It means that edition goes out when a person gets to it. We think that is the correct trade for brand exposure to a subscriber list, but it is a trade, and an organisation that wants fully hands-off outbound publishing should know we would argue against building it.
What went wrong
On 11 June 2026 the system went quiet.
A credential had died and the sends stopped. That part is ordinary. The uncomfortable part was that the alerting ran through the same path as the thing that had broken, so the system had no way to tell anyone it was broken. It sat there, failing correctly and silently, exactly as designed and exactly wrong.
Two changes came out of that morning. The alert channel now runs on its own separate credential, so it survives a failure of the main one. And both scheduled wrappers now run a preflight verification before they are permitted to send, so a dead credential fails loudly at the start of the run rather than silently at the point of delivery. Both were tested live rather than assumed.
We would rather publish this than the version where nothing ever broke.
What transfers
This is a newsletter, and the newsletter is the least interesting thing about it.
The transferable asset is a pattern for putting a non-deterministic system into a place where being wrong has a cost. A model that proposes. Deterministic code that disposes. Every irreversible action sitting behind a gate that a person controls. Health signals that fire on absence rather than only on error, because the dangerous failure in scheduled AI is silence.
That is the same shape an enterprise needs for AI-assisted underwriting decisions, automated customer communication, agentic workflow in a regulated process, or anything else where the question is not can the model do it but can we let it. Our answer to that question is architectural, not a longer prompt.
The five-gate pattern in particular travels directly. When a client asks how they stop an agent doing something irreversible, the answer is not to instruct it more firmly. It is to make the irreversible path structurally unreachable without a human, and then to test that the gates hold when misconfigured.
Where it stands
The daily brief and the Sunday roundup publish without anyone touching them. The subscriber edition renders, stages a draft and waits for a person, which is what it was built to do.
The failure that took the system down in June is now the failure it is best instrumented to detect.

