Everyone has a list of chores they know how to do and still haven't done. The refund never claimed, the subscription still charging, the deposit the landlord never returned. None of them are hard. They stall because someone has to send the first message, and the first message usually gets ignored.
Any model will tell you what to write. What it won't do is send the follow-up five days later when nobody answers, and then a firmer one after that. That second half is about patience, not knowledge, and patience is exactly what software is good at. Overdue is built around that gap. It was my entry for OpenAI Build Week 2026, in the "Apps for your life" track.
You dump the chores in messy words, something like "cancel gym, refund for the broken headphones, chase landlord about deposit". Overdue turns each one into a ready-to-send email, a call script or a direct action link. Each draft carries the facts that make the other side respond, like a chargeback window, a cooling-off period or a consumer-protection clause, and every one of those claims shows its source. When a message goes unanswered, the task climbs a ladder on its own: polite, then firm, then formal, with each new draft waiting for your tap.
One rule holds the whole thing together. The model proposes, plain code validates, and you authorize. The model never sends anything and never changes a task's state. Extraction treats your dump as untrusted data, never as instructions. A pure TypeScript layer then assigns ids, drops low-confidence guesses, removes duplicates, resolves dates and stamps every field as extracted, inferred or default, so an inferred date never shows up looking like a fact. The escalation engine is a state machine with an injected clock, and every send has a tap in front of it.
The constraints shaped more than I expected. Free model access went through GitHub Models, which allows about 10 requests a minute and 50 a day. A judge clicking around a live demo would burn through that in minutes. So the demo path makes zero model calls: Load demo fills the queue with five seeded tasks and pre-baked drafts. The model id sits in one constant, so swapping it is a one-line change. All task state lives in the browser's localStorage. There's no database and no accounts, and two thin server routes hold the API key and make the model calls.
My favourite part is the time-travel control. Nobody wants to wait five days in a demo to watch a message escalate, so the clock is faked, but it drives the real escalation engine. The clock is fake. The logic isn't.
How it got built is worth saying plainly, because the repo says it too. I ran the build with two coding agents in one long session. Claude Code wrote the design spec and the task-by-task plan, then reviewed and committed each result. Codex wrote the code, one task at a time, test-first for the schema and the three pure modules: validation, the curated rules and the escalation machine.
What I took from it: the most useful design decision wasn't about the model at all. Keeping every irreversible step in plain code behind a human tap made the AI part easy to trust, and easy to test.