Special edition Vol. I · The making of Saturday, 31 October 2026 Printed at 6.15 a.m. daily

My Newspaper

The story of a daily paper with a circulation of one

Goes to press
6.15 a.m.
every day, in about 2 minutes

Front page

A personal morning paper that writes itself before I wake up.

No feeds to scroll, no apps to open. One page, in the style of an Indian English daily, waiting with my morning coffee.

Every day at 6.15 a.m. a small set of scripts on my Mac reads my inboxes, my YouTube subscriptions, my AI plan limits and my spending, and lays it all out as a broadsheet.

This page is the story of how it went from three separate chat ideas to a live paper in about a day and a half, including the parts that broke along the way.

The live paper opens a copy of today’s edition: the YouTube digest is real, the emails, money and AI usage are made up. My own paper stays private.

Watch the demo

About 3 minutes

My morning, on one page

A short walkthrough of the real thing: the 6.15 morning run, each section of the paper, and where it goes next.

The live paper opens a copy of today’s edition with a real YouTube digest and made-up emails, money and AI usage.

Page 2My Newspaper · The making ofHow it works

How it works

Printed on a MacBook, not in the cloud

From inbox to front page, every morning at 6.15

The paper is printed on my own MacBook, not in the cloud. A scheduled job wakes up at 6.15 a.m., runs each section side by side, stitches the results into one edition, and uploads it to a private site that only I can open.

The morning run: alarm, four reporters, one edition, the login gate, and me with coffee.
Describe this sketch

An alarm clock rings over a laptop showing 6:15: launchd wakes the Mac while I sleep. An arrow leads to four circles side by side, the reporters, marked with an envelope (Inbox), a gauge (AI limits), a play button (YouTube) and a rupee coin (Money). They feed one newspaper labelled edition.json, which passes a padlock (the login gate, checked first) and reaches a stick figure holding a paper and a coffee. Two notes underneath: if a reporter crashes the paper still prints with a "didn't run today" note; if the gate is missing nothing uploads, ever. About 2 minutes start to finish.

  1. The alarmmacOS's built-in scheduler (launchd) starts the morning run at 6.15. If the laptop is asleep, it runs the moment I open the lid.
  2. The reportersEach section is its own small Python program: Gmail, AI Limits, YouTube and Money. They run in parallel, and each one writes a single JSON file that follows an agreed contract.
  3. The editorAn orchestrator collects those files. If a section crashes, hangs or writes something invalid, the paper still prints, with a short "didn't run today" note in its place. The front-page lead is picked by simple rules, not an AI.
  4. The writerSummaries come from one LLM call per section, with the code filling in every link, count and date itself. The model only writes words.
  5. The pressA publish script validates the edition, keeps the last 30 days, and uploads it to Cloudflare Pages. Before every upload it checks that the login gate is still in front of the site, and refuses to publish if it isn't.
  6. The readerI open one address on my phone or laptop, sign in with a one-time email code, and read. The page is plain HTML, CSS and JavaScript reading one JSON file.
The one rule: every section hands in a card of data in the same envelope.
Describe this sketch

On the left, a stack of JSON cards, each ticked, one per section, plus a dashed "next.json?" slot for a future section; all share the same envelope of title, headline and status. They go to a stick figure at a desk, the editor (the orchestrator), who passes one edition to a printer that only lays it out. A note reads: new section? Add a card. Nothing else changes. That's how four sections got built at once.

Design principleEvery section produces data, not prose. The newspaper is only a renderer. That one rule is what made it possible to build four sections in parallel and plug in new ones without touching the others.

Page 3My Newspaper · The making ofWhere it started

Where it started

30 and 31 October 2026

Three chats, one idea

My Newspaper didn't start as a newspaper. It started as three separate conversations with Claude about three small annoyances: emails I forgot to answer, YouTube videos I never had time to watch, and AI plans that ran out of usage at the worst moment.

  • Summarise my emails every morning.I get 15 to 20 emails a day across three Gmail accounts, and some slip through. The first sketch: read each inbox with the Gmail API, drop the noise, and group the rest into Needs action, FYI and Low priority. Delivery ideas ranged from a web page to an email digest to a Telegram message.
  • Tell me what my subscriptions posted.About 90 channels across two accounts, far more than I can watch. The first sketch used a Google Takeout export plus each channel's public RSS feed, with an AI summary per video.
  • How much of my Claude and Codex plans is left?The first sketch called the same private usage endpoints the apps use, with their saved login tokens. That idea did not survive (see Corrections).
Three questions in three chats became three sections of one paper.
Describe this sketch

