The AI news service that feeds this blog
Disclosure: I let Claude write this entire post — prose and all — then published it close to as-is. The last two meta posts were mine, with AI as the editor. This one is the inverse, on purpose: the subject is a machine that reads the news and writes things up for me, so it felt only fair to let the machine write up the machine. Read it knowing that. If it reads like slop, that’s the experiment failing in public, which is also worth something.
The writing tools I built solved the back half of the problem. They made it easy to take an idea and turn it into a post without letting AI quietly take the keyboard. What they never touched was the front half: where the idea comes from. An empty /new-post scaffold is still empty. Something has to fill it.
For me that something is the news. I write about AI and markets, which means staying near the frontier, which means drinking from a firehose of newsletters, lab blogs, X threads, and a daily avalanche of papers. I was doing a bad job of it. AiSecret and Platformer piled up half-read. I never once opened the actual lab blogs. The good blog angles — the ones where connecting two stories is the whole point — were dying unread in my inbox.
So I built a thing to fix that. It’s the upstream end of the same idea: the news-service finds the thread, the writing tools help me pull it, I write the words.
How I built it
The whole thing is a Claude Code skill plus a handful of plain files in a git repo. No app, no database, no dashboard. That was the one design decision I’d defend to the death:
sources.yaml— the list of places to pull frominterests.md— what I care about, in prose, used to rank and filterstate/seen-stories.jsonl— a ledger of everything it’s already shown me, so nothing repeatstemplates/digest-template.md— the shape of the output- the skill itself — the actual pipeline
Everything is version-controlled text. When the tool changes its mind about a source, that’s a diff I can read. I built the whole thing in one sitting. The git log is honest about it: scaffold, then a first email-only digest, then Gmail delivery plus thirteen lab feeds and two paper feeds bolted on, then a full run. One commit just deletes a source — an X list it turned out I never actually had. The registry is supposed to drift like that.
The part I keep poking at is that it’s adaptive. Every source carries a quality score between 0 and 1. Each run nudges it by a hundredth or two: up if that source’s stories made the cut, down if it was all noise. It also scans my Gmail for newsletters I haven’t registered, classifies them, and adds the AI/tech ones as candidate sources to confirm later. So the tool slowly curates its own inputs. Is that elegant or is it wild overkill for a thing exactly one person reads? Genuinely not sure. I built it anyway because the feedback loop is the interesting part, and a static RSS reader is not a thing worth writing about.
Here’s the contrast that makes this post worth the words. The writing tools have one unbreakable rule: AI does not write the prose. This tool is the opposite — I want it to do the entire job, read everything and write the digest, no human in the loop. Both feel right to me, which means I owe myself a reason. The reason is that a digest is disposable. It’s internal signal, read once, by me. The output of this tool is just the input to my own thinking. Nobody reads it with my name on it. (Except, well, you, right now. Awkward.)
What it actually does
The flow is the boring part — collect, corroborate, rank, write. Two steps in the middle are where it stops being a glorified RSS reader.
The first is corroboration and dedupe. A single model release shows up four times: a lab blog post, an arXiv paper, a Hugging Face daily-papers entry, and a breathless newsletter blurb. A naive tool hands me four stories. This one collapses them into one and treats the fact that it appeared four times as the importance signal. Before it asserts anything surprising it fetches the primary source and runs a web search to find the original announcement, not the newsletter’s gloss on it. That’s the difference between a digest and a rumor mill.
The second is unglamorous plumbing, which is usually where the real work hides. Newsletter emails are enormous — full of tracking links and HTML cruft — and they blow past the context window if you read them directly. So the tool never reads them directly. It saves each one to disk and spawns a separate sub-agent per file whose only job is to return a tight JSON list of stories. The main agent stays clean and never sees the raw mail. None of that is clever. It’s the kind of thing that decides whether the whole pipeline works or quietly chokes on the third newsletter.
It ends by writing a dated digest to the repo and dropping a draft into my Gmail. A draft — never a send. I read it on my phone like any other email, except this one is the only one in the inbox I actually wanted.
What came out
The first real run produced two digests on the same day. A morning one off the newsletters and X, about twenty stories considered. Then a fuller one that layered on thirteen first-party lab feeds and the paper feeds.
The output was better than I expected, and I went in skeptical. A few of the stories it surfaced and stood behind:
- The US cutting off foreign access to Anthropic’s Fable 5 and Mythos 5, and the G7 scrambling for a “trusted partners” arrangement. It caught this in a newsletter, then corroborated it against Euronews and Anthropic’s own statement before it would assert it. That’s the corroboration step earning its keep.
- Noam Shazeer leaving Google for OpenAI — a newsletter item, confirmed across CNBC, Bloomberg, and Axios.
- “Agents as employees” going mainstream — DeepMind’s control roadmap, SK Telecom redesigning around agent identities, Estonia issuing agents digital IDs. That one it assembled from three separate items into a single thread. Nobody in my inbox wrote that story. The tool did, because the relevance lens told it to look for connections, not just headlines.
And then the payoff feature, the only one I actually built this for: every digest ends with a Blog angles section. Under-covered, contrarian, or connective threads, written as suggestions. The first run handed me “agents as employees is an org-design story, not a model story,” and “the junior-engineer question” — engaging head-on with a founder’s claim that AI makes a “1,000x engineer” and renders junior hires unsustainable. Are those finished posts? No. Are they better cold-starts than a blank page? Every time.
Is it any good
I want to grade this honestly, because the easy version of this post is a victory lap and that’s exactly the kind of thing I don’t want to write.
The good news is that it knows what it doesn’t know. When it hit a story that smelled off — a sneaker company renaming itself “Smartbird” and pivoting to buying GPUs, a Midjourney full-body scanner — it didn’t launder the rumor into a fact. It flagged both as low-confidence and told me to verify before citing. It was equally blunt about gaps: OpenAI’s newsletter had nothing in the window, X got sampled lightly to save tokens, and it said so instead of padding.
The bad news is the plumbing leaks in exactly the places you’d guess. The Qwen feed is stale — its newest item is from last September — because the real releases moved to a JavaScript-rendered page with no feed. The tool noticed and flagged it but can’t fix itself. Meta’s research feed served three-year-old cached items. arXiv affiliation matching turned out too weak to rely on, so the paper layer leaned on Hugging Face’s curated set instead — a fine fallback, but not the plan. And the juiciest sources, the ones behind Cloudflare like X and Perplexity, need a live logged-in browser. The moment I try to run this on a schedule with no browser around, they vanish silently.
Here’s the thing I keep landing on: the quality ceiling isn’t the model. It’s the sources and the lens. A good digest is interests.md being right about what I care about. Point it at junk and rank with a junk lens and you get a beautifully corroborated pile of junk. The model is just the part that does the reading.
Which leaves the question I don’t have an answer to. I’ve now built a machine that reads the news through a filter I wrote, and quietly drops everything that doesn’t match it. That’s the point — and it’s also how you end up only ever seeing what you already decided was important. I notice the tension. I’m not going to pretend I’ve resolved it.
What’s next
The obvious next step is a scheduled run every morning, so the digest is just there when I wake up. The catch is the browser-gated sources — a headless run loses X and Perplexity, so it’d have to fall back to email and feeds and admit the gap rather than hide it. After that, better corroboration and letting it auto-label newsletters in Gmail so the signal compounds.
But that’s the upstream half doing its job. It finds the thread. The writing tools help me pull it. I still write the words.
Except this time I didn’t. Did you notice?