From Personal Tool to Public Product — Scaling the AI News Bot

This is a sequel to Building an AI News Bot in 2 Days. If you haven’t read that, the short version: I built a personal AI news curator with my coding agent Harry, went through 15+ iterations, and ended up with a slot-based v2 ranking engine that delivers a daily digest to my Telegram.

The v2 engine was solid. The output was good. I was using it.

Then the obvious question hit me: why keep this to myself?

The live feed is up at llm-digest.com.


Hardening the Pipeline

Before going public, the pipeline needed to be tighter. I asked Harry to review the full system end-to-end and tell me what needed work.

What we fixed:

  • Config presets — standardized configurations so the system can be tuned without understanding every knob
  • Richer diagnostics — each run now emits detailed telemetry: slot priorities, LLM usage, source health, timing breakdowns
  • Git hygiene — cleaned up tracked artifacts, proper .gitignore for runtime data
  • Slot quota rebalancing — increased total items and adjusted per-slot allocations for better coverage

Small stuff individually. But the kind of stuff that separates “it works on my machine” from “it works reliably.”


The Vercel Pivot

I asked Harry: “Can we deploy this to Vercel so other users can get the feed too?”

The typical instinct would be: set up a database, build an API, deploy a server. Harry suggested something simpler: use GitHub as the content store.

Think about it — the feed artifacts (digests, processed JSON, diagnostics) already live in the repo. They get updated every run. All we need is a static site that reads those files and renders them.

So that’s what we’re building: a static Astro site (same engine as this blog) that serves the feed as a web page. GitHub is the database. Vercel auto-deploys on every push. No server to maintain.


Discovering Sources by Browsing

Here’s where it got interesting. I wanted to expand beyond RSS feeds to find content from X, Medium, and Substack. The usual approach would be to set up API integrations. But APIs need tokens, rate limits, and ongoing maintenance.

Instead, I gave Harry browser access to my accounts and said: “Go browse and tell me what quality sources you find.”

What He Found

Medium — my following feed surfaced strong engineering publications:

  • Netflix TechBlog
  • Airbnb Tech Blog
  • Pinterest Engineering

The insight: use a publication-level allowlist, not the raw following feed. My Medium follows include too much noise.

Substack — the strongest signal. My home stream had:

  • Alberto Romero (The Algorithmic Bridge)
  • Steve Yegge
  • Kent Beck

These are high-quality, low-noise sources that would meaningfully improve the feed.

X — useful but noisy. Lots of hot takes mixed with genuine insight. Needs much tighter filtering to be useful as a source.

Decision: defer social platform collectors for now. The RSS-based sources are already strong, and adding social platforms introduces complexity (auth, rate limits, content extraction) that isn’t worth it yet. But we know exactly where to look when we’re ready.


Scheduling: Leaving the Cloud

The pipeline originally ran on GitHub Actions — cron-triggered, simple. But there was a problem: our LLM integration uses local OAuth (via pi-ai), which doesn’t work in a GitHub Actions runner.

So we moved scheduling entirely to local cron, managed by OpenClaw:

  • 09:00 KST — morning digest
  • 12:00 KST — midday refresh
  • 19:00 KST — evening digest

Three runs a day. The field moves fast enough to justify it.

GitHub Actions still exists as a manual trigger for one-off runs, but the daily cadence is fully local.


Closing the Auto-Deploy Loop

Here’s the problem we didn’t see coming: local cron runs don’t trigger Vercel deploys.

The pipeline runs locally, updates the digest files, publishes to Telegram and GitHub Issues. But Vercel only deploys when it sees a push to main. Our local runs weren’t pushing anything.

Harry’s fix was clean:

Pipeline run

Build digest

git pull --rebase --autostash  (stay in sync)

Commit changed artifacts

git push to main

Vercel auto-deploy triggers

Telegram + GitHub Issue publish

Now every successful cron run pushes updated feed data to GitHub, which triggers a Vercel redeploy, which updates the public-facing web feed. Full loop closed.

Added a kill switch too: AUTO_PUSH_RUNTIME=0 disables the push if you want to run without deploying.


The Pattern

In a single day, this project went from “personal tool that texts me” to “deployable product with a public web presence, 3x daily auto-refresh, and a content pipeline that syncs local execution with cloud deployment.”

I keep coming back to the same pattern:

  1. Build for yourself first. Don’t think about “users.” Solve your own problem.
  2. Iterate until the output is good. Not the code — the output. What you actually see and use.
  3. Generalize only when it’s working. The jump from personal to public should be small if the foundation is right.
  4. Keep the architecture boring. GitHub as a database. Static site on Vercel. Cron jobs. No Kubernetes. No message queues. No microservices.

The boring stack is the one that ships.


What’s Next

  • Web feed — public Astro site serving the daily digest (in progress)
  • RSS output — so others can subscribe in their own readers
  • Multi-language summaries — same content, Korean and English versions
  • More sources — Substack and Medium integration when the ROI is clear
  • Open sourcing — once the rough edges are smoothed, the whole pipeline could be useful to others

The tool keeps growing. But it started with one frustrated engineer who was missing important news. Everything else followed from there.