Devlog #22
Table of Contents
Devlog — 2026-11-09#
TL;DR#
1.17.0 shipped: skip any task, checklists, drag-between-groups, and a brand new Decision log. Then I spent the back half of the week being paranoid — a big security pass on auth and the web app, plus performance fixes for things I’d been quietly ignoring. Turns out “it works on my phone” is not a threat model.
User-facing features#
- Skip any task, catch up on overdue ones. Swipe right on anything due today or overdue. One-off moves to tomorrow, recurring jumps to its next date. Doesn’t count in stats, streaks or goals. Undo included. Android, iOS, web.
- Checklists inside tasks. Tick them off as you go. Recurring tasks reset them each round.
- Drag a task between groups — energy, priority, status, date. Android, iOS and web.
- Decision log. New place to write down what you decided and why (Future You will ask). Android, iOS and web.
- Up to three daily toads, plus an off switch if you hate frogs. Mobile and web.
- Task search. Mobile search on the Tasks screen; web search now matches description, tags, every word, and ignores accents.
- Tag autocomplete with “did you mean #work?”
- Session window rework. Shift start by 5 or 15 minutes, start right after your last session, one-tap length presets (no more 4-hour ceiling). Focus rating is gone from the form — old ratings stay.
- ±5 min on the idle timer, mobile and web.
- Undo bar for tasks — short, batched, swipe to dismiss. Web also offers Undo after archiving.
- Settings: Prompts & tips (re-enable dismissed coachmarks, collapsible) and a Rate Kombine row.
- iOS native date and time pickers instead of my homemade ones.
- Web: other devices’ changes now show up on every main page without a refresh.
- Fixes you’d notice:
- Overdue monthly task keeps its day (Jan 31 → May 31, not May 28).
- Clearing a due date cancels the reminder.
- Tasks stuck in a sync conflict now sync; the conflict message stops nagging.
- Goals carry-over works after swiping between periods.
- Duplicate briefcase icons on activities gone.
- Decision editor sits flush on the keyboard; edit/delete menu actually works.
- Dark-mode and contrast fixes on web.
- Android notification for a running timer no longer goes stale.
Technical improvements#
- Security sweep on auth. Refresh-token reuse is now detected and kills the chain, rotation is bound to the device, per-account login throttling (IPv6-aware), demo accounts rate-limited. Scoped tokens can’t pose as web sessions anymore.
- Web hardening. Host-only cookies, request body caps before parsing, import row caps, secrets redacted from request logs, stored values kept out of inline scripts.
- Android delta sync was silently skipping. It reported success and sent nothing. Task changes never left the phone. Fixed, and it now fails loudly. (Yes, I’m also embarrassed.)
- Sync pulls got smarter. Full task pull is paged properly instead of reading one 200-row page; pull-to-refresh does a delta; archived tasks stay out of the full pull.
- Timer & battery. Ongoing notification uses the system chronometer instead of being rebuilt every second; timer UI recomposes only what ticks. Logs are batched instead of one request per line.
- Backend perf. Task lists no longer aggregate whole session history; hub pushes only timer transitions, not every heartbeat; web uses one timer socket per tab and dropped an always-on poll.
- Deploys got safer. Graceful drain fits inside the kill timeout; migrations run in the release step.
- Date-only due dates use a single 12:00 UTC anchor across clients and server, with one reader. Kills a class of off-by-one-day bugs.
- Session updates are partial now — send what changed, not everything.
- Release pipeline sends Play “What’s New” from the repo; docs drift cleaned up.