Files
Lumotia/docs/roadmap/2026-04-23-magnotia-feature-complete-roadmap.md
Jake 3770815fbf
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
agent: lumotia — v0.1 release-completion run
Closes the code-side v0.1 ship gate. All quality gates green:
cargo fmt/clippy/test (~327 tests), npm check (0/0), vitest 13/13,
scripts/dogfood-rebrand-drill.sh 8/8.

Phase F — first-run onboarding promoted to v0.1
- FirstRunPage with skip-to-main + failure recovery + event recording
- Six onboarding commands (record/list/has-completed + lumotia_events)
- Storage migration v17 (onboarding_events + lumotia_events tables)

UI hardening (in-scope items from v0.1-ui-hardening.md)
- StatusPill + PostCaptureCard components, 21st preview entry
- Sidebar recording-as-sacred-state (opacity + aria-disabled, reduced-motion)
- Settings 6-section regroup + Help section + Activation log + Privacy toggle
- Error-state copy sweep (DictationPage + SettingsPage, plain-language)
- Global :focus-visible rule, textarea outlines restored
- Ctrl+K / Ctrl+, / Escape bindings in +layout

LLM resilience
- rule_based_extract_tasks (regex-free imperative-verb extractor) +
  extract_tasks_with_fallback wrapper — task extraction never returns zero
- tokio::time::timeout(120s) wraps cleanup/tags/tasks commands

Release artefacts
- LICENSE (canonical AGPL-3.0), CHANGELOG (Keep-a-Changelog format)
- v0.1-release-notes, privacy-and-ai-use, install-warnings,
  tester-onboarding-kit, tester-acceptance-runbook, code-signing-setup,
  apple-silicon-rb08-runbook, virtual-audio-setup, v0.1-contrast-audit
- Workspace versioning + AGPL spdx; npm exact-pin (10 ranges removed)
- AppImage SHA-256 sidecar in build.yml
- README v0.1 section + Reporting-issues; canonical repo slug

Closure pass — items moved from human-required to code-complete
- KI-02 Linux idle inhibit: zbus 5 → org.freedesktop.login1.Manager.Inhibit
- KI-03 Windows sleep prevention: SetThreadExecutionState(ES_CONTINUOUS|...)
- acquire/release_idle_inhibit Tauri commands, wired in DictationPage
- Diagnostic-bundle frontend wire-up (Settings → Help button)
- WCAG-AA contrast fix via .btn-filled-text utility (no token changes)
- 8 destructive-action sites wrapped in plain-language confirm() guards
- KNOWN-ISSUES.md + v0.1-known-limitations.md updated (KI-02/03 fixed)

Scripts
- pre-tag-verify.sh, tag-day.sh, smoke-linux + driver
- parse-diagnostic-bundle.sh, parse-activation-log.py

Per-item audit trail: docs/release/v0.1-completion-status.md
Remaining: W-01…W-08 (signing certs, hardware probes, smoke matrix,
tester recruitment) — see docs/release/v0.1-known-limitations.md.
2026-05-15 06:59:08 +01:00

