Willi Krappen

LifeOS

Personal commitment system: Telegram-first capture, AI structuring, relationship memory, weekly review. PWA with push, everything modelled on a single commitment table.

LifeOS

Key engineering call

One commitment data model for everything — tasks, reminders, promises, events, habits, goals, areas and projects are just type flags on the same table, hierarchy via parent self-reference. One recurrence engine, one status machine, one set of safety rules. Cost: type-flag polymorphism everywhere, queries occasionally get clunky. Pays off because no schema migration is ever needed when a new commitment type shows up.

Not a todo app, not a CRM — a personal operating system for commitments: to yourself (goals, routines), to others (promises, follow-ups) and to reality (events, tasks). Capture is primarily over Telegram in natural language; Claude structures input and asks for clarification instead of guessing. Recurrence is stored as RRULE; reminders run through BullMQ + web push. People are first-class objects with an interaction timeline and configurable follow-up cadence.

Vision in one sentence

Everything in life is a commitment — to yourself, to others, to reality. LifeOS captures, structures and surfaces them at the right time. Not a todo app, not a CRM — a personal operating system.

Capture channels

Phone-first, always. Telegram is the front door — a fast capture line you use on the move to park a thought without opening the app.

ChannelRole
TelegramPrimary capture channel. Natural language in, inline buttons for disambiguation out. Replying to old bot messages revives that thread.
PWA Quick-AddSecondary capture slot when already in the app. Same AI parsing pipeline as Telegram.
Web Push (PWA)Passive reminders, scheduled notifications, gentle nudges — works on iOS thanks to the service worker.
Telegram-ReminderActionable notifications with inline buttons: done, snooze, reschedule.

Sample captures

What the AI turns messy input into:

  • 'call mom tomorrow'
  • 'remind me in 2 weeks to ask Jonas about the move'
  • 'Anna birthday April 12, need gift and dinner'
  • 'every other Tuesday yoga'

Commitment — the core object

Everything that requires action is a commitment. A single table with a type flag and a parent self-reference — areas, projects, tasks and habits are just different views of the same data type.

FieldDescription
typetask, reminder, promise, event, habit, goal, area, project — one data type.
dueDate / scheduledDateHard deadline vs. planned work date. Both on the calendar, treated differently.
recurrence (RRULE)iCal standard. Claude parses natural language into RRULE: 'every 2nd Tuesday' → a real recurrence rule object.
parentArea → Goal → Project → Task → Subtask. Arbitrary depth, one data model.
linkedPeopleWho is involved / whom it was promised to. Direct join to the person.
linkedGoalWhich long-term goal this commitment serves.
commitmentStrengthHard promise / soft intention / idea. Affects sorting and UI weight.
status + snoozeUntilopen / in_progress / done / snoozed / deferred / cancelled. Snoozed items resurface automatically.

Architecture

Classic monorepo: React PWA, Express API, Postgres with Prisma. Alongside it: Telegram webhook, BullMQ on Redis and the Anthropic API.

┌──────────────┐     ┌──────────────┐     ┌──────────────────┐
│  React PWA   │────▶│  Express API │────▶│   PostgreSQL     │
│  (Tailwind)  │◀────│  (Node.js)   │     │   (Prisma ORM)   │
└──────────────┘     └──────┬───────┘     └──────────────────┘
                            │
                    ┌───────┼────────┐
                    │       │        │
              ┌─────▼──┐ ┌─▼─────┐ ┌▼──────────┐
              │Telegram│ │BullMQ │ │Claude API │
              │Webhook │ │(Redis)│ │(Anthropic)│
              └────────┘ └───────┘ └───────────┘
                            │
                      ┌─────▼──────┐
                      │ Web Push   │
                      │ Service    │
                      └────────────┘

Dashboard — what matters right now?

The home screen answers exactly one question. Seven sections, all structured the same way, all derived from the single commitment table.

Today

Scheduled commitments, due items, events, routines.

Overdue

Missed deadlines, unresolved items.

Upcoming

Preview of the next few days.

Open loops

Promises to / from others, outstanding items.

People

Who needs attention, follow-ups due.

Goals

Progress, streaks, drift warnings.

Inbox count

Unprocessed captures needing triage.

Weekly review — guided flow

Appears in the dashboard on Monday, triggered by a scheduled push. Six steps; also manually accessible any time.

  1. 1

    Clear the inbox — process all unstructured items.

  2. 2

    Review commitments — overdue, stale, reschedulable.

  3. 3

    Someday / maybe — deferred items worth reconsidering.

  4. 4

    Relationships — who needs attention, outstanding promises.

  5. 5

    Goals — progress check, drift detection, AI-suggested next actions.

  6. 6

    Plan the week ahead — schedule key commitments.

Key engineering decisions

One data model for everything

Tasks, reminders, promises, events, habits, goals, areas, projects — all the same Commitment table with a type flag. Parent relations build the hierarchy. One schema, one recurrence engine, one status machine.

Capture-first, structure-second

Inputs are allowed to be messy. 'Anna birthday April 12, need gift and dinner' lands in the inbox; the AI extracts a person, a date and two follow-up commitments. What stays unclear gets asked — not guessed.

AI assists, never decides

On ambiguity the system asks via inline-button multi-choice or free text. Important data is never silently changed. Haiku handles fast micro-operations, Sonnet does the heavy parsing.

RRULE instead of a custom recurrence format

iCal RRULE covers everything — daily, weekly, biweekly, 'every 2nd Tuesday', custom cron. Widely supported, compatible, no custom recurrence engine to maintain. On completion the next instance is auto-created; completed instances are archived, not deleted.

Relationships as first-class objects

A person has context, an interaction timeline (manual + auto from commitment completion), a follow-up cadence, open loops. The system actively surfaces who needs attention — not a CRM data grave.

Ephemeral AI conversations

Conversation is ephemeral per interaction session; context ends after successful extraction. Only replying to old bot messages revives the original thread. History is kept for 24h then pruned — only the extracted commitments persist.

SSE instead of WebSockets

Live dashboard updates run over Server-Sent Events. Simpler than WebSocket, sufficient for 'unidirectional + reconnect', saves complexity on both server and client.

Notification batching with hard caps

Quiet hours, per-category mute, frequency caps, smart batching of low-priority items into digests. Sensible defaults, fully configurable — nobody gets spammed.

Deployment

Self-hosted on a VPS, Docker Compose for Postgres and Redis. The Telegram bot runs in webhook mode on the same server. VAPID keys are server-generated, JWT has no expiry for persistent sessions, simple username/password auth via bcrypt. Online-only — no offline sync, no sync-headache.