Five-slice navigable map of the entire codebase under
docs/architecture-map/. Each slice is a self-contained
breadcrumbed sub-tree:
01-frontend (16) Svelte/SvelteKit UI
02-tauri-runtime (26) src-tauri commands + lifecycle
03-audio-transcription (16) audio + transcription crates
04-llm-formatting-mcp (19) llm, ai-formatting, mcp, cloud
05-core-storage-hotkey-build core, storage, hotkey, workspace,
(26) CI, dev glue
Plus master README.md and data-flow-end-to-end.md tracing
audio bytes from microphone to FTS5 search to MCP read.
Generated by 5 parallel subagents on 2026/05/09 against
HEAD 3c47000. Each page has YAML frontmatter, file:line code
refs, sibling cross-links, plain-English summaries.
Aggregated debt surfaced (full lists in master README):
RB-08 macOS power assertion, schema head drift v14 vs v15,
VAD blocked on ort version conflict, streaming primitives
not wired into live.rs, no prompt versioning, MCP has no
auth, cloud-providers in-memory keystore, SettingsPage
2 484 LOC, commands/live.rs 1 737 LOC, dual theme system,
brand rename to Lumenote pending across the codebase.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
name, type, last_verified
| name | type | last_verified |
|---|---|---|
| Magnotia architecture map | architecture-map-root-index | 2026/05/09 |
Magnotia architecture map
Where you are: Architecture map root. Reading order if this is your first time: read this page top to bottom, pick the slice that matches what you are trying to do, follow the breadcrumb trail.
What Magnotia is in 60 seconds
Magnotia is a local-first dictation desktop app. You press a hotkey, you speak, your speech becomes formatted text on disk and on the clipboard. Everything that touches your voice or your transcript runs on your own machine. Zero telemetry, zero analytics, no calls home unless you turn on auto-update.
It is a Tauri 2 app. The shell is Svelte 5. The brain is a Rust workspace of nine crates. Speech-to-text runs through Whisper (whisper-rs) by default with Parakeet (transcribe-rs ONNX) as an alternative. Optional cleanup runs through a local llama-cpp-2 LLM (Qwen3.5 / 3.6, four-tier model picker). Transcripts live in a SQLite database with a FTS5 full-text index. A standalone magnotia-mcp binary opens that database read-only and serves four tools over the Model Context Protocol so external agents can read your history without write access.
Targets: Linux (primary, Wayland-friendly), macOS, Windows. Android is on the roadmap (a few crate features carry android cfgs).
Brand rename in flight. Magnotia was approved as "Lumenote" on 2026/05/08. The codebase still says "magnotia" and "Magnotia" everywhere. The rename is a separate session.
The three layers
┌─────────────────────────────────────────────────────────────────────┐
│ Frontend (slice 01) │
│ Svelte 5 + SvelteKit. 4 windows, 7 pages, 25 components, 10 stores. │
│ ~17 200 LOC. │
├─────────────────────────────────────────────────────────────────────┤
│ Tauri runtime (slice 02) │
│ src-tauri/. 91 commands across 22 modules + 3 utility modules, │
│ system tray, ACL capabilities, plugins, panic + log + CSP guards. │
├─────────────────────────────────────────────────────────────────────┤
│ Rust workspace │
│ ┌────────────────────┬──────────────────────┬─────────────────────┐ │
│ │ Audio + │ LLM + Formatting + │ Core + Storage + │ │
│ │ Transcription │ MCP + Cloud │ Hotkey + Build │ │
│ │ (slice 03) │ (slice 04) │ (slice 05) │ │
│ │ magnotia-audio │ magnotia-llm │ magnotia-core │ │
│ │ magnotia- │ magnotia- │ magnotia-storage │ │
│ │ transcription │ ai-formatting │ magnotia-hotkey │ │
│ │ │ magnotia-mcp │ workspace + CI │ │
│ │ │ magnotia- │ │ │
│ │ │ cloud-providers │ │ │
│ └────────────────────┴──────────────────────┴─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
The frontend never touches the filesystem, the audio device, the models, or the LLM directly. Everything that crosses the WebView boundary uses invoke() (calling a Rust command) or Tauri events (one direction or the other). The Rust workspace is the brain. The Tauri layer is the integration surface.
Slices
| # | Slice | Owns | Files |
|---|---|---|---|
| 01 | Frontend | Svelte UI, routes, pages, components, stores, i18n, design system, the WebView side of the bridge | 16 |
| 02 | Tauri runtime | App lifecycle, 91 commands, system tray, ACL, plugins, configs, build.rs | 26 |
| 03 | Audio + Transcription | Microphone capture, resampling, VAD, file decode, Whisper + Parakeet engines, streaming primitives, model manager | 16 |
| 04 | LLM + Formatting + MCP | Llama-cpp engine, four LLM surfaces (cleanup, decompose, extract tasks, content tags), formatting pipeline, MCP server, cloud-provider stubs | 19 |
| 05 | Core + Storage + Hotkey + Build | Shared types, hardware probe, power, thread tuning, model registry, SQLite + FTS5 + 15 migrations, evdev hotkey listener, workspace, CI | 26 |
103 markdown pages in total under this directory.
Data flow
For an end-to-end trace of a single recording session from microphone to FTS5 search to MCP read, see data-flow-end-to-end.md.
"I want to find X"
Cross-cutting concerns and known debt (aggregated 2026/05/09)
Open items surfaced by the slice maps. Each slice's README has its own debt section with the full detail.
Release blockers (gating v0.1)
- RB-08 macOS power assertion (MAJOR, open).
PowerAssertion::beginis a non-functional stub awaiting anobjc2rewrite plus runtime verification on Apple Silicon. Source: 02-tauri-runtime/commands/power-and-security.md. RefHANDOVER.md. PowerAssertionis a no-op on Linux and Windows too (separate from RB-08). Doc comments promise logind inhibitors andSetThreadExecutionState; neither implemented. Long Linux dictation can be idled by the compositor.
Brand rename pending
- The codebase still says "magnotia" and "Magnotia" everywhere. Strings include
"magnotia live dictation session",magnotia_preferencessettings key,magnotia_settingslocalStorage key, prefixed events (magnotia:hotkey-pressed,magnotia:llm-download-progress,magnotia:open-wind-down,magnotia:preferences-changed), the bundle identifieruk.co.corbel.magnotia, every crate name (magnotia-core,magnotia-audio, etc), themagnotia-mcpbinary, the brand asset folders. A rebrand sweep is a single dedicated session.
Bridge surface drift
- Slice 02 registers 91 Tauri commands. Slice 01 invokes 60. The 31 unaccounted commands are likely registered for tests, internal lifecycle, or removed callers. Worth an audit pass.
- Backend events emitted but not listened to (apparent).
runtime-warning,transcription-result,native-pcm,magnotia:hotkey-released. Some may be deprecated, some may be observed only in specific routes. Verify before any cleanup.
Schema drift vs HANDOVER
HANDOVER.md(2026/04/25) quotes schema head v14. Disk head is v15 (idx_transcripts_profile_created). HANDOVER needs a refresh or a session-end note.
Audio pipeline gaps
- VAD is a stub in
magnotia-audiobecause both candidate Silero crates pinort 2.0.0-rc.10while transcribe-rs (Parakeet) needs2.0.0-rc.12. Live capture leans on the energy-basedRmsVadChunkerinmagnotia-transcriptionas a working fallback. Two VADs in two crates with no shared code or thresholds. - Streaming primitives (
RmsVadChunker,LocalAgreement,trim_buffer_to_commit_point) are unit-tested but not yet wired intosrc-tauri/src/commands/live.rs. Comments instreaming/mod.rs,buffer_trim.rs,commit_policy.rsflag the integration as a follow-up.
LLM and formatting
- No prompt versioning. No
PROMPT_VERSIONconstant. Cached cleanup output will silently drift across prompt revisions. - Trivial-true GPU cross-check (commit
052265b).gpu_offloadedderived fromuse_gpu && gpu_layers >= n_layeris provably true today becausegpu_layers = u32::MAXwheneveruse_gpuis set. Real residency observability needs llama.cpp log parsing. - MAX_CONTEXT_TOKENS is a process-wide cap of 8192 regardless of model tier. The 27B tier has a much larger native context that is never advertised.
MAGNOTIA_LLM_TEST_MODELenv-var gate is the only thing keeping the LLM smoke tests honest. Worth documenting in a contributor note.- British English regex misses
-ingforms of-izeverbs (e.g.organizingslips through unconverted). - Multi-token phrase repetition not detected by the anti-hallucination filter. Five repetitions of
"thank you"does not trigger.
MCP and security
- MCP has no auth. Stdio is the trust boundary. Any future HTTP / SSE transport needs an auth layer before it ships.
magnotia-cloud-providersis empty scaffolding. In-memory keystore only. API keys vanish on restart. Documented TODO forkeyringmigration.
Frontend debt
SettingsPage.svelteis 2 484 LOC and Phase 9c handover already deferred the seven-group restructure plus search box.- Dual theme system.
settings.theme("Light" / "Dark" / "System") andpreferences.theme("light" / "dark" / "system") coexist with a migration$effectrunning every cycle. @ts-nocheckon six files including+layout.svelteand four pages.- Triple transcript font-size knobs are in tension and likely drifted.
- i18n is a stub. Each locale carries 19 lines.
- Two font directories (
src/fonts/andstatic/fonts/) ship the same five woff2 files. - Default SvelteKit demo assets (
static/svelte.svg,tauri.svg,vite.svg) likely unused. - Dead
profilesroute. Rewritten tosettingsat+page.svelte:13.
Tauri runtime debt
commands::liveis 1 737 LOC in one file. Splitting per concern (runtime, speech gate, dedup, chunker, progressive WAV) is overdue.build.rslink arg--allow-multiple-definitionmasks a real ggml duplication issue betweenwhisper-rs-sysandllama-cpp-sys-2. Documented as INTERIM.- Updater stubs ship disabled.
install_updatereturns "Updates are disabled until release signing is configured." Matchingtauri.conf.jsonplugins.updaterblock is absent. - Production crash dumps lack stack traces because
RUST_BACKTRACEis not set in the packaged binary and the panic hook does not capture a backtrace. commands::tasks::decompose_and_storeandextract_tasks_from_transcript_cmdlackPowerAssertion::begindespite running multi-second LLM inference.commands::llm::cleanup_transcript_text_cmdhas it; tasks should too.commands::transcribe_pcmdoes not callensure_model_loadedunlike its file sibling. Asymmetry could panic if invoked before a load step.tauri-plugin-cloud-providerscrate is depended-on inCargo.tomlbut no command file imports it. Reserved for future upload flow.parallel_mode_availablehard-wired tofalseincommands/models.rs:509. Phase A.4 marker for unblocking.
Build / CI / dev glue
run.shhard-codesLIBCLANG_PATH=/usr/lib64/llvm21/lib64. Fedora 41 default. Breaks on Debian / Ubuntu / macOS without override.src-tauri/.cargo/config.tomlhard-codesLIBCLANG_PATH = "C:\\Program Files\\LLVM\\bin"for Windows.- No code signing. Apple and Windows signing env blocks are commented out. First-run users hit Gatekeeper / SmartScreen.
tauri-action@v0is unpinned. Floats. Pin before v0.1.pcm-processor.jshard-codes16000and8000which must move in lock-step withmagnotia_core::constants::{WHISPER_SAMPLE_RATE, MIN_CHUNK_SAMPLES}.uuidCargo feature isv4despite the storageCargo.tomlcomment claiming "v7 random". Cosmetic but worth cleaning up.- GPU probe is a stub.
magnotia_core::hardware::probe_gpu()returnsNone; no NVIDIA / AMD / Intel / Apple discrimination at runtime. - Power probe is Linux-only. macOS and Windows return
PowerState::Unknown, which callers treat asOnAc.
How this map was generated
Five subagents ran in parallel on 2026/05/09, one per slice. Each read the code under its slice, wrote breadcrumbed markdown with file:line refs, returned an executive summary, a cross-slice dependency list, a public-surface inventory, and a debt list. This master page is the synthesis. The data-flow trace is a separate page that follows the audio bytes from microphone to FTS5 search to MCP read.
Refresh history
- 2026/05/09 — initial generation. Five slices, 103 pages. Generated against codebase head per
git logat the time of capture (most recent commit3c47000 chore(core): add tuning_log_demo example for live heuristic validation).
When to refresh
Re-run the five-slice generation when any of these is true:
- A new Rust crate is added or removed from the workspace.
- A new top-level frontend route or window is added.
- The schema head moves by more than one migration.
- A new MCP tool ships.
- A new top-level Tauri plugin is wired.
- Any slice's debt section has been materially knocked down.
- Brand rename lands (a sweep across every page is needed).
The procedure for a refresh is in /home/jake/.claude/projects/-home-jake-Documents-CORBEL-Main/memory/ — search for "architecture-map".