10 KiB
Magnum Opus — Design Document
Core Concept
A unified productivity system built on standard protocols (IMAP/SMTP, CalDAV, CardDAV). Email, tasks, calendar, and contacts share a single threaded interface. Everything that enters the system must be processed (inbox zero). The email thread is the fundamental unit — projects are just bigger threads.
Build for ourselves first, but with clean abstractions to make it a product later.
Inspirations
- macOS Mail (UI feel, three-column layout)
- Thunderbird (protocol breadth)
- OmniFocus (GTD task management depth)
- GTD / Inbox Zero (methodology)
- Emacs org-mode (file-based power — but too inaccessible)
Key Principles
- Standard protocols — IMAP/SMTP for email, CalDAV for tasks/calendar, CardDAV for contacts. Opening the same accounts in Apple Mail or Thunderbird shows normal, unmodified data.
- Unix philosophy — compose existing tools (mbsync, vdirsyncer, notmuch), don't reimplement them.
- Files are the source of truth — Maildir, VTODO, VEVENT, vCard. Syncable with any service. Theoretically usable from the CLI.
- Append-only history — nothing is deleted, ever. State changes are recorded like accounting entries. Export-and-compact is the only way to drop history (per-project or globally, e.g., yearly).
- Progressive disclosure — simple by default, structured on demand. Complexity surfaces only when the user needs it.
- Meet users where they are — familiar GUI, standard workflows. No new paradigms to learn.
Architecture
Backend (Uberspace)
Hono/Node API layer orchestrating unix tools:
mbsync→ IMAP sync to Maildirvdirsyncer→ CalDAV/CardDAV sync to local files- SQLite as a derived cache (rebuildable from files at any time)
- REST API for mutations, SSE (Server-Sent Events) for real-time push to clients
The backend is a thin coordinator and API layer. It does not reimplement mail or calendar protocols.
Storage
Files are the source of truth:
| Data | Format | Sync Protocol |
|---|---|---|
| Maildir | IMAP (via mbsync) | |
| Tasks | VTODO (iCalendar) | CalDAV (via vdirsyncer) |
| Calendar events | VEVENT (iCalendar) | CalDAV (via vdirsyncer) |
| Contacts | vCard | CardDAV (via vdirsyncer) |
SQLite indexes everything for fast queries, resolves dependency graphs, computes "what's actionable now." If the cache is lost, rebuild from files.
API
- REST (JSON) for all mutations (triage, compose, create task, defer, delegate, etc.)
- SSE for real-time push (new email arrived, deferred item resurfaced, delegated item timed out)
- Clean API enables multiple clients: macOS, iOS, web (future), CLI (future)
Clients
- macOS (SwiftUI) — primary, v1
- iOS (SwiftUI) — primary, v1
- Web — possible later
- CLI — theoretically possible since everything is files
Data Model
The Inbox
A unified queue of heterogeneous items:
- Emails arriving via IMAP
- Self-created tasks (VTODO)
- Delegated items returning with responses
Every item must be triaged: do / defer / delegate / file / discard.
Everything Is a Thread
The thread is the universal container:
- An email conversation is a thread
- A task with notes is a thread
- A project is a thread that grew (multiple tasks/emails linked together)
- The detail view always shows a threaded timeline mixing emails, tasks, notes, events
Tasks (VTODO)
Standard iCalendar VTODO with GTD enrichments:
| Concept | VTODO Property |
|---|---|
| Title | SUMMARY |
| Description | DESCRIPTION (plain text) |
| Defer / hide-until date | DTSTART |
| Deadline | DUE |
| GTD contexts (@office, @phone) | CATEGORIES |
| Status | STATUS (NEEDS-ACTION, IN-PROCESS, COMPLETED, CANCELLED) |
| Priority | PRIORITY (1-9) |
| Subtasks | RELATED-TO;RELTYPE=PARENT |
| Dependencies | RELATED-TO with FINISHTOSTART (RFC 9253) |
| Link to email | ATTACH:mid:<message-id> |
| Notifications | VALARM |
| Custom enrichments | X-properties (energy, time estimates, etc.) |
Dependency-Driven Visibility
- If task B depends on task A, B is hidden until A is done
- Inbox / Today / Forecast views only show actionable items
- SQLite cache resolves the dependency graph
Projects
Projects emerge organically through progressive disclosure:
- Any thread with 2+ tasks automatically becomes a project
- Can be explicitly promoted early (even with one task)
- Simple projects: just grouped tasks in a thread
- Complex projects: add dependencies, milestones, phases as needed
- Projects live in the sidebar under "Projects" and open as threads in the detail view
Delegation & Waiting Loop
Delegation is an active tracking loop, not fire-and-forget:
- You delegate a task → Magnum Opus sends an email to the assignee
- The item moves to "Waiting" with a link to the original thread
- Each waiting item has an expected response window (configurable default + per-item override)
- If the window expires without response, the item automatically resurfaces in your inbox
- Assignee responses (email replies) are threaded back into the project context
- Future: external portal via link in delegation email — assignees can update task status, attach files, mark done without a Magnum Opus account
Accounts
- Multi-account is a first-class concept in the data model
- v1 supports one account; architecture allows adding more
- Each account = one IMAP + one CalDAV + one CardDAV connection
Append-Only History
- No deletes. State changes are recorded like accounting entries.
- Full audit trail from the moment the user starts using Magnum Opus.
- Export-and-compact is the only mechanism to drop history:
- Can be run on an interval (e.g., yearly)
- Can be scoped per-project
- Produces a clean snapshot of current state with no historical links
GUI
Layout
┌─────────────┬──────────────────┬─────────────────────────┐
│ SIDEBAR │ ITEM LIST │ DETAIL / THREAD VIEW │
│ │ │ │
│ Inbox (3) │ ✉ RE: Q1 plan │ Threaded timeline: │
│ Today │ ☐ Draft spec │ - Email from Alice │
│ Upcoming │ ✉ Invoice.pdf │ - Your reply │
│ Forecast │ ☐ Review PR │ - [Task: write spec] │
│ Projects ▸ │ │ - Email from Bob │
│ Waiting │ │ - [Note: decided X] │
│ Someday │ │ - [Event: meeting] │
│ Archive │ │ │
│ Tags ▸ │ │ │
│ Accounts ▸ │ │ │
└─────────────┴──────────────────┴─────────────────────────┘
Sidebar Perspectives
| Perspective | Content |
|---|---|
| Inbox | Unprocessed items (emails + self-created tasks) |
| Today | Items deferred to today + items due today |
| Upcoming | Items with future defer/due dates |
| Forecast | Calendar view — events and dated tasks across all projects |
| Projects | All projects (threads with 2+ tasks) |
| Waiting | Delegated items with response tracking |
| Someday | Deferred indefinitely — review periodically |
| Archive | Processed items (filed, completed, discarded) |
| Tags | Filter by GTD contexts and categories |
| Accounts | Account management |
Triage Workflow
- Keyboard-first: single keystrokes for do/defer/delegate/file/discard
- Swipe/buttons: always available for discoverability and iOS touch
- Keyboard is the soul of the interaction
Defer Options
- To a date (item disappears, reappears on that date)
- To a date + time (with notification)
- To a context (@office, @phone — appears when user is in that context)
- To a combination (date + context)
Calendar / Forecast
- Global forecast: "what does my week look like?" across all projects
- Per-project calendar: timeline of events and dated tasks within a project
- Per-task context: when is this due, what's blocking it
Compose (v1)
- Plain text replies, forwards, compose
- Rich text editor is a future enhancement
Contacts (v1)
- Display contact names and avatars from CardDAV in threads
- Autocomplete email addresses when composing
- No contact editing in v1
Standard Mail Client Compatibility
Opening the same IMAP account in Apple Mail or Thunderbird shows normal email. All task/project metadata lives in VTODO files via CalDAV, not inside the emails. The two data stores are linked by Message-ID references in VTODO ATTACH properties.
Technology Choices
| Component | Technology | Rationale |
|---|---|---|
| Backend runtime | Node/Bun + Hono | Matches existing stack, good for API layer |
| IMAP sync | mbsync | Battle-tested Maildir sync |
| CalDAV/CardDAV sync | vdirsyncer | Standard file-based sync |
| Mail indexing | notmuch (or similar) | Xapian-based search over Maildir |
| Cache/index | SQLite | Fast queries, rebuildable, single file |
| API transport | REST + SSE | Simple mutations + real-time push |
| macOS/iOS client | SwiftUI | Native Apple experience |
| Deployment | Uberspace | Always-on, no Docker, shared hosting |
v1 Scope
In
- Single account (IMAP + CalDAV + CardDAV)
- Unified inbox with email + task triage
- Full GTD workflow: do / defer / delegate / file / discard
- Defer to date, date+time, context, or combination
- Task dependencies with visibility filtering
- Projects via organic thread growth + explicit promotion
- Delegation with automatic resurfacing on timeout
- Waiting loop tracking
- Plain text compose/reply/forward
- Contact display + autocomplete
- Calendar/forecast view
- Keyboard-first triage with swipe/button fallback
- Append-only history
- macOS + iOS clients
Out (Future)
- Multiple accounts
- Rich text composer
- External delegation portal (web link for assignees)
- Contact editing
- Web client
- Advanced project views (Gantt, resource allocation)
- Recurring task support (poor ecosystem support)
- Export-and-compact tooling (can be manual/scripted initially)