Found during the pure-refactor pass on claude/rust-codebase-refactor-7ot3v1; deliberately not fixed there because the fix is a behavior decision, not a refactor.
What the code says vs. what it does
vault_info_impl (crates/b2-desktop/src/commands.rs) documents itself as a model-free read — "the real model is never loaded here." But it calls crate::semantic_available() (crates/b2-desktop/src/main.rs), and that calls LocalEmbedder::load — which parses config.json, builds the tokenizer, mmaps model.safetensors, and constructs a full BertModel (crates/b2-embed/src/model.rs).
So vault_info pays a full model load on every call, and it sits on the first-paint path — exactly the path the project/embed split (index-engine.md) exists to keep model-free. The comment is load-bearing and currently says the opposite of what happens, which is why the surrounding code shouldn't be refactored around until this is settled.
Options (each changes observable behavior somewhere)
- Probe files, don't load —
semantic_available uses EmbedConfig::is_model_provisioned / b2_embed::model::files_present (the one "installed" check after the refactor) instead of a full load. Cheap and honest for the common case, but a present-but-corrupt model would report semantic: true and only fail later at reindex/search. That failure is already fail-fast and actionable, so this may be acceptable.
- Cache the probe — keep the full-load check but do it once (e.g.
OnceLock), invalidated when the configured model changes. Keeps the "loadable, not just present" guarantee; adds cache-staleness rules (a model provisioned mid-session should flip the flag).
- Reuse what the call already knows —
vault_info_impl opens the vault read-path; the semantic answer the UI actually needs may be derivable from embed_status + the recorded embedder without probing the model at all.
Whichever way it lands, the doc comment on vault_info_impl needs to match the implementation again.
Found during the pure-refactor pass on
claude/rust-codebase-refactor-7ot3v1; deliberately not fixed there because the fix is a behavior decision, not a refactor.What the code says vs. what it does
vault_info_impl(crates/b2-desktop/src/commands.rs) documents itself as a model-free read — "the real model is never loaded here." But it callscrate::semantic_available()(crates/b2-desktop/src/main.rs), and that callsLocalEmbedder::load— which parsesconfig.json, builds the tokenizer, mmapsmodel.safetensors, and constructs a fullBertModel(crates/b2-embed/src/model.rs).So
vault_infopays a full model load on every call, and it sits on the first-paint path — exactly the path theproject/embedsplit (index-engine.md) exists to keep model-free. The comment is load-bearing and currently says the opposite of what happens, which is why the surrounding code shouldn't be refactored around until this is settled.Options (each changes observable behavior somewhere)
semantic_availableusesEmbedConfig::is_model_provisioned/b2_embed::model::files_present(the one "installed" check after the refactor) instead of a fullload. Cheap and honest for the common case, but a present-but-corrupt model would reportsemantic: trueand only fail later atreindex/search. That failure is already fail-fast and actionable, so this may be acceptable.OnceLock), invalidated when the configured model changes. Keeps the "loadable, not just present" guarantee; adds cache-staleness rules (a model provisioned mid-session should flip the flag).vault_info_implopens the vault read-path; the semantic answer the UI actually needs may be derivable fromembed_status+ the recorded embedder without probing the model at all.Whichever way it lands, the doc comment on
vault_info_implneeds to match the implementation again.