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.