A puzzled stick figure surrounded by question marks, "too much to follow". Three speech bubbles float beside them: "Summarise my emails?", "What did my channels post?" and "How much AI is left?". Arrows from all three lead into one folded newspaper: one paper, every morning. A note reads: each question became one section of the paper.

Somewhere in the email chat the bigger idea appeared: what if every one of these was a section, and the morning output was a paper? Each source would produce structured data, and one page would lay it all out like a broadsheet.

Early decisions that stuck

Cost must be close to zero. A cloud VM to run it all was proposed and turned down. The laptop I already own does the work.

Sign in with Google, read-only. OAuth with the read-only Gmail and YouTube scopes, so nothing can ever be sent or deleted.

Data first, design later. Agree the JSON shape of every section before writing any section.

How it was built

I built it with Claude in a single project, working like a small newsroom. One conversation acted as the editor, and each piece of work got its own thread: Google setup, contracts, design, one thread per section, one to combine them, one to publish.

Once the contracts were agreed, the Gmail, YouTube, AI Limits, orchestrator and publishing threads all ran at the same time. Code was written and tested in the cloud, copied to my Mac, and run there against my real accounts.

A day and a half, in eight entries

  1. Three earlier chats imported into one project
  2. Google Cloud project and sign-in app set up
  3. JSON contracts agreed, newspaper design approved
  4. Gmail, YouTube, AI Limits and orchestrator built in parallel
  5. Daily 6.15 a.m. schedule installed on the Mac
  6. Site live behind a login, first real edition published
  7. Gmail links fixed, video likes added, X section shelved
  8. Money section live
Page 4My Newspaper · The making ofProofs of concept

Proofs of concept

Nine small experiments

Test the risky parts first

Before any section was built for real, each risky piece was tried on its own, with fake data where possible. Most of these small experiments are still in the codebase as tests and probe scripts.

A lab bench of experiments. "Spiked" is the newsroom word for a story that didn't run.
Describe this sketch

A row of labelled jars on a lab bench, one per experiment, with a scientist stick figure. Most jars carry a green "kept" tick; two carry a red SPIKED stamp, meaning tried, learned and dropped. Notes read: small experiments, cheap mistakes; and every probe printed only what was needed to decide, never secrets.

Each card is a page from the lab notebook. Flip it to see what happened next.

  • Experiment 1 · Hypothesis

    Usage check with saved tokens

    The private usage endpoints for Claude and Codex return clean numbers.

    ResultSpiked

    Dropped

    Reusing consumer login tokens outside the official apps breaks the terms of service.

  • Experiment 2 · Hypothesis

    Read the official apps instead

    Codex has a local app-server that reports rate limits. Claude Code shows the same numbers on its /usage screen, which a script can read from a hidden terminal.

    ResultKept

    Became the AI Limits section

    Both readers run every morning, and neither touches a login token.

  • Experiment 3 · Hypothesis

    Text plus screenshot cross-check

    A second reader (an LLM) can confirm the numbers a pattern-matcher pulled from the screen.

    ResultTrimmed

    Kept the cross-check, dropped the screenshot

    The screenshot was drawn from the same text, so it added cost but no new evidence.

  • Experiment 4 · Hypothesis

    JSON contracts and a validator

    Four very different sources can share one envelope: title, headline, status, issues, then section data.

    ResultKept

    Final v1.0 on day two

    Every section is tested against it.

  • Experiment 5 · Hypothesis

    A "bad morning" mock edition

    The paper can show an expired sign-in, numbers that disagree, a failed section and an unknown future section without breaking.

    ResultKept

    Drove all the error states in the UI

    You can flip between a normal and a bad morning further down.

  • Experiment 6 · Hypothesis

    Design on mock data

    A broadsheet layout works on desktop, tablet and phone, in light and dark.

    ResultKept

    Approved after a 14-fix alignment pass

    The design was signed off before a single real email was read.

  • Experiment 7 · Hypothesis

    Fake APIs and a fake LLM

    Each section can be run end to end offline, including retries and expired logins.

    ResultKept

    Every section shipped with these fixtures

    So every section could be built and tested in the cloud, away from my real accounts.

  • Experiment 8 · Hypothesis

    Model ping and auth probe

    Which models the LLM key can really use, and which way of sending the key each endpoint accepts.

    ResultKept

    Minutes, not hours

    Found the model and header problems in minutes instead of hours.

  • Experiment 9 · Hypothesis

    Metadata-only inbox scan

    Which banks send statements, in what format, without reading a single amount.

    ResultKept

    Shaped the Money section

    The parsers were designed from the shape of the mail, not its contents.

