01
The problem
I kept skipping days on my own learning and lying to myself about it. Streak apps don't work because they're trivially fakeable, you tap 'yes I studied' and move on. I wanted a lock screen that would actually grill me on what I claimed to have done, the way a good coach would. The app's job is to push back when I try to coast.
02
How it fits together
03
What this is built on
- The behavioural-economics literature on commitment devices (Karlan's stickK, Beeminder's monetary penalties, Forest's tree-killing) is the reference. The apps that work make failure expensive in a way the user actually feels.
- The structure of a good cross-examination (Reid technique critique, NIJ structured interviewing) is the model for the interrogator. What makes it hard to fake is asking for SPECIFICS the liar doesn't have. 'What did you build?' is gameable. 'What was the bug, what did you try first, why didn't it work?' isn't.
- Apple's Screen Time and Android's Focus Mode share the same flaw: they can be disabled from inside themselves. If the constraint can be turned off when willpower is low, it does nothing. Settings live behind a PIN.
- OpenRouter's routing model is the fit. Quality on a daily 200-token interrogation is fine across many models. Locking to one provider costs more without a quality benefit.
- Accountability-pod patterns from Nat Eliason and Tim Ferriss are the reference.
04
What I couldn't do
- Has to be impossible to bypass casually, a checkbox isn't enough.
- Has to feel earned to unlock, not annoying, otherwise you uninstall it within a week.
- LLM cost per check-in had to stay near zero, since this fires every day, every user.
- Has to work without the user opening the app, push notification at the lock-time.
- Couldn't be coercive in a way that crosses ethical lines (no surveillance, no shaming).
05
The decisions that shaped it
Decision 01
An LLM interrogator, not a form.
A form asks 'what did you do today?' and accepts any answer. The interrogator reads your claim and asks specific cross-examining follow-ups. Generic 'I studied React' gets pushed back: 'what specifically did you build, what was the bug, what would you do differently?' The system prompt is calibrated to reject vague claims and require specifics.
Decision 02
PIN-locked settings, not user-disable.
If the app can be disabled from inside the app, it will be, when willpower runs out at 11 PM after a bad day. Settings live behind a PIN that was set when the decision was fresh and cannot be changed without re-entering it. Same logic as ScreenTime parental controls. The PIN is checked server-side, so clearing the app cache or reinstalling does not help.
Decision 03
OpenRouter, not major AI labs direct.
OpenRouter routes to whatever model is cheapest while meeting quality bar. For a daily 200-token interrogation, GPT-4o-mini or Llama 3.3 70B is fine. I save 10x vs hardcoding to a single provider, and if one provider goes down the app keeps working. Provider neutrality is the right architecture for high-volume low-stakes calls.
Decision 04
Streak resets on skip, no make-ups, no buybacks.
If yesterday can be bought back with twice the work today, the gamble becomes attractive and skipping increases. Streak loss has to be permanent or it is not a deterrent.
Decision 05
Accountability pods, small groups (3-5), public skip notifications.
Internal motivation is unreliable. External accountability is harder to fool. When you skip, your pod sees it. When they skip, you see it. Built this in (commit 7fbcdb2). Opt-in because forced groups feel coercive.
Decision 06
Public build log, posts of what users built, opt-in.
A public stream of 'today I built X' creates a soft pressure to have something interesting to post.
Decision 07
Grace days, but limited and visible.
Pure no-skip is too brittle. Real life: travel, illness, family emergencies. I added 3 grace days per quarter, visible in the streak UI. Using them costs nothing but is visible to your pod. Skipping without grace days resets the streak.
06
What broke and how I changed course
- Original interrogator was too soft, accepted 'I studied for 2 hours' without follow-up. Tightened the system prompt: 'Reject any claim that lacks specifics. Ask for what was built, what failed, what was learned.' Pass rate dropped 40%. Iteratively rewrote the prompt 6+ times to get the right level of skepticism.
- First model was the model Sonnet, which was overkill and expensive for daily check-ins. Moved to OpenRouter with cheaper routing (Llama / Gemma / Mixtral, picked by cost-quality bid). Quality stayed identical, cost dropped 90%.
- Tried camera-based proctoring, make the user appear on camera during interrogation to make lying harder. Removed it (commit b032662). Reasons: too invasive for the religious and privacy-conscious users I cared about, and it proved you were physically there without preventing lying about what was done.
- Added a leaderboard of streaks. Removed it (commit b032662). Public ranking turned the system into a competition and produced the wrong incentive: people gaming streak length instead of doing work. Built it, shipped it, removed it.
- Re-entry flow: when a user broke their streak, the original UX showed them a sad face and 'streak: 0'. Felt punishing in a demoralising way, not a productive way. Rewrote the re-entry as 'day 1 again, what's the first specific thing you'll build?' (commit 7fbcdb2).
- Initially required sign-up for every visit. Added a guest/demo mode (commit 12cdb83). Users try the interrogator without creating an account, data wipes on tab close. Activation went up about 10x.
07
What I didn't know, and how I learned
- I had not built a NextAuth v5 app before. Spent days on the new auth.config / middleware patterns. NextAuth v4, then v5 is a breaking redesign. Had to rebuild the whole auth surface around the new useSession hook + edge-friendly middleware.
- I underestimated how aggressive my own willpower-bypass instincts would be. Built features assuming users would respect them; tested on myself; immediately broke them by uninstalling and reinstalling. Hardened them against my own future self. The PIN lock is there because I tried to disable it on day 3.
- Prompt engineering for 'be skeptical without being cruel' is a delicate calibration. Overshoot and the app feels mean and people uninstall. Undershoot and it accepts anything. Eventually settled on a tone that's like a respectful old coach: 'I hear you. Tell me more. What was the actual bug you hit?'
- Cron jobs on Vercel free tier max at one per day. I needed multiple, one for daily check-ins, one for streak-loss notifications, one for digest emails. Worked around it by triggering downstream crons from the daily one (chain pattern, same as VANTAGE).
08
What shipped
- Daily lock-screen interrogation, ~200 tokens/day per user via OpenRouter
- PIN-protected settings (anti-cheat against your future self)
- Streak engine with no buy-back, 3 quarterly grace days
- Accountability pods (3-5 users, opt-in, peer skip-visibility)
- Public build log
- Re-entry flow that reframes failure as fresh start
- Guest/demo mode for instant try-without-signup
- PWA, share certificates, OG images, onboarding shortcut
- Removed features (leaderboard, camera proctoring) when they produced wrong incentives
09
What's next
I'd add a calendar-blocking feature: when you set 'I'll build between 7 AM and 9 AM tomorrow', the app automatically blocks distracting apps during that window. Pure check-in is reactive. Pre-commitment + blocking is proactive. Adding next iteration.
What I learned
The leaderboard and camera proctoring both shipped and were later removed when they produced the wrong incentive.