Files
Lumotia/docs/audit/phase0-cartography.md
Claude 7ff7295567
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
docs(audit): add fix-areas section to Phase 0 + Phases 1-8 playbook
Phase 0 update: replaces the loose "quick wins" list with a structured
Fix Areas section organised into impact tiers (A: high-impact README
truth fixes, B: low-effort self-violation fixes, C: structural smells
deferred to Phase 2, D: hygiene). Each task names the file, the change,
the verification command, and the effort estimate.

New playbook: docs/audit/phases-1-8-playbook.md — step-by-step
acquisition-grade audit procedure for the remaining seven phases. Each
phase has goal, inputs, procedure (with concrete commands), deliverable,
acceptance criteria, and time estimate. Designed to be picked up
independently from any phase.
2026-05-01 06:38:54 +00:00

19 KiB
Raw Blame History

Phase 0 — Cartography

Acquisition-grade audit, Phase 0 deliverable. Date: 2026-04-30. Branch: claude/rebrand-to-magnotia-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 magnotia_lib + binary magnotia
Library crates crates/* (×9) See §3
MCP standalone binary crates/mcp/ Bin magnotia-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): magnotia (Tauri app), magnotia-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
magnotia-core 1,212 9 10 / 104 16
magnotia-audio 1,533 8 14 / 38 14
magnotia-transcription 2,617 12 13 / 51 51
magnotia-llm 1,330 6 27 / 56 17
magnotia-ai-formatting 1,502 6 9 / 21 47
magnotia-storage 3,771 4 6 / 69 60
magnotia-hotkey 632 3 5 / 14 4
magnotia-cloud-providers 80 2 2 / 3 2
magnotia-mcp 584 2 8 / 8 9
src-tauri (magnotia + magnotia_lib) 8,330 27 n/a 67
Total 21,591 287

Outliers worth a Phase-2 look:

  • magnotia-core exposes 104 public items — high for a "shared types" crate; likely leakage of internals.
  • magnotia-storage exposes 69 public items across only 4 files; the file split is suspect (2.5k-line database.rs).
  • magnotia-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

magnotia-core ──┬─→ magnotia-audio
                ├─→ magnotia-transcription
                ├─→ magnotia-llm ──→ magnotia-ai-formatting
                ├─→ magnotia-cloud-providers
                ├─→ magnotia-hotkey
                └─→ magnotia-storage ──→ magnotia-mcp

magnotia (src-tauri)
  └─→ all 8 library crates (NOT magnotia-mcp — separate binary)

Observations:

  • magnotia-core is the workspace floor; nothing depends on it depending on something else. Good.
  • DAG is clean — no cycles, no upward dependencies.
  • magnotia-mcp correctly depends only on magnotia-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.
  • magnotia-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 magnotia-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 magnotia-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
magnotia-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
magnotia-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 magnotia 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 (magnotia-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 Magnotia (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. magnotia-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. magnotia-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 magnotia-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. magnotia-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 magnotia-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 magnotia-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 magnotia.
  • 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.