The probe ruleThe rule for every probe was the same: print only what's needed to decide, never secrets or personal content. The statement layout probe, for example, replaced every digit with 9 before saving.

Page 5My Newspaper · The making ofThe sections

What's in the paper

Four sections and one feedback loop

Four reporters and one feedback loop

Each section is a small program that writes one JSON file; the paper only lays them out. Here is the front page of the sample edition, with the parts that matter marked.

The sample edition. Every name, amount and video on it is made up.
  1. The index ear. Lists the sections that ran today, with their page numbers, like a real paper's "In today's paper" box.
  2. The lead story. Picked by simple rules, not by an AI: anything urgent and due today wins the front page.
  3. Usage watch. A markets-style box for AI plans: how much is used, the change in a day, and when each window resets.
  4. Notice to readers. When something went wrong, the paper says so in plain words instead of hiding it.
  5. Money. This month by category against last month, and the card bill's due date.
  6. Video cards. Every new upload, with a watch, skim or skip verdict.
Page 5aThe sectionsInbox

Inbox

Gmail · three accounts

Three inboxes, one list of things to do.

Every morning it reads three Gmail accounts from where the last successful run stopped, so a missed morning never loses mail. Simple rules first throw away one-time passwords and sign-in alerts. The rest goes to the LLM in a single request, which sorts each email into Needs action, FYI or Low priority.

Needs-action items come with a one-line instruction, an urgent flag and a due date when the email has one. Low-priority mail is only counted, with its top senders. Every item links straight to the thread in the right account.

On the first real run

  • 23read
  • 6filtered as noise
  • 1needs action
  • 9FYI
  • 7low priority
  • ~1minute
The Inbox page, sample edition.
Rules first, then one LLM call sorts what's left into three trays.
Describe this sketch

Three inboxes, account 1 to 3, pour envelopes into a sieve labelled "rules first", which catches OTPs and sign-in alerts and drops them. The rest go through one LLM call into three trays: Do, FYI and Low (low is counted only). One letter carries a red "due Fri" tag. A note reads: starts where yesterday stopped, so a missed morning never loses mail.

Page 5bThe sectionsAI Subscriptions

AI Subscriptions

Claude and Codex · printed on pink business paper

A Sensex ticker for my AI plans.

This section answers one question: how much of my Claude Pro and ChatGPT Plus (Codex) allowance is left, and when does it reset? It never touches a login token. For Codex it asks the official Codex app-server for its rate limits. For Claude it opens Claude Code in a hidden terminal, types /usage, reads the screen as text and quits, which uses no plan usage at all.

The LLM then reads the same screen independently. When both readings agree, the numbers are marked verified; when they don't, they are shown but flagged needs check. Claude is read at most once every three hours, because its usage page throttles frequent requests. After a day of history it adds a pace note, such as "at this rate you'll run out before the weekly reset".

On the front page it appears as a markets-style Usage watch box, and its inside page is printed on pink business paper.

The AI page, sample edition.
Two independent readers. If they agree, it's verified; if not, it's flagged.
Describe this sketch

A dark terminal window shows "> /usage", "Current week 72%" and "Resets Sun 4 a.m.": a hidden terminal types /usage, then quits. Two stick-figure readers study it, a pattern reader and an LLM reader (a robot), and both say 72%. If they agree, a green VERIFIED stamp; if they disagree, an orange NEEDS CHECK stamp, and the number is still shown, never hidden. A note: no login tokens touched, Codex asks its own app-server, and Claude is read at most every 3 hours.

Page 5cThe sectionsFrom your subscriptions

From your subscriptions

YouTube · two accounts

89 channels, read for me, before breakfast.

It reads the subscriptions of two YouTube accounts through the official YouTube Data API and picks up every upload since the last run. Shorts are detected and hidden (44 of them on the first run) and just counted. Premieres and upcoming streams are labelled as such.

For 22 talk-heavy channels I picked, it reads the transcript; everything else is summarised from the title and description. One LLM request writes, for each video, a one-line takeaway, up to five key points and a verdict: watch, skim or skip. The code fills in every link, duration and count, so the model can't invent them.

On the first real run

  • 89channels checked
  • 22new videos summarised
  • 44Shorts hidden
The YouTube page, sample edition. Channels and videos are made up.
A funnel from 89 channels to a short list with a verdict on each video.
Describe this sketch

A funnel takes in 89 channels, drawn as generic shapes, and keeps only what is new since the last run. Shorts are tossed into a bin: 44 Shorts hidden, just counted. Transcript scrolls come from 22 picked channels. At the bottom, three badges: Watch, Skim and Skip. Caption: one line, five points and a verdict per video.

