# Roadmap ## Foundation — current milestone - C++20 domain model and deterministic six-week month layout - Responsive, theme-native ANSI month view with keyboard navigation - Appointment focus, dense-day traversal, and full-frame detail reader - Validated add/edit/delete forms with confirmation and failure rollback - Guarded atomic `.ics` persistence, advisory locking, and round-trip tests - Bounded session undo/redo, exact external-change detection, and backup recovery - Windowed recurrence expansion, compatible RDATE, EXDATE, IANA TZID, and multi-day segment cues - Occurrence-aware appointment search with exact result-to-grid navigation - Session calendar toggles shared by month rendering, focus, and search - Read-only 42-day agenda with bounded recurrence and exact return navigation - Configurable week start with Monday-default CLI and consistent grid queries - Explicit atomic import/export with validation, collision refusal, and backups - Meson build, Nix development shell, desktop entry, and Hyprland launcher - Seeded sample data when explicitly requested, never silent data mutation ## 0.1 — complete local calendar - Advanced recurrence rule editing and detached RECURRENCE-ID overrides - Embedded VTIMEZONE support - Screen-reader-friendly linear view and full Unicode display-width handling ## 0.2 — durable cache and provider boundary — in progress Completed cache foundation: - Provider-neutral SQLite WAL cache in a private local file - Versioned, all-or-nothing schema migrations - Raw provider payload retention, inactive calendars, and event tombstones - Per-calendar/window opaque cursors committed atomically with pulled pages - Normalized event instances for immutable snapshots - Reserved transactional outbox and conflict records for later remote writes Completed HTTP/OAuth boundary: - Generic injected HTTP transport and deterministic fakes, with retries left to provider operations - Public-desktop OAuth authorization code design with PKCE `S256`, system browser, and loopback redirect - Multitenant Microsoft account audience and delegated least-privilege `Calendars.Read`; tenant policy may still require administrator consent or block user consent - No client secret in the open-source desktop binary Completed concrete Linux adapters: - libcurl transport with verified TLS, bounded responses/timeouts, no automatic redirects/retries, and cleartext HTTP only for loopback tests - Shell-free `xdg-open` launcher and one-shot `127.0.0.1` callback receiver advertising `http://localhost:/nocal/oauth/callback` - Mobile/Desktop public-client registration at `http://localhost/nocal/oauth/callback`; Microsoft ignores localhost ports, while literal HTTP `127.0.0.1` needs a manifest edit and IPv6 loopback is not supported Completed token/secret boundary: - Strict, bounded token JSON parsing with a required initial refresh token - Refresh-token rotation with retention of the previous token when a refresh response omits a replacement - Versioned libsecret payloads keyed by opaque local account IDs - Synchronous, cancellable Secret Service calls restricted to worker threads - Real isolated D-Bus/gnome-keyring integration tests - Explicit missing, locked, cancelled, and failure results; no connected account until the complete secret store succeeds - OAuth secrets only in Secret Service, never SQLite, logs, CLI arguments, or environment variables Completed Microsoft Graph read phase: - Public desktop multitenant organizational/personal account support - Delegated `User.Read` for `/me` and `Calendars.Read` for calendars/events; tenant policy may still require approval or block user consent - Per-operation access tokens with persistent tokens retained only by Secret Service - Complete paged all-calendar discovery with atomic cache replacement and deterministic local IDs - Immutable Graph event IDs, strict bounded parsing, and credential-safe errors - HTTPS `graph.microsoft.com`-only opaque continuation/delta links - Half-open UTC event windows and per-page event/tombstone/cursor transactions - Resumable primary-calendar v1 delta synchronization Completed secondary-calendar stable-v1 reconciliation: - Documented per-calendar `calendarView` reads with complete bounded paging - Schema-v2 durable per-window event membership - Atomic complete-window replacement after every page validates - Range omission distinguished from a remote deletion tombstone - Overlapping windows retain events until their last membership is removed - No beta or undocumented per-calendar delta dependency Completed provider-boundary contracts and token broker: - Generic `SyncProvider`/`SyncObserver` contracts for account connect, sync, and disconnect with staged progress events - `OAuthTokenBroker` returning valid per-operation access tokens with a five-minute refresh skew - Refresh rotation persisted before use so a new refresh token is never lost; transient refresh failures leave stored credentials untouched - 400/401 refresh rejections erase the stored secret and surface `AccountDisconnected` for re-authentication - Credential material never appears in exception messages Next provider-boundary slices: - Account setup and CLI/TUI orchestration with live credential integration - Generic `SyncProvider` integration and observable sync status ## 0.3 — CalDAV - Discovery and incremental sync for Nextcloud and standards-compliant servers - ETag-aware writes, offline mutation queue, conflict UI - TLS and failure-path integration tests ## 0.4 — hosted providers - Google Calendar adapter with incremental synchronization - Microsoft 365 read-only discovery and Graph delta synchronization, followed by ETag-aware remote writes after the conflict boundary is proven - Account/calendar management UI and per-calendar ANSI identity The Graph read boundary uses stable v1 delta for the primary calendar and complete stable-v1 calendar views for secondary calendars; it deliberately avoids beta and undocumented per-calendar delta routes. No account UI/CLI orchestration or live Microsoft credential integration exists yet, and remote writes remain out of scope. ## 1.0 — distribution quality - Stable configuration/data format and documented recovery procedures - Nomarchy package, Hyprland defaults, man page, shell completions - Performance budgets exercised against large and adversarial calendars - Fuzzed iCalendar parser, accessibility review, translations ## Quality gates Every milestone requires clean warning-enabled builds, unit and integration tests, sanitizer runs, terminal-state recovery after signals/errors, no network access without explicit account setup, and no loss of unknown calendar data.