From d0a7c8cf15aecb60bc64f6da97533d0470a9b284 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Fri, 14 Aug 2026 09:56:11 +0300 Subject: [PATCH 1/5] chore: files changed core/src/tinycortex/config.rs Auto-committed-on: dragonfly Co-authored-by: Medulla --- core/src/tinycortex/config.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/tinycortex/config.rs b/core/src/tinycortex/config.rs index d06c0b4..5617494 100644 --- a/core/src/tinycortex/config.rs +++ b/core/src/tinycortex/config.rs @@ -9,6 +9,10 @@ //! Field provenance: //! - `workspace` ← the memory workspace root (same root `MemoryClient` opens). //! - `embedding.dim` ← `config.memory().embedding_dimensions`. +//! - `embedding.provider` ← [`effective_embedder_slug`], the slug the embedder +//! ladder actually resolves to — **not** `config.memory().embedding_provider`. +//! See the note on the mapping below; reading that field here would mis-key +//! every locally-embedded row. //! - `embedding.model` ← `config.memory().embedding_model`. //! - `embedding.strict` ← `config.memory_tree().embedding_strict` (when false the //! engine tolerates an inert embedder and falls back to scope+recency rerank). From 2ce7b7018ed15e84c8b68f213c7b9c4aaa50de9f Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Fri, 14 Aug 2026 09:56:18 +0300 Subject: [PATCH 2/5] chore: files changed core/src/tinycortex/config.rs Auto-committed-on: dragonfly Co-authored-by: Medulla --- core/src/tinycortex/config.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/src/tinycortex/config.rs b/core/src/tinycortex/config.rs index 5617494..fab0a39 100644 --- a/core/src/tinycortex/config.rs +++ b/core/src/tinycortex/config.rs @@ -43,8 +43,20 @@ use crate::Config; pub fn memory_config_from(config: &Config, workspace: PathBuf) -> MemoryConfig { let mut mc = MemoryConfig::new(workspace); mc.content_root = Some(config.memory_tree_content_root()); + // `provider` is part of the signature every per-model sidecar row is keyed + // by, so it has to name the backend that actually produced the vectors — + // two backends serving one model id must never share a vector space. + // + // That is `effective_embedder_slug`, which walks the same resolution ladder + // the read and write factories walk, and NOT `config.memory() + // .embedding_provider`: the ladder resolves local Ollama from + // `memory_tree.embedding_endpoint` or the unified + // `workload_local_model("embeddings")` setting, and neither path rewrites + // that field — so a user embedding entirely locally still reads as `"cloud"` + // there. Keying on it would file local vectors under the cloud provider. mc.embedding = EmbeddingConfig { dim: config.memory().embedding_dimensions, + provider: effective_embedder_slug(config).to_string(), model: config.memory().embedding_model.clone(), strict: config.memory_tree().embedding_strict, }; From 1bdac9b0c3b5185625fad433c5bc7681ebeaa4d2 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Fri, 14 Aug 2026 09:56:22 +0300 Subject: [PATCH 3/5] chore: files changed core/src/tinycortex/config.rs Auto-committed-on: dragonfly Co-authored-by: Medulla --- core/src/tinycortex/config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/tinycortex/config.rs b/core/src/tinycortex/config.rs index fab0a39..eb38da5 100644 --- a/core/src/tinycortex/config.rs +++ b/core/src/tinycortex/config.rs @@ -31,6 +31,7 @@ use tinycortex::memory::MemoryConfig; #[cfg(test)] use tinymemory_api::host::test_support::TestHostConfig; +use crate::tree::score::embed::effective_embedder_slug; use crate::Config; /// Build a [`MemoryConfig`] from the host [`Config`] and the resolved memory From 3d42678942861fe22d2a84d1521e118607b0ea3b Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Fri, 14 Aug 2026 09:57:35 +0300 Subject: [PATCH 4/5] chore: files changed Cargo.lock,vendor/tinycortex Auto-committed-on: dragonfly Co-authored-by: Medulla --- Cargo.lock | 61 +++++++++++++---------------------------------- vendor/tinycortex | 2 +- 2 files changed, 17 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e3583d..0ba37a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1531,15 +1531,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "serde_spanned" version = "1.1.1" @@ -1783,7 +1774,7 @@ dependencies = [ "tinyagents", "tinycortex-api", "tokio", - "toml 0.8.23", + "toml 1.1.4+spec-1.1.0", "tracing", "uuid", "walkdir", @@ -1976,18 +1967,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit", -] - [[package]] name = "toml" version = "0.9.12+spec-1.1.0" @@ -1996,7 +1975,7 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.1.1", + "serde_spanned", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", @@ -2004,12 +1983,18 @@ dependencies = [ ] [[package]] -name = "toml_datetime" -version = "0.6.11" +name = "toml" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" dependencies = [ - "serde", + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.4", ] [[package]] @@ -2022,17 +2007,12 @@ dependencies = [ ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ - "indexmap", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow 0.7.15", + "serde_core", ] [[package]] @@ -2044,12 +2024,6 @@ dependencies = [ "winnow 1.0.4", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" version = "1.1.2+spec-1.1.0" @@ -2595,9 +2569,6 @@ name = "winnow" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] [[package]] name = "winnow" diff --git a/vendor/tinycortex b/vendor/tinycortex index be7b395..0a7a067 160000 --- a/vendor/tinycortex +++ b/vendor/tinycortex @@ -1 +1 @@ -Subproject commit be7b395354271082953d2594765aded73975b54c +Subproject commit 0a7a06710fce8dba1cdb06b3e4640c351bba800c From bff74cf23230e8f8198eb2dac46c46479f2fd507 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Fri, 14 Aug 2026 09:58:04 +0300 Subject: [PATCH 5/5] chore: files changed core/src/tinycortex/config.rs Auto-committed-on: dragonfly Co-authored-by: Medulla --- core/src/tinycortex/config.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/core/src/tinycortex/config.rs b/core/src/tinycortex/config.rs index eb38da5..75a1dda 100644 --- a/core/src/tinycortex/config.rs +++ b/core/src/tinycortex/config.rs @@ -95,6 +95,29 @@ mod tests { assert!(mc.embedding.strict); } + #[test] + fn embedding_provider_is_the_resolved_slug_not_the_config_field() { + // The regression this pins: `memory.embedding_provider` is not + // authoritative. A user embedding entirely locally still reads as + // `"cloud"` there, because neither local rung of the ladder rewrites + // the field. Since `provider` keys the vector space, mapping it + // straight through would file local vectors under the cloud provider. + let mut config = TestHostConfig::default(); + config.memory.embedding_provider = "cloud".to_string(); + // Rung 1 of the ladder: an explicit Ollama endpoint + model. + config.memory_tree.embedding_endpoint = Some("http://127.0.0.1:11434".to_string()); + config.memory_tree.embedding_model = Some("nomic-embed-text".to_string()); + + let mc = memory_config_from(&config, PathBuf::from("/tmp/ws")); + + assert_eq!( + mc.embedding.provider, "ollama", + "locally-resolved embeddings must be keyed as ollama, not the \ + stale 'cloud' spelling in memory.embedding_provider" + ); + assert_ne!(mc.embedding.provider, config.memory.embedding_provider); + } + #[test] fn tree_defaults_match_engine_constants() { // The base mapping leaves tree budgets at the crate defaults, which are