Page 5dThe sectionsMoney

Money

Spending · described here, never shown with real figures

Where did this month go?

My bank and card already email me everything: a monthly statement PDF for a savings account, a monthly statement for a credit card, and an alert for every card spend. Money reads those emails. Statement PDFs are password-protected; the passwords live only in a local file on my Mac.

Each statement parser checks that the rows it read add up to the statement's own totals, so a missed line shows up immediately (on the first run, 6 of 6 statements matched).

Categories are decided in layers: fixed rules first, then the bank's own category, then a saved list of merchants it has seen before. Only a brand-new merchant name is ever sent to the LLM, never an amount or account number. Transfers between my own accounts and card bill payments are left out so nothing is counted twice.

The page shows this month by category against last month, spends since yesterday's paper, top places and the card bill's due date.

The Money page, sample edition. Every figure and shop is made up.
The statement stays locked at home; the LLM only ever sees a new shop's name.
Describe this sketch

A padlocked PDF statement whose key stays in the Mac's drawer. A calculator checks that the rows add up to the statement's own total, with a green tick. A shop tag reads "MegaMart" (a made-up name); its amount is covered by a sticky note saying "stays home", because only the name goes to the LLM, a robot, which answers "Groceries". Notes: 6 of 6 statements matched their totals on the first run; own transfers and card bills are never counted twice.

Page 5eThe sectionsLikes

Likes

The feedback loop

The paper is starting to learn what I like.

Every video card has Like and Dislike buttons; tapping the lit one again takes the vote back. Each vote is saved with the video's title, channel and summary to a small key-value store on Cloudflare, behind the same login as the paper.

Nothing is re-ranked yet, on purpose: the plan is to collect two to four weeks of votes first, then let them shape what the YouTube section puts at the top.

Collect first. Rank later.
Describe this sketch

A video card with like and dislike thumbs (tap again to undo). Votes drop into a jar labelled "taste", with the title, channel and summary saved with every vote. A calendar shows 2 to 4 weeks, then a list labelled "then: rank". Bottom line: collect first, rank later.

Try it

What a bad morning looks like

Things break: a sign-in expires, two readings disagree, a section crashes. The paper was designed on a deliberately broken mock edition first, so it always prints something honest.

  • Every section ran and reported in.
  • The lead story is the most urgent email of the day.
  • Usage watch shows verified numbers for both AI plans.
Page 6My Newspaper · The making ofStruggles and pivots

Corrections and clarifications

Thirteen of them

What broke, and what we did instead

Every real newspaper prints its corrections. These are ours: the things that broke, the plans that didn't survive contact with reality, and what we did instead. Each one is written as a headline.

Old plans struck through and rewritten, and one section spiked.
Describe this sketch

A newspaper corrections column. Each old plan is struck through and rewritten beside an arrow: saved tokens become the official apps, Python certificates become curl, a broken link becomes a fixed link. Beside it, a box for X (Twitter): $0.005 per post, free mirrors dead, with a red SPIKED stamp and a shrugging stick figure: not worth it, yet.

Correction 1

Google won't publish a personal app

What went wrong

The sign-in app had to be "In production", or every login expires after 7 days. The Publish button stayed greyed out, and at least eight forum threads that month reported the same thing with no answer from Google.

The pivot

Built a tiny public site with About, Privacy and Terms pages, verified it in Google Search Console, and listed it in the app's branding. Publish unlocked. The app stays unverified, which is fine for my own accounts: one "Google hasn't verified this app" warning per sign-in.

Correction 2

The usage numbers we weren't allowed to read

What went wrong

The first AI Limits plan reused the apps' saved login tokens to call their private usage endpoints. Reading the terms showed that consumer plan tokens are only for the official apps.

The pivot

Rebuilt it to drive only the official tools: Codex's own app-server, and Claude Code's /usage screen read from a hidden terminal. No tokens are ever read.

Correction 3

Claude showed the bill, not the plan

What went wrong

On my Mac, Claude Code signs in through an API gateway, so /usage showed API costs instead of Pro plan usage. Worse, the cross-check model happily "read" numbers off a screen that had none.

The pivot

The hidden Claude now ignores the global settings file and uses a separate Pro login just for the paper. And the model is no longer allowed to fill in a screen with no usage on it.

Correction 4

The models on the menu weren't in the kitchen

What went wrong

The first-choice models weren't available on my LLM plan's key, and one fallback needed a region setting I didn't have.

The pivot

Every call now goes through a fallback chain, and a one-line ping command lists which models answer before anything relies on them.

Correction 5

"Go requires a credential"

What went wrong

