Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.
transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
-> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
as immutable audit trail). Includes architecture-map references
to magnotia_core::*, magnotia_storage::*, etc. now pointing at
lumotia_*; dev-setup.md tracing output examples (lumotia_startup
target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
("lumotia_task_sync"); magnotia_locale i18n localStorage key
renamed + migration shim added; CSS keyframe names
magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
to "lumotia era" earlier — restored).
Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
legacy detection strings in legacy_and_target_paths() so the
migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
— migration call sites reference the legacy magnotia keys
deliberately.
- docs/handovers/ — historical audit trail.
cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
19 KiB
Phase 0 — Cartography
Acquisition-grade audit, Phase 0 deliverable. Date: 2026-04-30. Branch: claude/rebrand-to-lumotia-UWYkg.
This is a survey, not a verdict. It maps what exists, sizes the surface, and flags every place the README disagrees with the code. Phase 1 (lean-pass) and Phase 2 (architecture conformance) consume this as input.
1. Workspace shape
| Layer | Path | Notes |
|---|---|---|
| Rust workspace root | Cargo.toml |
members = ["src-tauri", "crates/*"], resolver = "2" |
| Tauri app crate | src-tauri/ |
Library lumotia_lib + binary lumotia |
| Library crates | crates/* (×9) |
See §3 |
| MCP standalone binary | crates/mcp/ |
Bin lumotia-mcp (separate process from main app) |
| Svelte frontend | src/ |
SvelteKit, Svelte 5 runes, Tailwind 4 |
| Static assets | static/, src-tauri/icons/, src-tauri/resources/ |
Binaries shipped (2): lumotia (Tauri app), lumotia-mcp (stdio MCP server).
2. Lines of code
| Area | LOC | Files |
|---|---|---|
crates/ (Rust, all 9 crates) |
13,261 | 52 |
src-tauri/ (Rust) |
8,330 | 27 |
| Frontend (Svelte/TS/JS, excl. design-system) | 15,192 | ~80 |
src/design-system/ (reference kit, not live code) |
1,412 | — |
| Total active | ~36,800 |
Largest files (top complexity candidates)
| LOC | File |
|---|---|
| 2,534 | crates/storage/src/database.rs |
| 2,250 | src/lib/pages/SettingsPage.svelte |
| 1,737 | src-tauri/src/commands/live.rs |
| 1,185 | crates/storage/src/migrations.rs |
| 1,081 | src/lib/pages/DictationPage.svelte |
| 897 | src/lib/pages/HistoryPage.svelte |
| 790 | src-tauri/src/commands/paste.rs |
| 735 | crates/transcription/src/streaming/rms_vad.rs |
| 725 | src/lib/pages/TasksPage.svelte |
| 720 | src-tauri/src/commands/models.rs |
| 697 | src/lib/stores/page.svelte.ts |
Phase 1 candidate.
database.rs(2.5k),SettingsPage.svelte(2.25k), andlive.rs(1.7k) are each large enough to deserve a structural review in isolation. HANDOVER.md already flagsSettingsPageas needing decomposition into 7 progressive-disclosure groups.
3. Crate inventory
| Crate | LOC | Files | pub items (lib.rs / total) |
Tests |
|---|---|---|---|---|
lumotia-core |
1,212 | 9 | 10 / 104 | 16 |
lumotia-audio |
1,533 | 8 | 14 / 38 | 14 |
lumotia-transcription |
2,617 | 12 | 13 / 51 | 51 |
lumotia-llm |
1,330 | 6 | 27 / 56 | 17 |
lumotia-ai-formatting |
1,502 | 6 | 9 / 21 | 47 |
lumotia-storage |
3,771 | 4 | 6 / 69 | 60 |
lumotia-hotkey |
632 | 3 | 5 / 14 | 4 |
lumotia-cloud-providers |
80 | 2 | 2 / 3 | 2 |
lumotia-mcp |
584 | 2 | 8 / 8 | 9 |
src-tauri (lumotia + lumotia_lib) |
8,330 | 27 | n/a | 67 |
| Total | 21,591 | 287 |
Outliers worth a Phase-2 look:
lumotia-coreexposes 104 public items — high for a "shared types" crate; likely leakage of internals.lumotia-storageexposes 69 public items across only 4 files; the file split is suspect (2.5k-linedatabase.rs).lumotia-cloud-providersis 80 LOC and 3 public items — README calls it "empty scaffolding" (verified: just an in-memory keystore + env-var fallback). Either grow it or remove it; it currently earns nothing.
4. Crate dependency graph
lumotia-core ──┬─→ lumotia-audio
├─→ lumotia-transcription
├─→ lumotia-llm ──→ lumotia-ai-formatting
├─→ lumotia-cloud-providers
├─→ lumotia-hotkey
└─→ lumotia-storage ──→ lumotia-mcp
lumotia (src-tauri)
└─→ all 8 library crates (NOT lumotia-mcp — separate binary)
Observations:
lumotia-coreis the workspace floor; nothing depends on it depending on something else. Good.- DAG is clean — no cycles, no upward dependencies.
lumotia-mcpcorrectly depends only onlumotia-storage(its sole job is to read the SQLite DB). The Tauri app does not depend on it, confirming the "separate process" claim in the README.lumotia-ai-formattingdepends on bothcoreandllm. Reasonable.
Phase 2 will verify: every
pubitem in the leaf crates (audio,transcription,llm,storage,hotkey) has at least one external consumer. Internal-only items shouldn't bepub.
5. External surfaces
5.1 Tauri commands
102 #[tauri::command] attributes across 22 of 25 modules in src-tauri/src/commands/.
power.rsandsecurity.rsare utility modules (no commands; helpers only).mod.rsis the registry.
| Module | # commands | Module | # commands |
|---|---|---|---|
tasks |
12 | intentions |
5 |
models |
12 | audio |
4 |
llm |
10 | tts |
3 |
profiles |
9 | transcription |
3 |
transcripts |
8 | paste |
3 |
windows |
8 | update |
2 |
diagnostics |
6 | rituals |
2 |
hotkey |
5 | live |
2 |
hardware |
2 | ||
feedback |
2 | ||
nudges, meeting, fs, clipboard |
1 each |
Every one of these is a trust boundary — Phase 4 (security) will audit input validation per command.
5.2 MCP tools (read-only stdio)
Confirmed in crates/mcp/src/lib.rs:
list_transcriptsget_transcriptsearch_transcriptslist_tasks
The init_readonly connection mode in lumotia-storage is opened at OS level (SQLITE_OPEN_READONLY), per crates/mcp/src/main.rs:18 — Phase 4 will confirm with a write-attempt test.
5.3 Frontend route surface
| Route | Purpose | Layout |
|---|---|---|
/ |
Main dictation shell | +layout.svelte (sidebar + chrome) |
/float |
Tasks float window | +layout@.svelte (chrome-free) |
/viewer |
Transcript editor | +layout@.svelte (chrome-free) |
/preview |
Live transcription overlay | +layout@.svelte (chrome-free) |
Pages: DictationPage, SettingsPage, HistoryPage, TasksPage, FilesPage, FirstRunPage, ShutdownRitualPage (7).
Stores: page, preferences, profiles, toasts, focusTimer, llmStatus, nudgeBus, implementationIntentions, completionStats, speaker (10).
Components: 25 in src/lib/components/.
i18n locales: en, es, de (scaffolding only — most strings are still hard-coded; the migration is incremental per README).
5.4 Model registry
7 models declared in crates/core/src/model_registry.rs:
- Whisper (6):
whisper-tiny-en,whisper-base-en,whisper-small-en,whisper-distil-small-en,whisper-medium-en,whisper-distil-large-v3 - Parakeet (1):
parakeet-ctc-0.6b-int8
Moonshine is mentioned in the README's
lumotia-coredescription ("Moonshine entries") but no Moonshine entry exists in the registry. See §7.
6. Test floor
| Location | Count |
|---|---|
crates/*/src/ (lib tests) |
217 |
crates/*/tests/ (integration) |
3 |
src-tauri/src/ + src-tauri/tests/ |
67 |
| Total | 287 |
Only 3 cross-crate integration tests is light. Per-crate lib tests dominate. Phase 5 (test integrity) will mutation-test the heavy crates (storage, transcription, llm) to grade whether these tests actually pin behaviour.
7. README ↔ code drift
Items where the README disagrees with the code as-of this audit:
| README claim | Reality | Severity |
|---|---|---|
| "245 automated lib tests across 10 crates" (line 14) | 287 tests total (220 lib + 67 src-tauri); 220 lib-only | LOW — undercount (good direction, but stale) |
| "10 crates" (line 14) | 9 library crates + 1 app crate (src-tauri) — depends how you count; technically the workspace has 10 packages |
OK if counting src-tauri; misleading otherwise |
| "Commands: audio, clipboard, diagnostics, hotkey, live, llm, meeting, models, paste, power, profiles, tasks, transcription, transcripts, update, windows" (line 95-97) — 16 listed | 22 modules with commands: README missing feedback, fs, intentions, nudges, rituals, tts. Architecture diagram and §"Tauri commands" table both stale. |
MED — visible to anyone evaluating the codebase |
| "18 Tauri command modules" (line 117) | 25 files in commands/ (22 with command attrs + mod, power, security) |
MED |
lumotia-core "model registry (Whisper + Parakeet + Moonshine entries)" (line 165) |
No Moonshine entries in model_registry.rs. 6 Whisper + 1 Parakeet only. |
MED — claims an unimplemented feature |
Stores listed: settings, profiles, tasks, history, taskLists, templates, page, toasts, preferences (line 202) |
Actual stores: page, preferences, profiles, toasts, focusTimer, llmStatus, nudgeBus, implementationIntentions, completionStats, speaker. README list is largely fictional — there is no tasks, history, taskLists, templates, or settings store as a separate file. |
HIGH — describes architecture that doesn't exist |
lumotia-cloud-providers "BYOK cloud-STT provider stubs… Currently empty scaffolding. When populated: OpenAI-compatible endpoint + Anthropic" (line 172) |
Crate has an in-memory API-key store with env-var fallback — not "empty scaffolding". No HTTP code, no provider implementations. | LOW — partial |
"Every new workspace crate needs a description in its Cargo.toml" (line 362, contributing rule) |
crates/llm/Cargo.toml has no description field. Self-violation of the contribution rule. |
LOW — easy fix |
| README §"Architecture" Rust crate list spelling (line 102-104) | Correct, but the manual line-break formatting got mangled by the rebrand sweep — visible whitespace inconsistency. | TRIVIAL |
Phase 0 verdict on documentation truth: The README is mostly right but actively misleading in two places — the stores list and the Moonshine claim. Both will fail an acquirer's first sanity-check (
grep -r "Moonshine" crates/) and erode trust in the rest of the doc.
8. HANDOVER files
| File | Date | Topic | Status |
|---|---|---|---|
HANDOVER.md |
2026-04-25 | Latest session (Phase 9a–9d) | Active reference |
HANDOVER-2026-04-24.md |
2026-04-24 | Phase 8 close | Historical |
HANDOVER-2026-04-19.md |
2026-04-19 | Earlier session | Historical |
HANDOVER-2026-04-18.md |
2026-04-18 | Earlier session | Historical |
HANDOVER-2026-04-17.md |
2026-04-17 | Earliest in tree | Historical |
Five handovers in the repo root is unusual — most projects keep one. Phase 8 (docs truth) will recommend either archiving them under docs/handovers/ or rotating to a single HANDOVER.md with prior content moved.
The post-rebrand state: all five handovers were rewritten by today's sweep (line counts identical, words different). They now reference lumotia paths but their content describes work done under the kon / corbie names — there's a temporal-vs-naming mismatch a reader has to mentally track. Acquirer-friendly fix: add a one-line note at the top of each historical handover saying "Originally written when the product was named X; references rewritten 2026-04-30."
9. Fix areas — actionable tasks
Each task below is concrete: file, change, verification, effort. Pick any in any order; they don't depend on later phases. Items are grouped by impact tier.
Tier A — High impact, do first
A1. README stores list is fiction
- File:
README.md, line 202 - Current:
Reactive stores (src/lib/stores/page.svelte.ts): settings, profiles, tasks, history, taskLists, templates, page, toasts, preferences. - Reality: stores are
page,preferences,profiles,toasts,focusTimer,llmStatus,nudgeBus,implementationIntentions,completionStats,speaker— each in its own*.svelte.tsfile undersrc/lib/stores/. - Fix: rewrite the bullet to enumerate the actual ten store files, and clarify that
page.svelte.tsis the central app-state store (transcripts, profiles, taskLists, etc. live as fields on it). - Verify:
ls src/lib/stores/matches the README list 1:1. - Effort: 10 min.
A2. Moonshine claim has no implementation
- File:
README.md, line 165 (lumotia-corerow in the crate table) - Current:
model registry (Whisper + Parakeet + Moonshine entries) - Reality:
crates/core/src/model_registry.rshas 6 Whisper + 1 Parakeet entries. Zero Moonshine. - Fix (pick one):
- (a) Remove the Moonshine reference from the README. Cheapest.
- (b) Add a
// TODO(moonshine): not yet wiredconstant inmodel_registry.rsand a roadmap entry under §Roadmap, so the claim is at least flagged as forthcoming.
- Verify:
grep -ri moonshine crates/ src-tauri/ src/returns no orphan references. - Effort: 5 min (option a) / 30 min (option b).
A3. Six Tauri command modules undocumented
- File:
README.md, lines 95-97 (Architecture diagram) and 175-195 (Tauri commands table) - Missing:
feedback,fs,intentions,nudges,rituals,tts - Fix: add a one-line description for each in the §Tauri commands table; add the names to the Architecture-diagram bullet list.
- Verify:
ls src-tauri/src/commands/*.rs | xargs basename -s .rs | sortmatches the README table 1:1 (excludingmod,power,security, which are utility modules — note that explicitly). - Effort: 20 min.
Tier B — Low effort, removes self-violations
B1. crates/llm/Cargo.toml missing description
- File:
crates/llm/Cargo.toml - Current:
[package]block hasname,version,editiononly. - Reality: README §Contributing line 362 declares this a hard rule. Self-violation.
- Fix: add
description = "Local LLM engine for Lumotia (Qwen3 via llama-cpp-2). Cleanup, task extraction, content tags."(or similar). Match the prose style of the other 8 crates' descriptions. - Verify:
for d in crates/*/Cargo.toml src-tauri/Cargo.toml; do grep -L "^description" "$d"; donereturns empty. - Effort: 2 min.
B2. Stale test-count claim
- File:
README.md, line 14 - Current:
245 automated lib tests across 10 crates, all passing - Reality: 287 tests total (220 lib + 67 src-tauri); 220 lib-only.
- Fix: decide on a number that's automatable, not a snapshot. Either: (a) replace with
220+ lib tests across 9 library crates plus 67 Tauri-app tests, or (b) drop the absolute number and saycomprehensive automated test floor — see CI for current count. - Verify:
grep -rE '#\[(test|tokio::test)\]' crates/*/src/ | wc -lmatches whatever number you ship. - Effort: 5 min.
B3. Crate count claim ambiguity
- File:
README.md, line 14 ("10 crates") - Reality: 9 library crates + 1 Tauri app crate. The README's own crate table only documents 9.
- Fix: say "9 library crates plus the Tauri app crate" — or just "9 library crates" and let the Tauri app stand separately, which matches the existing prose.
- Effort: 2 min.
Tier C — Structural smells (defer to Phase 2 but flag now)
C1. lumotia-core over-exports
- File(s):
crates/core/src/lib.rsand the modules it re-exports - Symptom: 104 public items in a "shared types" crate. High blast radius for any change.
- Fix (Phase 2 work, do not touch yet): audit every
pubitem; demote anything not used outside the crate topub(crate). The expected outcome is a 30–60% reduction in public surface. - Verify: after the demotion pass,
cargo +nightly rustdocshould still succeed and downstream crates should still compile without changes. - Effort: ~½ day (Phase 2 scope).
C2. lumotia-storage::database.rs is 2,534 lines
- File:
crates/storage/src/database.rs - Symptom: single file holds CRUD for transcripts, tasks, subtasks, profiles, profile-terms, settings, error log, FTS5. No internal module boundaries.
- Fix (Phase 2): split by domain —
database/transcripts.rs,database/tasks.rs,database/profiles.rs, etc. Keep the public re-export shape unchanged so callers don't move. - Verify:
cargo test -p lumotia-storagestill passes; no public-API changes. - Effort: ~2-4 hours.
C3. SettingsPage.svelte is 2,250 lines
- File:
src/lib/pages/SettingsPage.svelte - Symptom: HANDOVER.md already flags this;
SettingsGroup.sveltewas prepared but the seven-group split was deferred. - Fix (Phase 2): complete the planned restructure. Pick this up from HANDOVER.md §"9c — Settings (scaled down)".
- Effort: ~½ day.
C4. lumotia-cloud-providers does not earn its existence
- Files:
crates/cloud-providers/(80 LOC across 2 files) - Symptom: crate contains an in-memory keystore with env-var fallback. Not "empty scaffolding" as the README says — but also not provider-specific. No HTTP code, no providers.
- Fix (decide, then act):
- (a) Fold into
lumotia-core::keystore(preferred — it's a generic key store, nothing cloud-specific). Drop the crate. README §Architecture and the dependency graph simplify. - (b) Grow it: actually implement an OpenAI-compatible STT client and an Anthropic STT client, gated behind a
cloud-sttfeature flag. Earn the boundary.
- (a) Fold into
- Verify (option a): workspace builds with
cloud-providersremoved fromCargo.tomlmembers; the two consumers (commands/llm.rsand wherever else) re-import fromlumotia-core::keystore. - Effort: ~1 hour (option a) / multi-day (option b).
Tier D — Hygiene (Phase 1 / Phase 8)
D1. Five HANDOVER files in repo root
- Files:
HANDOVER.md,HANDOVER-2026-04-{17,18,19,24}.md - Symptom: root noise; rebrand also rewrote their content so they describe
kon/corbiework but read aslumotia. - Fix:
- Move the four dated files under
docs/handovers/. - Add a one-line italic note at the top of each historical file: "Originally written when the product was named Kon (and briefly Corbie); references rewritten in the 2026-04-30 rebrand sweep."
- Keep the latest as
HANDOVER.mdin root, or also move underdocs/handovers/HANDOVER-latest.mdwith a symlink — pick one.
- Move the four dated files under
- Effort: 15 min.
D2. Tauri command total count drift
- README says "18 Tauri command modules" (line 117); actual is 22 modules with commands (plus 3 utility modules in the same dir).
- Fix: update line 117 to "22 Tauri command modules + 3 utility modules (
mod,power,security)". - Effort: 1 min — usually folded into A3.
10. Phase 1 entry plan
Tier A and Tier B fixes above (≈45 min total) bring the README back into truth and close the self-imposed Cargo.toml rule. Do these as a warm-up before Phase 1 proper; they make every subsequent phase' "what does the README say?" comparison cheaper.
Phase 1 (Lean-pass) — see phases-1-8-playbook.md — should then target, in order:
cargo machete+cargo udepsworkspace-wide → unused deps kill list.knipon the frontend → unused TS/Svelte modules.- Manual review of the 5 files >1k LOC for duplicate logic (
SettingsPage.svelte,database.rs,live.rs,migrations.rs,DictationPage.svelte). - Grep audit of
TODO/FIXME/unimplemented!/unwrap()outside tests → tech-debt log. - Apply the Tier C structural smells if Phase 2 is being done immediately afterwards.
Estimated time: 1 working day for Phase 1 in full, plus ~45 min of Tier A/B fixes.
End of Phase 0 cartography.