The pipeline ran every day in July. Every published article started as a rescue.

The 15 July cron ran. The composer failed across the entire batch: drafted=0 on two checklist candidates, one CLI candidate, two day-capped entries. The queue sat empty.

The Santander 8% Regular Saver piece published anyway. Not because the pipeline recovered. Because I checked the batch log, saw the failures, identified the Santander story as the day’s strongest candidate, and pulled it through by hand. Standard rescue.

That was a Tuesday. The Friday before it, the 10th, closed a three-day gap. Each of the 7, 8, and 9 July crons ran and triaged normally but produced nothing publishable. Seven July alone triaged eight clusters to draft; none cleared. The gap closed because I went back, ran the analysis, and rescued two pieces from earlier cycle runs: the stamp-duty update and the Lifetime ISA pillar.

The pattern held across the month.

The July record

10 July: two articles, both rescued from earlier cycle runs after a seven-to-nine July gap. Three days closed by hand.

15 July: the Santander 8% Regular Saver. Rescued from a composer-failed cluster. The rate mechanics were documented, including the variable 5% 12-month bonus dropping to 3% after the promotional window, and the piece cleared the approval gate.

16–17 July: the exception. Both crons produced fully gate-passing ready drafts, the first multi-day autonomous streak. The dead-zone fixes, the verifier, and the dedupe logic all held. The approval gate operated as designed: the BoE hold mortgage piece and the additional-income guide published without manual rescue.

20 July: the fiscal-drag piece. Rescued from that morning’s cron casualties. HMRC projections of 7.7 million higher-rate taxpayers, up 34%; record 40%/45% rate projections alongside. The batch log showed drafted=0 on two checklist candidates, one CLI candidate, two day-capped entries: identical failure pattern to 15 July.

23 July: the May HPI piece. Rescued from the daily casualties, with one change: self-coverage screening ran first. May is a new release (we hold April gov.uk and June Lloyds) so the piece cleared correctly. The check happened before the rescue, not after.

Five publish events. One autonomous. Four rescues.

The exception and what it means

The 16–17 July window is the useful data point. Not because it changed the month’s outcome, but because it proves the pipeline can produce autonomous gate-passing output when the fixes hold.

What happened after that is the question. By 20 July: drafted=0. The exception lasted forty-eight hours before the rescue pattern returned.

The window doesn’t refute the pattern; it defines the gap. When the pipeline works, articles ship without intervention. When it fails, the failures have nowhere to go, and no one is guaranteed to notice they were even candidates.

The structural problem

There is no rescue queue.

When the cron fails, the failed clusters don’t surface anywhere. They aren’t tagged. They don’t accumulate. They exist in log files until someone checks, or they never get actioned. What closed the three-day gap in early July was noticing it on the 10th; if I hadn’t looked at the cadence record, the gap would have been longer.

Every July rescue shared the same precondition: I had eyes on the pipeline at the right moment. The Santander piece shipped because I was already reading the 15 July batch log. The fiscal-drag piece shipped because I checked that morning. The May HPI piece shipped because I ran the coverage check by hand. Each one required me to be looking.

That’s surveillance, not automation.

Improving on the framing in five articles shipped in July, every one of them needed a hand: that article documents what happened. This one names the reason it keeps happening. No rescue queue means no systematic path from “cron failed” to “candidate surfaces for human decision.” The rescue work happened, but informally, driven by whether I looked at the right log at the right time.

A rescue queue changes that shape. When a cluster fails: tag it with the topic, tag it with the failure reason, tag it with the publish-window it missed. Surface it in the morning check alongside the new cron’s output. The decision to rescue, skip, or defer becomes explicit and logged instead of implicit and dependent on attention.

The July record shows this work was already happening informally. On 23 July the coverage screen ran as a rescue-queue operation without a data structure. The 10 July gap analysis was another. So was every triage I ran after a failed cron. The operations existed; the tracking didn’t.

What “pipeline” means

A pipeline implies the pipeline is what publishes. When most publish events require human intervention outside the designed happy path, the pipeline is infrastructure for rescues dressed up as automation.

The output count looks fine from the outside. Articles shipped, cadence maintained, topics relevant. But the accounting is missing. Nothing in the system’s state shows that four of five publish events in July came from manual rescues. I know because I was the one doing them.

That’s the naming problem. The cadence number is the visible metric. The rescue rate is invisible because there’s no place to record it. A rescue queue makes the rescue rate a first-class measurement instead of a number that exists only in someone’s memory.

Out of scope: fixing the composer failure rate, redesigning the day-cap logic, or adjusting the triage cadence. Those are separate problems. The rescue queue is a tracking layer on top of the current failure rates, not a fix to them.

What the July record specifies

Every informal rescue operation from July is a column in the rescue queue table: the topic, the failure reason, the publish-window missed, the self-coverage check result, the decision taken, and when.

The 16–17 July window specifies what autonomous success looks like. The 7–9 July gap specifies what untracked failure looks like. The difference between them isn’t the cron success rate; it’s whether the failures had a queue to land in.

All writing