354 lines
27 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: Lumotia — feature-complete roadmap
description: Build plan from 2026-04-23 baseline to full feature-complete v0.1 release
type: roadmap
tags: [roadmap, planning, lumotia, release]
created: 2026/04/23
status: active
author: Wren (CORBEL's resident agent) on behalf of Jake Sames
---
# Lumotia — Feature-Complete Roadmap
> **What Lumotia is.** A local-first, cognitive-load-aware dictation + task-capture desktop app. Vulkan-accelerated Whisper / Parakeet speech-to-text, a local LLM (Qwen3 tiers) for transcript cleanup and task extraction, an MCP server for integration with Claude Desktop / Cline / Cursor, and a UI designed around ADHD / executive-dysfunction needs. Tauri 2 + Svelte 5 + Rust. Zero telemetry.
>
> **Formerly known as Lumotia.** Rebrand in flight; repo names at `jakeadriansames/lumotia` + `git.corbel.consulting/jake/lumotia` still carry the Lumotia name and will rename together with the codebase sweep in the final phase.
## Baseline — where we are (2026/04/23)
**Core MVP (from `docs/brief/feature-set.md`):** 9 of 10 complete.
One gap: **visual time representation** (the spec's "#1 community-requested feature" — shrinking colour disks / progress rings, externalising time passage). The rest — local transcription, auto-populating tasks, WIP limits, history + search, light/dark theming, templates, vocabulary profiles, file upload, open-format markdown export — all shipped.
**Post-MVP (designed, not yet prioritised):** 1 of 9 complete.
MicroSteps is shipped; its "just-start" timer button emits an event that currently has no listener anywhere in the codebase. The differentiating ADHD-specific features (Margot nudges, energy-aware sequencing, rituals, if-then intentions, forgiving gamification, TTS, human-in-the-loop feedback) are all documented in the brief but not started.
**Release-blockers:** 1 — RB-08 macOS power-assertion, pending manual verification on a real Mac (Jake's friend Rachmann has a Mac and can run this offline).
**Workspace state:** main is clippy-zero-warnings, 245/245 tests passing, fmt clean, svelte-check clean, npm build clean. Three dependabot bumps landed this session plus a clippy cleanup pass and a needless_range_loop refactor. One orphan design-system WIP branch parked on github as archive.
## Approach
> **Layer 1 first** (per Jake's standing rule): build the features roughly, in series, through Phase 1 Phase 8. Do polish passes in Phase 9 and QC + release in Phase 10. **Do not mix make-it-work and make-it-neat passes** — every phase ships end-to-end (event wired, UI rendered, store state committed, tests updated) but does not chase aesthetic polish until Phase 9.
> **Ordering rationale.** Phase 1 closes the Core MVP gap and unblocks the already-half-wired just-start timer. Phase 2 enables model improvement by collecting human feedback — useful even while later phases are being built. Phases 38 build the differentiating ADHD-specific features from highest-utility-per-effort to lowest. Phase 9 is polish debt. Phase 10 is release prep (including Rachmann's RB-08 verification and the Lumotia → Lumotia codebase rename).
---
## Phase 1 — Visual countdown + Just-Start timer
**Why now.** Closes the one remaining Core MVP gap. Unblocks the dangling `lumotia:start-timer` emit from MicroSteps. Directly combats time blindness, which the brief names as the single biggest lever for the target audience.
**Scope.**
- `FocusTimer.svelte` — a progress-ring countdown component. Shrinking colour ring (not digital). Subtle colour shift across the last 15%. Remaining time label inside the ring for users who want the number; small enough that the ring dominates the visual field.
- `focusTimer.svelte.ts` store — single active timer, running / paused / completed state, elapsed / remaining computed, event dispatch on state transitions.
- Mount in `+layout.svelte` so the timer persists across page navigation (dictation → tasks → settings).
- Listener for `window` event `lumotia:start-timer` with `{ durationSeconds, label }` payload.
- Trigger from MicroSteps row (already exists). Trigger from task-row context button (new).
- Floating position top-right of main content, above everything, not intrusive when idle (hidden until a timer is running).
- On completion: gentle chime + 3-second ring flourish + OS notification via `tauri-plugin-notification`. No modal. No guilt copy.
- Store survives window close/reopen via localStorage.
**Out of scope for Phase 1.** Rhythmic voice anchoring (part of Margot, Phase 6). Custom-duration picker (fixed 2 / 5 / 10 / 15 min presets for now). Multi-timer UI.
**Acceptance.** From a MicroStep row, clicking the timer button (a) shows the ring visible somewhere on screen, (b) it counts down, (c) at 0 it fires completion + notification, (d) works across page switches, (e) survives a window close + reopen mid-countdown.
**Estimated effort.** Half day.
---
## Phase 2 — Human-in-the-loop feedback
**Why here.** AI output quality is the single biggest determinant of whether Lumotia feels useful. Thumbs-up / thumbs-down on AI-generated micro-steps and task extractions costs almost nothing to add and gives us a feedback corpus the moment anyone uses it. Enables later retraining / prompt tuning.
**Scope.**
- Thumbs-up / thumbs-down buttons on every AI-generated item (micro-step row, extracted task, cleanup paragraph).
- "Edit" path already exists for text; the feedback is additive.
- `feedback` table in SQLite: `item_id`, `item_type`, `rating`, `timestamp`, optional `correction_text`.
- Rust command `record_feedback` + `list_feedback` (for later export).
- No UI surface for viewing feedback yet. Just capture. A future export pass to JSONL feeds prompt-engineering or fine-tuning.
**Out of scope.** Retraining loop, per-user profile adjustment, any UI to view feedback history.
**Acceptance.** Thumbs visible on AI-generated items. Clicking records to SQLite. `cargo test` on storage covers migration + insert + list.
**Estimated effort.** Half day to 1 day.
---
## Phase 3 — Energy-aware task sequencing
**Why here.** Next-highest-utility post-MVP feature. Replaces the cut-for-OS-reasons temptation-bundling feature. Small surface, clear user-facing outcome.
**Scope.**
- `energy` column on tasks: nullable enum `High | Medium | BrainDead`.
- Migration + Rust CRUD.
- Tag chip on task rows; tap to cycle / set.
- Sort / filter option on the tasks page: "Match my energy" → AI surfaces tasks matching a user-set current energy, falls back to `Medium` if unset.
- No automatic energy detection. Pure user input.
**Out of scope.** Time-of-day heuristics, calendar integration, AI-predicted user energy.
**Acceptance.** User tags a task, sets their current energy via a header control, tasks page filter respects it.
**Estimated effort.** 1 day.
---
## Phase 4 — Read Page Aloud (TTS)
**Why here.** Small and self-contained. Engages auditory processing which the brief specifically calls out as a retention lever for the target audience. Uses OS-native TTS (no new dependencies, no model download). Clean single-tap affordance.
**Scope.**
- Rust command `tts_speak(text: String, rate: f32, voice: Option<String>)` — platform dispatch:
- Linux: `spd-say` (speech-dispatcher is available on most distros; graceful fallback to `espeak` if missing).
- macOS: `say` (built in).
- Windows: PowerShell `System.Speech.Synthesis.SpeechSynthesizer`.
- Small "speaker" icon on any text view (transcript viewer, micro-step list, cleanup result).
- Single-tap play; second tap stops. No pause/resume in v1.
- Settings: voice picker (populated from OS), rate slider (0.52.0).
**Out of scope.** Premium voices. Cloud TTS. Concurrent-speaking queue. SSML.
**Acceptance.** Tap speaker icon on a transcript → hear it read on Linux + expected-to-work-on macOS+Windows (test matrix in Phase 10).
**Estimated effort.** Half day.
---
## Phase 5 — Start / shutdown rituals
**Why here.** Meaningful UX but larger surface. Needs calm copy, gentle flow, and a default-off toggle because rituals can feel parental if not optional.
**Scope.**
- Morning triage: on first launch after 06:00, show a modal / dedicated page: "yesterday's incomplete tasks" (from SQLite query: `completed = false AND created_at < today`), with checkbox pick-list, and "pick 13 for today" constraint that refuses selections > 3.
- Evening shutdown: user-triggerable (not scheduled) review: "what got done today", "open loops to close", "separate work from rest" copy. No automation; ritual as reflection.
- Both off by default in settings. When off, no modal, no pressure.
- Skip-for-today button on morning triage; never shows guilt copy.
**Out of scope.** Calendar integration, automatic sleep detection, weekly / monthly reviews.
**Acceptance.** Morning modal shows correct tasks. Selecting > 3 is prevented with a gentle message. Skip works and doesn't re-prompt same day. Evening shutdown opens a reflective page, doesn't block closing the app.
**Estimated effort.** 1 2 days.
---
## Phase 6 — Soft-touch nudging (Margot protocol) — **REVISED 2026/04/23**
**Why here.** Big differentiator. Scheduled late because it nudges *about* the things the earlier phases built (tasks, timers, rituals), and needs careful copy so it doesn't collapse into a push-notification daemon. Spec is explicit: not push notifications — anticipatory guidance.
**Revised architecture — "nudge bus" hybrid.** Earlier drafts proposed a Rust-side OS-activity watcher (keyboard, active window). Cross-platform review flagged this as fragile: Wayland offers no sanctioned global-keyboard API, macOS needs accessibility permission, Windows needs a message-loop hook, and the signal is low quality everywhere. Deferred to post-v0.1.
Phase 6 instead ships a **frontend-owned nudge bus** that consumes signals Lumotia already produces:
- Focus-timer state (running / completed / cancelled) — already on `window` events from Phase 1.
- Task-completed events — adds a `lumotia:task-completed` window event dispatched when `complete_task_cmd` / `complete_subtask_cmd` resolve.
- Micro-step generation — event from the decompose path.
- Ritual state — `ritualsMorning`, `lastTriageDate` from settings/storage.
- App focus / visibility — `document.visibilitychange` + Tauri window `focus`/`blur` events.
The bus applies suppression rules, then dispatches via Rust commands for platform-native delivery.
**Notification plugin prerequisites (new cross-cutting work, done in Phase 6).**
- Add `tauri-plugin-notification = "2"` (Cargo.toml) + `@tauri-apps/plugin-notification` (package.json).
- Register the plugin in `lib.rs`.
- Frontend checks `isPermissionGranted()` and calls `requestPermission()` on first use.
- Expose ACL entries in `src-tauri/capabilities/default.json`.
- Windows caveat: notifications only deliver properly for *installed* apps (not `tauri dev` builds). Flag this in release notes and the dev HANDOVER.
- Sound path: Windows expects a `.wav` file path, not a platform sound name. Drop the original spec's `"Default"` string for Windows; ship a tiny custom `.wav` in `src-tauri/sounds/`. macOS `"Glass"` is valid. Linux freedesktop sound-name `message-new-instant` works via `tauri-plugin-notification`'s `sound` option.
**Scope (revised).**
- `nudgeBus.svelte.ts` store — subscribes to the in-app signals above, owns cooldown/suppression logic.
- Rust command `deliver_nudge(title, body, sound?)` — thin wrapper around `tauri-plugin-notification` that also persists a row to a new `nudges` SQLite table (for debugging + future analytics).
- **Trigger set for v1 (all in-app, no OS-wide detection):**
- `inactivity_with_active_timer` — timer running + `document.visibilitystate === 'hidden'` OR window `blur` for 90 s continuous. (We know the user has switched away; we don't need to know what they switched to.)
- `pending_morning_triage` — past 10:00 local + triage enabled + last-shown ≠ today. Fires once per day; gets suppressed forever if user later skips or completes.
- `micro_step_idle` — micro-step created + no `lumotia:task-completed` or `lumotia:step-completed` event for that parent-task-id within 15 min.
- **Suppression rules:**
- Global mute in settings (on/off).
- Hard cap 3 nudges per rolling hour.
- No nudge in first 60 s of a timer.
- No nudge during app focus (the user is already looking).
- Rhythmic voice anchoring: piggy-back on Phase 4 TTS. Optional "speak nudges aloud" toggle. Default off. British-English calm lines: "Time to move on", "Your list is still here". No personality yet — Phase 9.
**Out of scope.**
- OS-wide activity detection (keyboard hooks, active-window polling). Deferred post-v0.1 as a separate phase, if a real need emerges.
- Custom trigger editor (owned by Phase 7).
- Biometric signals. Any Margot-as-character visual.
**Acceptance.** Each trigger fires on its defined condition in a dogfood walkthrough. Suppression observed (hidden-for-90 s → nudge; return-to-focus → no nudge). Global mute kills everything immediately. Notification permission request appears on first trigger; denial is respected.
**Estimated effort.** 1 2 days (including notification-plugin setup and the nudges table).
---
## Phase 7 — Implementation intentions (if-then automation) — **REVISED 2026/04/23**
**Why here.** Leans on Phase 6's nudge bus. User-defined rules reuse the same delivery path.
**Rule idempotency (new explicit requirement).**
- Each rule stores `last_fired_at: ISO8601` and, for daily rules, `last_fired_local_date: YYYY-MM-DD`. Without this, a poll-driven "at 09:00" fires on every tick.
- On sleep/resume: on app focus after > 10 minutes away, check each time-of-day rule; if today's fire time has passed and `last_fired_local_date` is not today, fire once and update. Configurable per-rule toggle: `catch_up_on_resume` (default ON for time-of-day rules).
- "After a task completes" rule: subscribes to the `lumotia:task-completed` event from Phase 6. Rule fires once per task id (guarded via `last_fired_task_ids`).
- "Morning triage finishes" rule: fires on *either* "Start the day" or "Skip for today" — skip counts as finishing. Fires once per `last_fired_local_date`.
**Scope.**
- Rule editor UI. Minimal: `if [when-condition], then [action]`.
- When-conditions for v1: `time of day = HH:MM`, `after a task completes` (pick a specific task from list), `morning triage finishes`.
- Actions for v1: `surface a specific task` (jump to Tasks page + highlight), `start a 5-min timer`, `speak a line aloud` (reuses Phase 4 TTS).
- Rules stored in SQLite (`rules` table: id, name, when_json, then_json, enabled, last_fired_at, last_fired_local_date, last_fired_task_ids). Global mute respected.
- No location triggers (desktop app, no geolocation). No app-running detection (fragile cross-platform — revisit post-v0.1).
**Out of scope.** Calendar triggers, cross-app automation, macro-style action chains, shared/community rules.
**Acceptance.** User can write "at 09:00, speak 'time to plan the day' aloud and surface my 'daily standup' task", save it, have it fire next morning at 09:00. Polling tick does not re-fire it. Delete works. Sleep the machine through 09:00; on resume the rule catches up once, then goes quiet until tomorrow.
**Estimated effort.** 1 1.5 days.
---
## Phase 8 — Forgiving gamification — **REVISED 2026/04/23** — **SHIPPED 2026/04/24**
**Why here.** Low-risk, closes the spec list.
**Scope (revised — grace days dropped).**
- Completion count per day (non-punitive). "You've finished 3 today."
- **No streaks, no chains** — so the original "grace days" logic was solving a problem that doesn't exist in this design. Dropped.
- Optional "recent momentum" sparkline: last 7 days' daily completion counts as a tiny inline chart on the Tasks header. Always additive; empty days render as baseline, never as gaps.
- Visual: soft-edged numeric badges on the Tasks header. No leaderboards, no social comparison.
- Zero loss language. Always "look what you did".
**Out of scope.** Leaderboards. Shared challenges. Streak repair purchases. XP systems.
**Acceptance.** Complete 3 tasks today, header shows "3 today". Open the app after 4 days off, no "you were away" framing; header reads today's count only; sparkline simply shows flat zero bars for the away days.
**Estimated effort.** Half day.
**Shipped note (2026/04/24).** Landed on `main` across commits `729b82c` to `fa93033` (13 feature commits plus one style-fix commit for a comment em-dash). Migration v13 adds `auto_completed` on `tasks`; cascade path in `complete_subtask_and_check_parent` sets it, `uncomplete_task` clears it on both target and reopened parent. New storage fn `list_recent_completions(pool, days)` + Tauri wrapper `list_recent_completions_cmd` expose the fixed-length, oldest-first 7-day series. Frontend has a dedicated `completionStats.svelte.ts` store (listens on `lumotia:task-completed` / `lumotia:step-completed` / `lumotia:task-uncompleted` / `lumotia:task-deleted` / `focus`), a `CompletionSparkline.svelte` SVG component, and header wiring in `TasksPage.svelte`. Settings toggle `showMomentumSparkline` added (default `true`) in the Rituals section; Phase 9 polish may resection. Acceptance list verified by full suite: 273 Rust tests pass, `cargo clippy --all-targets -D warnings` clean, `cargo fmt --check` clean, `npm run check` 0/0, `npm run build` clean. Manual dogfood walkthrough (Task 12 Step 6) still owes real-app verification when Jake next opens Lumotia.
---
## Phase 9 — Polish debt — **MOSTLY SHIPPED 2026/04/24-25**
> **All Phase 9 work is paused until Phase 1 Phase 8 are closed.** Per Jake's rule: features first, polish second.
**Contents.**
- File-system `.md` save dialog (replace clipboard-only export). Rust `write_text_file` command; platform dialog via `tauri-plugin-dialog`.
- Bulk select + bulk export in History.
- LLM-powered content tags (`topic:*`, `intent:*`). Slot into the existing `lumotia-llm` stub.
- Settings UX overhaul: bundle high-traffic settings into a "Start here" group; hide advanced behind a disclosure.
- Visual polish pass on all Phase 1 Phase 8 surfaces: spacing, typography, motion curves, colour, dark-mode parity.
- Accessibility pass: keyboard navigation, screen reader labels, focus order, colour contrast audit against WCAG AA.
**Estimated effort.** 1 2 days.
**Shipped note (2026/04/25).** Sub-phases 9a (export plumbing) + 9b
(LLM content tags + migration v14 + storage extension) + sparkline
motion / a11y polish all on `main`, commits `49a795f` to `dd45f10`.
Migration v14 adds `transcripts.llm_tags`; `update_transcript_meta`
gains a sixth Option; the latent `manualTags` persistence bug was
also fixed in passing (the pre-existing `saveHistory()` no-op stub
is now bypassed by HistoryPage tag handlers calling
`saveTranscriptMeta`). Suite green: 277 cargo tests / clippy clean
all-targets / fmt clean / svelte-check 0/0 / npm build clean.
**Deferred to Phase 9 follow-up (post-v0.1 polish iteration):**
- Full `SettingsPage` regroup into 7 progressive-disclosure groups
(Start here / Transcription / Tasks / Rituals / Notifications /
Accessibility / Advanced) plus search box. The 2309-line file
uses a hand-rolled accordion that needs careful unwinding; only
the Phase 8 carryover sparkline relocation landed this session.
`SettingsGroup.svelte` component is in tree, ready for that pass.
- Walkthrough-driven a11y / contrast / typography sweeps. The
scoped checklist (keyboard traversal, focus-visible ring sweep,
WCAG AA contrast in both themes, dark-mode parity, prefers-
reduced-motion checks) needs a running dev server to validate.
Phase 10a QC absorbs the walkthrough.
---
## Phase 10 — QC + rename + release — **SPLIT 2026/04/23**
Earlier draft rolled QC, a full codebase rename, an app-data migration shim, and the release ceremony into one day. Review flagged this as unrealistic and split it. The rename sweep in particular crosses every surface in the app; rushing it is how you end up with `lumotia.db` on half the users' machines and `lumotia.db` on the rest.
### Pre-Phase-10: Cargo.lock policy decision — **RESOLVED 2026/04/24**
- `.gitignore` previously excluded `Cargo.lock`. For a Tauri binary workspace this was the wrong default, since CI resolves dependencies fresh each run (the leading theory for the 2026-04-24 CI red-state noted in earlier `HANDOVER.md` revisions).
- **Resolution (Jake's hardening pass, commit `b333c62`):** `Cargo.lock` now committed. Captures the dep set users actually get from release artefacts rather than whatever crates.io happened to resolve at build time.
- No further action before v0.1.0 tagging.
### Phase 10a — QC (estimated half day)
**Prerequisite:** Phase 1 Phase 9 complete. Cargo.lock committed.
- Full dogfood walkthrough: record a real brain-dump → clean transcript → task extraction → micro-step one task → run a focus timer → tag energy → complete → open evening wind-down → skip morning triage → re-check no re-prompt.
- RB-08 macOS power-assertion verification: **Rachmann runs this offline** on his Mac. `pmset -g assertions` during a live session; expected `PreventSystemSleep` attributed to Lumotia's bundle id. On confirmation, close RB-08 and move `docs/issues/power-assertion-macos-objc2.md` to `docs/issues/resolved/`.
- Cross-platform build matrix green across Linux / macOS / Windows.
- Accessibility regression check: keyboard-only traversal of every new Phase 5 Phase 8 surface.
- Freshly-clean install test on a spare user account: no stray data leaks from dev.
Rachmann's Mac slot runs in parallel; not blocking the rest of 10a.
### Phase 10b — Lumotia → Lumotia rename sweep (estimated half day to 1 day)
Runs **after** Phase 10a QC, **after** Jake has renamed the two repos in GitHub + Gitea web UIs. The rename only starts here, not earlier, so in-flight Phase 1 Phase 9 work doesn't have to re-learn event names mid-cycle.
- `package.json``name: "lumotia"`, `description` update. (Version stays at `0.1.0`.)
- Cargo crates: `lumotia`, `lumotia-audio`, `lumotia-storage`, `lumotia-transcription`, `lumotia-llm`, `lumotia-ai-formatting`, `lumotia-core`, `lumotia-cloud-providers`, `lumotia-hotkey`, `lumotia-mcp``lumotia-*`. Mass-rename via `Cargo.toml` name field + workspace path references + `use` imports.
- Binary + product names: `src-tauri/tauri.conf.json` (productName, identifier), `.desktop` file, Windows product name, macOS bundle name.
- Install paths: `~/.local/share/lumotia/``~/.local/share/lumotia/` (plus the macOS `~/Library/Application Support` and Windows `%APPDATA%` equivalents). **App-data migration shim required** — first-run checks for the old dir, moves contents, writes a sentinel `.migrated-from-lumotia`. Shim must handle the case where both dirs exist (prefer new, log the duplicate).
- Database filename: `lumotia.db``lumotia.db`. Handled by the same shim.
- Window titles, tray tooltip, About-dialog, README body, docs references where they name the product (leave historical brief content talking about "Lumotia" — it's a historical document).
- Event names: `lumotia:start-timer`, `lumotia:task-completed`, `lumotia:open-wind-down`, `lumotia:preferences-changed`, `lumotia:hotkey-pressed`, `lumotia:llm-download-progress``lumotia:*`. Single commit; one find-replace; both emitter and listener in the same diff.
- Logs, error messages, user-facing copy (including toast strings that mention "Lumotia").
- Settings SQLite key: `lumotia_preferences``lumotia_preferences`. Migration reads old key on first launch, writes new key, deletes old.
- Remotes: `ssh://git.corbel.consulting:2222/jake/lumotia.git` + `github.com:jakeadriansames/lumotia.git``…/lumotia.git`. `git remote set-url` locally after web-UI renames.
### Phase 10c — Release (estimated half day)
- Version is already `0.1.0` in `Cargo.toml`, `package.json`, and `tauri.conf.json` — no bump needed. Confirm the three match.
- Write `CHANGELOG.md`. Seed from this roadmap's phases. Entries are written to end-users, not engineers — "You can now read transcripts aloud" not "Added tts_speak command".
- Write release notes in plain language: what it does, who it's for, the Lumotia-data migration note, the Windows notifications caveat (installed app only).
- Tag `v0.1.0` on the head commit.
- Push tag to both remotes. GitHub Actions release workflow auto-builds artefacts for Linux / macOS / Windows.
- Smoke-test at least one artefact per platform (ideally Rachmann covers macOS) before the release is made public.
**Estimated effort (Phase 10 total).** 1 2 days across 10a / 10b / 10c plus Rachmann's parallel Mac session.
---
## Totals
- Phase 1 8 feature build: **6 9 days** of focused work
- Phase 9 polish: **1 2 days**
- Phase 10 QC + rename + release (split): **1 2 days** + Rachmann's Mac session
**Total to v0.1.0 feature-complete release:** **~8 13 days of focused work**, depending on how much polish time Jake wants in Phase 9. Revised downward at the lower end after the Phase 8 grace-day drop and Phase 10 split clarified actual scope.
## Explicit non-goals
- Mobile apps. Lumotia is desktop-first; a mobile companion is post-v0.1.
- Cloud sync. Local-first is the floor, not a feature. Sync is out of scope through v0.1.
- Premium voices, paid tiers, subscription. Licensing + monetisation is a separate track tracked in memory `project_marketplace_creem`.
- AI body doubling (low-fi focus rooms) — validated but parked to post-v0.1.
- Temptation bundling — cut (OS-integration impossible cross-platform; replaced by Phase 3 energy-aware sequencing).
## Post-v0.1 ideas (captured, not scheduled)
Ideas worth keeping warm once the v0.1 release is out. Not tracked as phases until the core release is done.
- **Calendar integration.** Read-only first pass could parse a local ICS file (Thunderbird / Evolution export) and surface day events alongside the tasks list — stays local-first. A cloud-sync pass (Google / iCloud / CalDAV) is a v0.2+ conversation because it re-opens credential handling and refresh-token plumbing that v0.1 deliberately avoids.
- **Right-click highlighted text → capture as task.** Two flavours: (a) *In-Lumotia* — context menu on a selected transcript range or viewer segment, routes to `create_task_cmd` with the selection as text. Small — lives naturally in Phase 9 polish or a bolt-on. (b) *System-wide* — highlight anywhere (browser, Slack, IDE) and call Lumotia. Platform-painful: macOS Services API, Windows shell-extension, Linux desktop-env-specific context menus. Scope as a separate post-v0.1 phase.
## Anchors
- Spec: [docs/brief/feature-set.md](docs/brief/feature-set.md) + [docs/brief/design-principles.md](docs/brief/design-principles.md)
- Current baseline: this session's HANDOVER.md
- Rebrand memory: `~/.claude/projects/-home-jake-Documents-CORBEL-Main/memory/project_magnotia_rebrand.md`
- Release-blocker index: [docs/issues/README.md](docs/issues/README.md)
---
*This roadmap is a living document. Update it at the end of each phase with actuals vs estimates and any scope revisions.*