AI automation · 2025 · 6 min read

A newsroom that files itself

In a regulated vertical with high source density and a tiny attentive audience, a deterministic pipeline we built and run files twenty-four articles a day without a human touching a single one.

~720
articles per month
24/day
publishing cadence
99.4%
pipeline uptime
0
human edits per piece

Context

The vertical is regulated, technical, and unusually dense with primary sources. Hundreds of public feeds publish daily, most of them repeating each other with minor variations. The audience is small, sophisticated, and chronically behind. They want signal, not another inbox.

A newsroom staffed to cover that surface area honestly would need a dozen editors working in shifts. The economics don’t support that headcount, and never will. We built the system to match the coverage a small editorial team would produce, without the team.

Why it was worth building

Manual triage in a feed-heavy vertical is the worst kind of work. It is repetitive, time-sensitive, and mostly negative space, since the majority of incoming items are duplicates, off-topic, or low-value. We wanted the attentive audience served on a fixed cadence, which meant removing the human from the per-piece path.

The decision was not to build an assistant that speeds up editors. We built a publisher that runs without them, and hold it to a standard the audience would accept on its own merits. That framing shaped every downstream choice.

How it works

We poll source feeds on a schedule and normalize them into a single item shape. A taxonomy router classifies each item against the vertical’s topic map and drops anything outside it. A vector deduplication stage compares incoming items against a rolling window of recent publications and collapses near-duplicates before any language model is invoked, which keeps cost and noise predictable.

Surviving items are enriched in a single pass: a structured summary, metadata fields the CMS expects, and a headline shaped to the audience’s conventions. Source images are fetched and rehosted to the publisher’s own storage, both for legal hygiene and because upstream hosts are unreliable under repeated access. The finished record is posted to a headless CMS through its admin API. Cron orchestrates the whole chain on fixed intervals.

PUBLISHER LOG · LIVE

04:00:12  router     scanned 312 items  · kept 47  · dropped 265
04:00:48  dedupe     47 candidates     · unique 11 · collapsed 36
04:01:39  enrich     11 items          · gpt-4o ok · 0 retries
04:02:21  rehost     11 items          · 34 images · 0 failures
04:02:57  publish    11 posts queued   · cms ack 11/11
04:03:04  cycle done 00:02:52 elapsed  · next run 05:00:00

What the system actually is

At rest, the publisher is a small Python service, a vector index scoped to the recent publishing window, and a set of cron entries. There is no queue broker, no orchestration framework, no dashboard for editors to babysit. Each stage writes a structured log line, and the logs are the interface.

The CMS is headless and treated as a dumb target. The publisher owns the taxonomy, the deduplication state, and the image store. If the CMS were replaced tomorrow, the rest of the pipeline would not notice. We made that separation deliberately, and it is the reason the system has survived two upstream changes without an incident.

Failure modes are narrow and named. A source feed going dark reduces coverage but does not stall the cycle. A model timeout drops the item and logs it, rather than retrying into a cost spiral. The rehost step is the only stage allowed to block, and it blocks only on its own budget. A Python publisher, a vector index, a headless CMS, and cron. Nothing else earns its keep.

A small editorial team’s worth of manual triage, replaced by a deterministic pipeline that files on a schedule and does not ask for supervision.

— on what the system replaced

Results

The publisher files roughly seven hundred and twenty articles a month at a steady twenty-four-per-day cadence. Pipeline uptime sits at 99.4% measured over the last full quarter, with the remaining time accounted for by scheduled CMS maintenance rather than publisher faults. Average human edits per published piece is zero.

The more interesting result is what we stopped doing. The daily triage loop is gone. The audience receives coverage on a fixed rhythm they can plan around, and the cost of serving them does not scale with the volume of incoming noise. That is the point of the system, and it is the standard any future addition has to meet.

Python publisherHeadless CMSGPT-4oVector dedupecron

Want something like this?

Thirty minutes on what it should do and what it replaces. Free, no deck.

Book a 30-min call