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>
4.7 KiB
name, type, slice, last_verified
| name | type | slice | last_verified |
|---|---|---|---|
| Core recommendation scoring | architecture-map-page | 05-core-storage-hotkey-build | 2026/05/09 |
Core recommendation scoring
Where you are: Architecture map → Core, Storage, Hotkey, Build → Core recommendation scoring
Plain English summary. Given a SystemProfile (RAM, CPU, GPU, OS), score every model in the registry and rank them. The top entry is what Magnotia recommends. No boolean flags or scattered "is recommended" markers — position in the ranked list is the recommendation.
At a glance
- File:
crates/core/src/recommendation.rs(197 LOC, 113 of which are tests). - External deps: standard library only.
- Public surface:
ScoredModel,score_model,rank_recommendations. - Consumers: slice 2 model commands (frontend exposes the ranked list), the model picker UI (slice 1).
What's in here
ScoredModel — crates/core/src/recommendation.rs:7
pub struct ScoredModel {
pub entry: &'static ModelEntry,
pub score: f64,
pub reason: String,
}
Borrows the registry entry by 'static reference (no allocation per call). reason is a user-facing explanatory string, prefilled with model.description if no override applied.
score_model(model, profile) -> Option<ScoredModel> — crates/core/src/recommendation.rs:15
Pure function. Returns None when the model exceeds the system's RAM budget. Otherwise computes:
| Component | Score |
|---|---|
SpeedTier::Instant |
+40 |
SpeedTier::Fast |
+30 |
SpeedTier::Moderate |
+20 |
SpeedTier::Slow |
+10 |
AccuracyTier::Excellent |
+30 |
AccuracyTier::Great |
+20 |
AccuracyTier::Good |
+10 |
| GPU acceleration available for this model's engine | +15 |
Headroom > 4 GB above model.ram_required |
+10 |
GPU acceleration matrix (recommendation.rs:36-49):
- Whisper: any of
metal,vulkan,cuda. - Parakeet / Moonshine:
cudaorvulkan.
When GPU acceleration applies, reasons.push("GPU accelerated on your system"). Otherwise reason = model.description.to_string().
rank_recommendations(profile) -> Vec<ScoredModel> — crates/core/src/recommendation.rs:71
Filters out registry entries that exceed RAM, scores the rest, sorts descending by score, returns the vector. partial_cmp falls through to Ordering::Equal if NaN appears (defensive; the scoring path can't produce NaN today).
Data flow / contract
- Pure function over
&SystemProfileand the&'static [ModelEntry]from the registry. - Order is fully determined by score, with ties broken by registry order (which is what
sort_bypreserves). - The "Parakeet first when fits" expectation is asserted by a test at
recommendation.rs:184: any machine with enough RAM for Parakeet sees Parakeet at index 0.
Tests
6 tests in crates/core/src/recommendation.rs:85-197. Test fixtures profile_with_ram and profile_with_gpu build minimal SystemProfiles.
score_model_excludes_models_exceeding_available_ram— RAM budget guard.score_model_includes_models_fitting_in_ram— happy path.score_model_boosts_gpu_accelerated_models— GPU bonus is real.rank_recommendations_places_highest_score_first— sort invariant.rank_recommendations_returns_empty_for_very_low_ram— degenerate case.parakeet_is_top_recommendation_when_hardware_supports_it— asserts the implicit policy that English-speaking users on capable hardware see Parakeet first because it beats Whisper on English at lower latency.
Watch-outs
- No CPU-feature gate. A pre-AVX2 CPU does not down-rank Whisper or Parakeet entries. The runtime-capabilities banner (slice 2) handles that user-facing warning. Worth considering whether a hard down-rank ought to live here too.
- Recommendation ignores download cost. A user on a slow connection still sees
whisper-distil-large-v3ranked first because it scores 30+30+10 = 70 against Parakeet's 40+20+10 = 70 (tie, registry order picks Parakeet). On a 4 GB-RAM machine, onlywhisper-base-enandwhisper-tiny-ensurvive RAM filtering, so the ordering is well-behaved on low-end hardware. - GPU scoring keys off the
Enginevariant, not the model size. A 75 MB Whisper Tiny on a Vulkan GPU still gets the +15 bonus, which is technically correct (the inference does run on GPU) but is a marginal preference signal at that size. reasonisString, not a structured enum. UI that wants to badge the reason ("GPU accelerated", "Best for your RAM") needs to parse the string today. Worth pivoting to a discriminated union when more reasons land.