I chose Claude Haiku 5.5 at max effort, and it returned 401 even with a valid key.

The pivot

A probe script tried four ways of sending the key and printed only the status codes. Only one header worked (x-api-key). One-line fix, and Haiku has written the summaries since.

Correction 6

Gmail said slow down

What went wrong

The first six-month scan for bank emails hit Gmail's per-user, per-minute quota on two of three accounts.

The pivot

The scanner now spaces out requests, backs off and retries, and opens only a few emails per sender.

Correction 7

Python didn't trust Cloudflare

What went wrong

The publish script's safety check couldn't open the site over HTTPS. Python installed from python.org on a Mac doesn't use the system's certificates, so it refused every connection.

The pivot

The check now uses curl, which trusts the Mac's own certificate store.

Correction 8

Every email link was a 404

What went wrong

Links in the paper opened Gmail's "Temporary Error (404)" page. Gmail rejects the account-in-path link format the code used.

The pivot

Switched to the account-picker format, and the page quietly rewrites links in older editions too.

Correction 9

Where should a private paper live?

What went wrong

It holds my inbox and spending, so it can't just be a public page. Options: an encrypted public GitHub site, Cloudflare behind a login, or Mac-only.

The pivot

Chose Cloudflare Pages behind Cloudflare Access: one-time email code, one-month session, and both the main and preview addresses covered. Direct upload from the Mac, so the data never sits in a Git repo. The publish script refuses to upload unless it sees the login gate first.

Correction 10

The Mac said no to a background job

What went wrong

macOS blocked the assistant from installing the daily scheduled job, a sensible protection.

The pivot

I ran the one install command myself.

Correction 11

Descriptions aren't enough

What went wrong

On the first run, 17 of 22 videos got "skim", because a description rarely says enough to recommend a video.

The pivot

Transcripts turned on for 22 talk-heavy channels I picked; everything else stays description-only to keep costs down.

Correction 12

Even the builder ran out of AI

What went wrong

Midway through the build, Claude hit its own usage limit and had to pause for about 70 minutes.

The pivot

Proof, if any were needed, of why the AI Subscriptions section exists.

Correction 13

X (Twitter): spiked

What went wrong

I wanted posts from accounts I follow. X's free API tier is gone, the free mirror sites are mostly dead, and scraping with a login cookie breaks X's rules.

The pivot

The only allowed route was pay-per-post, about $7 a month for 10 accounts. Not worth it yet, so the section was shelved.

Page 7My Newspaper · The making ofStack and running cost

The cover price

What it runs on, and what it costs

About $10 a month, and that is the LLM plan

Everything else runs on free tiers or hardware I already had.

Parts of the stack, the tool used and the cost
PartToolCost
Printing pressMy MacBook Air, Python 3.12, macOS launchd at 6.15 a.m.Already owned
Gmail and YouTubeGoogle Gmail API and YouTube Data API, read-only OAuth, desktop sign-inFree
AI usageOfficial Codex app-server and Claude Code /usageFree
HostingCloudflare Pages, direct uploadFree
Login gateCloudflare Access (Zero Trust free plan), one-time email codeFree
LikesCloudflare Pages Function and Workers KVFree
Google app branding siteGitHub PagesFree
Front endPlain HTML, CSS and JavaScript, no build step. DM Serif Display, Newsreader and IBM Plex Sans CondensedFree
A price tag of ₹0, plus one LLM plan, with the free services stamped around it.
Describe this sketch

A big hand-drawn price tag reading ₹0, plus one $10 a month LLM plan. Around it, little stamps for each part of the stack, each marked free, and the Mac marked "already mine".

Why the numbers can be trustedThe LLM writes words only. Links, counts, dates, amounts and IDs all come from the code, so a model mistake can make a summary vague but can't put a wrong number or a fake link in the paper.

Page 8My Newspaper · The making ofWhat's next

Tomorrow's edition

What's next
  • A paper that learns.After two to four weeks of likes and dislikes, use them to rank the YouTube section.
  • A proper address.Move the paper to a custom domain of its own.
  • More money sources.Add other accounts and investment statements to Money.
  • Pace that predicts.As usage history builds up, the AI section warns days ahead, not just today.
  • More sections.The contract makes a new section a small, separate job. X may come back if its pricing changes.
You don't need more apps. You need a morning paper.
Describe this sketch

Hand-lettered: "You don't need more apps. You need a morning paper." A stick figure reads the paper with a coffee. An alarm clock beside them reads 6.15 a.m., every day, and a seedling in a pot is labelled "next: likes, then ranking".

The best thing about building your own newspaper is that you're the only reader it has to please.