Files
Lumotia/docs/audit/phase0-cartography.md
Jake 26c7307607
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-rebrand — docs, scripts, root config, residuals
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>
2026-05-13 12:38:03 +01:00

19 KiB
Raw Blame History

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), and live.rs (1.7k) are each large enough to deserve a structural review in isolation. HANDOVER.md already flags SettingsPage as 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-core exposes 104 public items — high for a "shared types" crate; likely leakage of internals.
  • lumotia-storage exposes 69 public items across only 4 files; the file split is suspect (2.5k-line database.rs).
  • lumotia-cloud-providers is 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-core is the workspace floor; nothing depends on it depending on something else. Good.
  • DAG is clean — no cycles, no upward dependencies.
  • lumotia-mcp correctly depends only on lumotia-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-formatting depends on both core and llm. Reasonable.

Phase 2 will verify: every pub item in the leaf crates (audio, transcription, llm, storage, hotkey) has at least one external consumer. Internal-only items shouldn't be pub.


5. External surfaces

5.1 Tauri commands

102 #[tauri::command] attributes across 22 of 25 modules in src-tauri/src/commands/.

  • power.rs and security.rs are utility modules (no commands; helpers only).
  • mod.rs is 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_transcripts
  • get_transcript
  • search_transcripts
  • list_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-core description ("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 9a9d) 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.ts file under src/lib/stores/.
  • Fix: rewrite the bullet to enumerate the actual ten store files, and clarify that page.svelte.ts is 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-core row in the crate table)
  • Current: model registry (Whisper + Parakeet + Moonshine entries)
  • Reality: crates/core/src/model_registry.rs has 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 wired constant in model_registry.rs and 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 | sort matches the README table 1:1 (excluding mod, 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 has name, version, edition only.
  • 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"; done returns 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 say comprehensive automated test floor — see CI for current count.
  • Verify: grep -rE '#\[(test|tokio::test)\]' crates/*/src/ | wc -l matches 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.rs and 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 pub item; demote anything not used outside the crate to pub(crate). The expected outcome is a 3060% reduction in public surface.
  • Verify: after the demotion pass, cargo +nightly rustdoc should 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-storage still 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.svelte was 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-stt feature flag. Earn the boundary.
  • Verify (option a): workspace builds with cloud-providers removed from Cargo.toml members; the two consumers (commands/llm.rs and wherever else) re-import from lumotia-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/corbie work but read as lumotia.
  • 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.md in root, or also move under docs/handovers/HANDOVER-latest.md with a symlink — pick one.
  • 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:

  1. cargo machete + cargo udeps workspace-wide → unused deps kill list.
  2. knip on the frontend → unused TS/Svelte modules.
  3. Manual review of the 5 files >1k LOC for duplicate logic (SettingsPage.svelte, database.rs, live.rs, migrations.rs, DictationPage.svelte).
  4. Grep audit of TODO / FIXME / unimplemented! / unwrap() outside tests → tech-debt log.
  5. 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.