Personal planning, 2026
Lumen Daily
I built Lumen Daily to catch a thought in one sentence and carry it everywhere it matters. It works offline and guards my privacy. It has run my days since the first week it existed.
- Built for
- Independent product
- Role
- Product direction, design, and build
- System
- Vanilla JS PWA, Cloudflare Workers + D1, IndexedDB
- Where it stands
- Live, installed, and used daily, with authenticated personal access and a privacy-safe public demo.
My notes stayed where I left them.
I’ve never had trouble writing things down. The trouble came after I’d written them down: a note would sit wherever I left it, and unless I happened to look in the right place at the right moment, it may as well not have existed. What I needed was one place that would bring things back when I could act on them.
Capture saves the sentence, then sorts it.
Everything I put into Lumen Daily goes through one box. I write the thought in my own wording, and the sort into a task, a reminder, or a note happens after the entry is saved.
Each demo pick runs one capture.
Three fabricated examples: a task, a reminder, a reflection. The post lands on a live endpoint on this site’s own edge; Lumen Daily’s private API stays untouched.
Clear your head.
Write it once. Lumen Daily will put it where it belongs.
Capture saves the original sentence first, then works out where it goes.
What happens to one sentence, in five steps.
One timed reminder, traced from the box to the receipt. The sentence keeps its wording at every step.
The wording is kept as I typed it.
Capture stores the thought before it's sorted.
Saved before anything else happens.
If I'm offline, IndexedDB holds the capture until the connection is back, and when it replays with the same idempotency key, D1 records it exactly once.
The Worker saves the sentence, then one Claude job sorts it.
Every typed capture lands in D1 as an inbox row and a sorting job in one batch. Captures in the same 15-minute window share that job, and when the wording is unclear the sorter files it for me to decide.
One write reaches three destinations.
A timed thought becomes exactly one Actions reminder, one Today entry, and one Calendar event.
A receipt shows the route.
Web Push delivers it when it comes due.
The wording is kept as I typed it.
Capture stores the thought before it's sorted.
Remind me to call the dentist tomorrow at 1
Saved before anything else happens.
If I'm offline, IndexedDB holds the capture until the connection is back, and when it replays with the same idempotency key, D1 records it exactly once.
The Worker saves the sentence, then one Claude job sorts it.
Every typed capture lands in D1 as an inbox row and a sorting job in one batch. Captures in the same 15-minute window share that job, and when the wording is unclear the sorter files it for me to decide.
One write reaches three destinations.
A timed thought becomes exactly one Actions reminder, one Today entry, and one Calendar event.
A receipt shows the route.
Web Push delivers it when it comes due.
Actions · Tasks
Ready when the work begins.
Today · Tomorrow
Journal · Daily Reflection
Keep what mattered.
The evening walk helped me reset
Actions
Every action keeps the sentence I typed.
Each tap writes once, and a receipt records it.
Original sentence retained · Anywhere
- 01Saved, then sortedLive
One Claude job filed it under Task.
- 02Committed onceNext
Offline replay and network retry reuse the same durable identity.
- 03Reversible with historyThen
Undo changes the current state without deleting the original receipt.
Ready for an action.
One durable identity prevents duplicate writes, and Undo keeps the original receipt. The Worker saves the sentence before one Claude job sorts it.
A task tied to a place surfaces on the day my plan puts me there.
Lumen Daily reads the mode from my plan, then surfaces everything held for that place at once.
Stored per date and versioned. No location permission is ever requested.
Tasks captured for a place are held in Actions until the day’s mode matches, then surfaced together. The mode is read from the plan alone.
Full day4 blocks
- Why there’s no geofence
- The mode comes from my plan, so the app never asks for location permission.
Operational proof
Six rules I enforced under the surface.
Software decides everything it can, Claude gets only bounded jobs, and everything ships private.
- Machinery
Claude gets one bounded job per capture batch.
The Worker writes the inbox row and its sorting job in one D1 batch, and the job covers a 15-minute window. A submitted photo creates one parsing job the same way.
- Offline state
Offline captures replay when the device reconnects.
Stable idempotency keys and D1 mutation receipts prevent an offline replay from becoming a duplicate.
- Automation
I removed the pollers.
The one scheduler left can't run the same slot twice.
- Observability
I can see why a job stopped.
Every request-backed job is a durable row carrying its attempts, next attempt, and error category.
- Boundary
The recovery route is absent from the public build.
A test asserts that absence. The demo ships through a six-file allow-list.
- Shape
I added versioning after a real conflict.
The day's mode carries a version because two devices were editing one date; a stale write returns 409 and refreshes instead of overwriting.
Logging a workout on a treadmill.
I gave Plan two ways to log a workout without filling in a form: a plain sentence, or a photo of the machine's screen.

Movement summary
Both inputs create the same session record.
Either explicit source creates one bounded route. Unreadable values are never invented.
Treadmill
- Time
- 38 min
- Distance
- 2.4 mi
- Calories
- 285 cal
- Incline
- 4%
Tonight · chosen from the pool
Lemon pasta
Bright, quick, and linked to its recipe and shopping context.
- TonightLemon pasta
- Still in the poolSheet-pan salmon
- Still in the poolTurkey taco bowls
- Produce · 2 lemonsLinked to tonight
Returned context carries a link to its source.
Lumen Daily pulls from my email and returns private notes when I ask for them. Work in progress comes back with the state I left it in.
A private note moves after I request it.
Request-only source
Session recap
Complete · Summary available
Waiting for an explicit request.
Latest recap
Session recap
- Protect recovery time after demanding weeks.
- Name the decision instead of carrying the whole question.
The same email is filed once.
Appointment confirmed
Dentist visit
Tomorrow · 1:00 PM · Fabricated
Tomorrow
Dentist visit
- Calendar
- 1:00 PM
- Reminder
- 12:30 PM
I can resume a thread from where it stopped.
Cedar House
Brand guide
Summary ready · concise by design
The handoff is ready when you are.
Workstream handoff
Ready to resume.
- Last completed
- Voice and tone pages approved.
- Next move
- Draft launch captions from the approved voice.
A fact is kept only after I approve it.
Operational data lives in the database. The facts that describe a life are different: preferences, constraints, the things worth still knowing next year. Those live in their own private repository, and nothing gets there until I approve it. Revisions are versioned, so a bad fact is corrected by moving a pointer. Most nights nothing is approved, so the filer ends without filing anything or making a commit.
From build to habit
Where Lumen Daily stands now.
I stopped opening Lumen Daily to test it. It's the app I open every day now, from my home screen, and it holds me to the things I said I'd do.
- Live
- Production
- Installed
- Home screen
- Trusted
- Daily use
- Offline replay
- Verified without duplicates
- Public demo
- Synthetic and isolated
- Release checks
- Nine contract suites