Ozym

BUILDING OZYM: A CALM NEWS APP IN A WORLD THAT WON'T STOP YELLING
A behind-the-scenes write-up
Ozym is scheduled for release in the summer of 2026.
Okay. Pull up a chair. Because I want to tell you about something I built that, on the surface, sounds almost old-fashioned — and underneath is one of the most modern pieces of software engineering I've put my name to.
It's called Ozym. And here's the pitch: it's a news app that gives you ONE digest a day, drawn from real verified sources, where every single story is cross-checked across at least two outlets — and then it gets out of your way. That's it. No infinite scroll. No likes. No little red notification dots engineered by behavioural scientists to hijack your Tuesday. You read it, you close it, you go live your life.
In an industry that has spent fifteen years figuring out how to keep your thumb moving, building something designed to END is — and I mean this — a radical act. That's the whole reason I made it.
-- WHERE THE NAME COMES FROM (because it matters) --
Ozym is short for Ozymandias. Shelley's poem. The shattered statue in the desert, the king who built a monument to himself, and the inscription that's outlived everything: "Look on my works, ye Mighty, and despair." Now — most people read that poem and root against the king. But there's another character in there that I couldn't stop thinking about. The sculptor. The one who "read well" the passions on the face and carved them faithfully. The mediator. The one who told the truth and outlasted the propaganda.
That's the app. Ozym is the sculptor, not the king. It doesn't build an empire of engagement. The old digests stick around to prove the thing worked, but the article bodies get pruned after sixty days — on purpose — because it refuses to become a monument. A news app with a conscience. Imagine that.
-- THE STACK, AND WHY EACH PIECE IS THERE --
Now here's where it gets fun, because this isn't a toy. It's a real multi-agent AI system, and every tool in it is there for a reason. Let me walk you through the band.
CLAUDE (Anthropic) is the brain. The writing brain. There are actually a few different Claude models doing different jobs — and that's the clever part. The big, careful one (Claude Sonnet) writes the summaries: 120-to-180 words, neutral tone, and it has to flag where the sources DISAGREE rather than papering over it. Then a faster, cheaper one (Claude Haiku) does two other jobs — it slaps quick topic labels on story clusters, AND it acts as a second pair of eyes that re-reads every summary against the original articles, hunting for any claim that isn't actually supported. Different model for different cost-and-care tradeoff. That's not showing off. That's economics.
OPENAI is here for exactly one job: embeddings. The text-embedding-3-small model turns every article into a list of 1,536 numbers — a kind of mathematical fingerprint of its meaning. Why OpenAI and not Claude for this? Because it's a specialized, dirt-cheap, fast operation, and that model is genuinely excellent at it. Use the right tool for the right screw.
PINECONE is the vector database — and this is the magic trick that makes the whole product possible. Once every article is a fingerprint of numbers, Pinecone lets you ask: "which articles are SEMANTICALLY close to this one?" Not same keywords — same MEANING. So when the BBC, Al Jazeera, and a wire desk in Berlin all cover the same event in totally different words, Pinecone is what clusters them together. That cross-outlet clustering IS the product. Without it, you've just got an RSS reader.
SUPABASE (Postgres under the hood) is the system of record. Sources, articles, clusters, the published digests, and the user accounts and subscriptions. It also handles auth: sign in with Google or Apple, or a one-time email code as a fallback.
LANGGRAPH.js is the conductor. The whole pipeline is built as two explicit state machines — little flowcharts where each AI agent is a labelled node and you can see exactly which step ran, when, and whether it passed, failed, or got skipped. Why bother? Because "we have an AI pipeline" means nothing if you can't SEE inside it. Every node writes a row to an observability table. When something breaks at 4am, I can reconstruct the entire run step by step. That's the difference between a demo and a system.
EXPO / REACT NATIVE is the app itself — one TypeScript codebase, Android and iOS. VERCEL hosts the backend. REVENUECAT handles the billing (more on the money in a second). RESEND sends account email — and ONLY account email, the sign-in codes and service notices.
Oh — and it's a paid app. $3.99 a month, seven-day trial. No ads, ever. When the product doesn't make money from your attention, it can afford to respect it. The whole business model is the ethics.
-- THE STUFF THAT BROKE (the good part) --
Anybody can list the tools. Let me tell you where it bled, because that's where the real engineering lives.
THE CLUSTERING DIAL. Early on, I set the "how similar is similar enough?" threshold tight — 0.78 — and it was beautifully precise. Too precise. The same story would shatter into separate clusters because the BBC and Al Jazeera worded it differently, and that broke the whole premise: you need TWO sources to publish, and fragmentation was starving stories of their second source. The fix was to loosen the dial to 0.74. Sounds trivial. It's the difference between the product working and not working. Tuning, not magic.
THE FOUR-DAY SILENT OUTAGE. This one's a great war story. The pipeline runs on GitHub's servers. And on those servers, the standard modern way of making web requests — a library called undici — was quietly choking when it tried to decompress responses. I'd patched the Anthropic calls to go around it. But I MISSED the OpenAI embedding calls. So for four days, articles came in, but nothing got embedded, nothing got clustered — and nothing screamed about it. A silent four-day embedding blackout. The fix was a shared, bulletproof request helper that EVERY AI service has to route through — no exceptions, no "I'll get to that one later." The lesson, written in blood: the dangerous outage isn't the one that crashes loudly. It's the one that fails quietly.
THE DISAPPEARING STORIES. Published digests were re-reading their stories live at request time. But the clustering job sometimes MERGES clusters after the fact — and when it merged one a published digest was pointing at, the story just... vanished. Blank slot. The fix was elegant: at the moment of publishing, FREEZE the stories into an immutable snapshot. A published digest no longer depends on anything that can change underneath it. Yesterday's news stays yesterday's news.
-- NOW — THE CLOCK. THE GITHUB ACTIONS TIME DRIFT. --
I saved this one for you because it's my favourite, and because the fix is a genuine engineering judgment call rather than a tidy textbook answer.
The heavy lifting — all that AI synthesis — runs on GitHub Actions, GitHub's automation runners. Great deal. Free compute. But there's a catch nobody tells you on the way in: GitHub's scheduled jobs are NOT punctual. When their servers are busy, your "9:00 AM sharp" job drifts. I watched the daily digest slide later and later — twelve minutes one day, a full sixty the next — and on one memorable occasion the scheduled run simply... didn't show up. Ghosted. No digest.
So here's the workaround I built, and it's a beautiful little piece of duct tape. Instead of trusting GitHub's flaky alarm clock, I use a DIFFERENT, reliable alarm clock — Vercel's scheduler — to fire at 9:00 AM on the dot. But Vercel can't do the heavy AI work; it'd time out. So Vercel's job is tiny: it just reaches over and TAPS GitHub on the shoulder and says "go, now." GitHub does what it's good at — the big compute — and Vercel provides what it's good at — punctuality. Two services, each covering the other's weakness. The run now starts within seconds of nine, every day.
Is it the FINAL fix? No — and I'll be straight about that. The truly bulletproof solution is a dedicated scheduler that owns the timing end to end, and that costs money. At this stage, a free workaround that WORKS beats a paid one I don't yet need. So it's logged, it's monitored, and it's on the roadmap with a clear note: when the budget says go, I close it for good. That's the part I'm actually proud of — knowing the difference between "broken" and "good enough for now, and I know exactly why."
-- THE FINISHED THING --
So here it is, fully built. You wake up. There's one digest waiting. A handful of the day's real stories — each one woven from multiple outlets, each one telling you honestly where the reporting agrees and where it doesn't, every source cited so you can go deeper if you want. You can highlight a few words that matter to you and the app gently marks them everywhere they appear. You read for eight minutes. You close it. There is no "next." There is no feed. You are DONE — and you are genuinely, calmly informed.
A finite end, every single day, in a world that has forgotten what those feel like.
That's Ozym. (It's not on the app stores quite yet — that's the last mile — but the thing itself is done and running.) I built it because I'm obsessed with both the craft AND the conscience of the thing — multi-agent AI, vector search, the works, all of it in service of an app whose entire ambition is to take up LESS of your life.
Look on its works, ye mighty. And — for once — relax.
This project is still in progress — the full write-up is on its way.