‹  Today

How Diff works

A scheduled pipeline reads about 48 sources each weekday at 6:30am Eastern, picks the three things that moved, and publishes them here. Every tap you make flows back into what tomorrow’s run selects and what Sunday’s quiz asks.

At a glance

Sources~48 feeds and sitesfetched 6:30am ET, weekdaysPipelineextract, select, write, validatethe only part that calls modelsEditionthree new items + Still openSundays: quiz and taskReader appthumbs + reason, Done,quiz answersWhat Diff learnsreading state, thumbs, skills mapseen, acted, proven, missedranks picks, aims the quizInstructionsprompt, sources, profiledraft, preview, commitSources~48 feeds and sitesfetched 6:30am ET, weekdaysPipelineextract, select, write, validatethe only part that calls modelsEditionthree new items + Still openSundays: quiz and taskReader appthumbs + reason, Done,quiz answersevery tapWhat Diff learnsreading state, thumbs, skills mapseen, acted, proven, missedranks picks, aims the quizInstructionsprompt, sources, profiledraft, preview, commit

The pipeline, stage by stage

Ordinary code that calls models at fixed points — no model ever decides which step runs next, so every run takes the same path and fails in the same places. Each stage is its own retried step on Inngest.

ExtractFetch~48 sources in parallel, a step eachRSS, sitemaps, HN, arXiv, HF, YouTube, XExtractHaiku 5.5 turns pages into dated candidatesstops the run if most extracts failTransformCarrycode picks up to 4 unfinished itemsfor Still openBuild contextcandidates, last 8 editions, skills map,held items, instructions, thumbs*Select + writeOpus 5.5, thinking streamed120 s of silence = hung; 720 s = too slowValidateschema, content rules, URLs were fetchedfails: errors back to the model, up to 2xWeekly passSundays: diagram, 5-question quiz, taskanswer positions shuffled in codeLoadAssemblenew + carried items, source-health note,thumbnails embeddedSavedigests, item_state, conceptsNotifyone push with the top headlineRecordruns: status, cost, structured audit logClay = model call · dashed = Sundays · rest is code* withheld every other weekday (exploration days)ExtractTransformLoadFetch~48 sources in parallel, a step eachRSS, sitemaps, HN, arXiv, HF, YouTube, XExtractHaiku 5.5 turns pages into dated candidatesstops the run if most extracts failCarrycode picks up to 4 unfinished itemsfor Still openBuild contextcandidates, last 8 editions, skills map,held items, instructions, thumbs*Select + writeOpus 5.5, thinking streamed120 s of silence = hung; 720 s = too slowValidateschema, content rules, URLs were fetchedfails: errors back to the model, up to 2xWeekly passSundays: diagram, 5-question quiz, taskanswer positions shuffled in codeAssemblenew + carried items, source-health note,thumbnails embeddedSavedigests, item_state, conceptsNotifyone push with the top headlineRecordruns: status, cost, structured audit logClay = a model call · dashed = Sundays only · everything else is code* thumbs are withheld every other weekday (exploration days)

Why it isn’t an agent

The whole design fits in one line: ordinary code, models at fixed points, and every tap read back.

Ordinary code. A normal program runs the same steps in the same order every morning: fetch the sources, pull out what’s new, choose and write, check, save, send the nudge. No model decides what happens next.

Models at fixed points. A model is called at three known steps, each with one job: a fast model pulls items out of each source, a strong model chooses and writes the edition, a mid-size model grades quiz answers. Code checks every answer before it’s used; an edition that doesn’t match the format gets one retry.

Every tap read back. Your thumbs, ✓, Keep and quiz answers are saved, and the next run reads them. That’s all the learning is: better input on the next run, which you can see and undo. Nothing is retrained.

The model decides what’s worth reading. The code decides what happens next.

What changed from v1

v1 ran for two weeks as an AI agent: a scheduled Claude session, handed the instructions and a set of tools, that worked through the morning’s job on its own. The writing was good. Getting it to arrive wasn’t.

v1 — an agentDiff — a workflow
Who picks the next stepThe modelThe code
Fetching sourcesTool calls the agent made, each needing permissionPlain code: no model, no permissions
When something goes wrongThe run waited for someone to tap Allow, and hung. Four of its last five runs stalledEach step retries on its own, and a failure names the step
Your feedbackA tap couldn’t reach the next runEvery tap is saved and read by the next run
Where you read itA republished web pageAn installable app with a morning nudge and offline reading

What stayed: the content rules. v1 proved the digest was worth opening, and its two weeks of real editions are where Diff’s rules come from.

The rule of thumb: use an agent when the path can’t be known in advance. Diff’s path is the same every morning, so letting a model choose it only adds ways to fail.

What each tap changes

Feedback ranks; it never excludes. There is no downvote and no dismiss.

SignalWhat it changes later
Thumbs up + reasonSelect sees your last 40. Useful = more of that kind; interesting = widen to adjacent debates; well made = presentation, not topic.
Done ✓The item stops appearing in Still open. Handled, not rated.
SeenThe concept moves from “no signal” to “seen” in the skills map.
Quiz answerRight = proven, re-checked in 7 → 14 → 30 → 60 days. Wrong = back into the dailies and the next quiz.
Weekly taskProves every concept it covers.

Two guards keep feedback from narrowing what you see: every other weekday the pipeline gets no thumbs at all, and silence never counts as rejection.

Reliability, from production

FailureFix
4 of 18 runs published nothing — the model thought silently for minutes, indistinguishable from a hangStream its thinking; 120 s of silence = hung, a separate 720 s cap = slow
Saved-for-Sunday items lost when a Sunday failedLook back to the last weekly that actually published
Every X post rejected for having no dateDecode the date from the post’s ID
The audit log grew 4× in three weeksStructure it; only standing issues carry forward
A deploy failed fetching Google FontsBundle the fonts

Changing the instructions

Edits are drafts — the 6:30 run never sees them. A preview runs every real stage with the drafts and publishes nothing. Commit writes git first, then the live copy, and refuses if the repo moved underneath it. Live and git never drift.