diff --git a/.github/workflows/ci-lite.yml b/.github/workflows/ci-lite.yml index 18514fca439..dd737809e72 100644 --- a/.github/workflows/ci-lite.yml +++ b/.github/workflows/ci-lite.yml @@ -522,7 +522,7 @@ jobs: # # This asserts the calibration still holds. If it fails, every # projection built on the simulator is suspect until it is fixed. - run: python3 scripts/dep-sim.py --cut-nothing --expect-names 268 + run: python3 scripts/dep-sim.py --cut-nothing --expect-names 264 - name: Guard — new feature-gated test modules must be acknowledged # Self-maintaining coverage: the set of source files that #[cfg]-gate a test on diff --git a/Cargo.lock b/Cargo.lock index 8eae65260f6..4d54dc60f30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6449,14 +6449,7 @@ dependencies = [ name = "tinycortex-api" version = "0.1.1" dependencies = [ - "anyhow", - "async-trait", - "chrono", - "serde", - "serde_json", - "sha2 0.10.9", - "thiserror 2.0.18", - "uuid", + "tinymemory-api", ] [[package]] @@ -6541,7 +6534,6 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "axum", "chrono", "dirs", "futures", @@ -6558,8 +6550,9 @@ dependencies = [ "tinyagents", "tinycortex", "tinycortex-api", - "tinymemory", "tinymemory-api", + "tinymemory-sources", + "tinymemory-sync", "tokio", "tracing", "url", @@ -6567,15 +6560,53 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tinymemory-sources" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "futures", + "regex", + "reqwest", + "schemars", + "serde", + "serde_json", + "tinymemory-api", + "tokio", + "toml 0.9.12+spec-1.1.0", + "tracing", + "uuid", + "walkdir", +] + +[[package]] +name = "tinymemory-sync" +version = "0.1.0" +dependencies = [ + "chrono", + "log", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "tinymemory-tinycortex" version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "chrono", + "log", + "serde", + "serde_json", "tinycortex", - "tinymemory", "tinymemory-api", + "tinymemory-core", + "tokio", + "uuid", ] [[package]] @@ -6797,6 +6828,21 @@ dependencies = [ "toml_edit 0.22.27", ] +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -6821,6 +6867,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" diff --git a/Cargo.toml b/Cargo.toml index cd7cf30444b..9724824d247 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1134,6 +1134,16 @@ should_implement_trait = "allow" too_many_arguments = "allow" while_let_loop = "allow" +# The tinycortex vendored above takes `tinymemory-api` by git (it re-exports +# the TinyMemory contract instead of duplicating it, tinymemory#18 §A1). +# Without this entry cargo resolves that git copy *and* the path copy under +# vendor/tinymemory as two distinct crates, and `tinymemory_api::MemoryCategory` +# from one is not the same type as from the other — the exact duplication §A1 +# deleted, reintroduced by dependency resolution. Same entry tinymemory's own +# workspace carries; the key has no `.git` suffix, matching the dep URL. +[patch."https://github.com/tinyhumansai/tinymemory"] +tinymemory-api = { path = "vendor/tinymemory/api" } + [patch.crates-io] # Upstream 0.2.1 enables reqwest's default native-tls backend even though it # also requests rustls. Patch the official release locally so Linux/macOS do diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index bd98e90200d..19cb84ac1f9 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -7135,14 +7135,7 @@ dependencies = [ name = "tinycortex-api" version = "0.1.1" dependencies = [ - "anyhow", - "async-trait", - "chrono", - "serde", - "serde_json", - "sha2 0.10.9", - "thiserror 2.0.20", - "uuid", + "tinymemory-api", ] [[package]] @@ -7212,7 +7205,6 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "axum", "chrono", "dirs 5.0.1", "futures", @@ -7229,8 +7221,9 @@ dependencies = [ "tinyagents", "tinycortex", "tinycortex-api", - "tinymemory", "tinymemory-api", + "tinymemory-sources", + "tinymemory-sync", "tokio", "tracing", "url", @@ -7238,15 +7231,53 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tinymemory-sources" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "futures", + "regex", + "reqwest 0.12.28", + "schemars 1.2.2", + "serde", + "serde_json", + "tinymemory-api", + "tokio", + "toml 0.9.12+spec-1.1.0", + "tracing", + "uuid", + "walkdir", +] + +[[package]] +name = "tinymemory-sync" +version = "0.1.0" +dependencies = [ + "chrono", + "log", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "tinymemory-tinycortex" version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "chrono", + "log", + "serde", + "serde_json", "tinycortex", - "tinymemory", "tinymemory-api", + "tinymemory-core", + "tokio", + "uuid", ] [[package]] diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 888e0317667..0d37502cbd6 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -251,6 +251,16 @@ sandbox-bubblewrap = [] # e2e-test-support`. See app/scripts/e2e-build.sh. e2e-test-support = ["openhuman_core/e2e-test-support"] +# The tinycortex vendored above takes `tinymemory-api` by git (it re-exports +# the TinyMemory contract instead of duplicating it, tinymemory#18 §A1). +# Without this entry cargo resolves that git copy *and* the path copy under +# vendor/tinymemory as two distinct crates, and `tinymemory_api::MemoryCategory` +# from one is not the same type as from the other — the exact duplication §A1 +# deleted, reintroduced by dependency resolution. Same entry tinymemory's own +# workspace carries; the key has no `.git` suffix, matching the dep URL. +[patch."https://github.com/tinyhumansai/tinymemory"] +tinymemory-api = { path = "../../vendor/tinymemory/api" } + [patch.crates-io] # Keep reqwest defaults disabled in this independent Cargo world too. Without # this patch, the registry release reintroduces native-tls/OpenSSL on Linux. diff --git a/scripts/kernel-floor.limits b/scripts/kernel-floor.limits index ed46bff9633..ddca09e1cf1 100644 --- a/scripts/kernel-floor.limits +++ b/scripts/kernel-floor.limits @@ -13,6 +13,22 @@ # Simulate with: scripts/dep-sim.py --cut # # History +# 286/264/2 2026-08-19 tinymemory bumped across its #18 arc (-4 names, 0 +# packages net, native unchanged). A shed, not a gate, and +# a downstream one: tinymemory#43 (§D2) moved `axum` from +# tinymemory-core's normal dependencies to dev-only — its +# four references there were all inside `mod tests` — and +# that takes the whole tail out of this always-on profile: +# `axum`, `axum-core`, `axum-macros`, `matchit`, +# `httpdate`, `serde_path_to_error` leave (-6). Two enter: +# `tinymemory-sources` and `tinymemory-sync`, the crates +# tinymemory#46/#48 split the source readers and the +# engine-free Composio sync into — both already-compiled +# code relocated, so packages stay flat. Net -4 names. +# Measured on CI (Linux): `scripts/kernel-floor.sh flows +# --json` -> 286/264/2. (macOS resolves 286/265/2 per the +# documented target skew.) The crate-set diff old-pin vs +# new-pin confirms exactly the six-out/two-in above. # 286/268/2 2026-08-15 tinywallet de-vendored back to a submodule + module # (-11 packages / -11 names). The inlined `tinywallet` # crate copy is deleted; key derivation and transaction @@ -316,4 +332,4 @@ # (libsqlite3-sys, ring) — see docs/plans MIGRATION-PLAN G6. # 307/284 2026-08-12 Re-baseline after the upstream lockfile resolution; # `flows` remains at two native packages. -flows:286:268:2 +flows:286:264:2 diff --git a/src/openhuman/integrations/composio/ops/connections.rs b/src/openhuman/integrations/composio/ops/connections.rs index 8ca046a2f49..c10b048f3aa 100644 --- a/src/openhuman/integrations/composio/ops/connections.rs +++ b/src/openhuman/integrations/composio/ops/connections.rs @@ -163,7 +163,17 @@ pub async fn composio_delete_connection( Err(_) => None, }; let memory_targets = if clear_memory { - composio_memory_targets_for_connection(config, toolkit.as_deref(), connection_id) + // The LIVE process client — target discovery loads notion sync state + // through it. Resolved here, not constructed inside the discovery: + // `MemoryClient::from_workspace_dir` starts an ingestion worker at + // construction, so building one per delete put a second worker on the + // live store every time. + let memory = crate::openhuman::memory::ops::helpers::active_memory_client() + .await + .map_err(|error| { + format!("[composio] delete_connection cannot resolve the memory client: {error}") + })?; + composio_memory_targets_for_connection(&memory, toolkit.as_deref(), connection_id) .await .map_err(|error| { format!("[composio] delete_connection cannot enumerate memory targets: {error:#}") diff --git a/src/openhuman/integrations/composio/ops/memory_cleanup.rs b/src/openhuman/integrations/composio/ops/memory_cleanup.rs index 5e670258080..7a0712716d0 100644 --- a/src/openhuman/integrations/composio/ops/memory_cleanup.rs +++ b/src/openhuman/integrations/composio/ops/memory_cleanup.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use crate::openhuman::config::Config; -use crate::openhuman::memory::MemoryClient; use tinymemory_core::store::chunks::store as memory_tree_store; use tinymemory_core::store::chunks::types::SourceKind; +use tinymemory_core::store::MemoryClientRef; #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum MemoryCleanupTarget { @@ -48,8 +48,14 @@ impl MemoryCleanupTarget { } } +/// `memory` is the caller's handle on the live store — the RPC path resolves +/// the process client, tests pass one bound to their own workspace. Taken as a +/// parameter rather than constructed here: `MemoryClient::from_workspace_dir` +/// starts an ingestion worker at construction, so building one per +/// connection-delete put a second worker on the live store every time — the +/// exact hazard `memory::bypass_allowlist_tests` names for that constructor. pub(crate) async fn composio_memory_targets_for_connection( - config: &Config, + memory: &MemoryClientRef, toolkit: Option<&str>, connection_id: &str, ) -> anyhow::Result> { @@ -63,7 +69,7 @@ pub(crate) async fn composio_memory_targets_for_connection( format!("slack:{connection_id}"), )], "gmail" => gmail_memory_sources_for_connection(connection_id), - "notion" => notion_memory_targets_for_connection(config, connection_id).await?, + "notion" => notion_memory_targets_for_connection(memory, connection_id).await?, "drive" | "googledrive" | "google_drive" => { drive_memory_targets_for_connection(connection_id) } @@ -82,19 +88,12 @@ fn gmail_memory_sources_for_connection(connection_id: &str) -> Vec anyhow::Result> { let mut targets = connection_scoped_document_targets("notion", connection_id); - let memory = Arc::new( - MemoryClient::from_workspace_dir(config.workspace_dir.clone()).map_err(|error| { - anyhow::anyhow!( - "failed to open memory client for notion cleanup target discovery: {error}" - ) - })?, - ); - let adapter = tinymemory_core::tinycortex::HostSyncAdapter::new(memory); + let adapter = tinymemory_core::tinycortex::HostSyncAdapter::new(Arc::clone(memory)); let state = tinycortex::memory::sync::SyncState::load(&adapter, "notion", connection_id) .await .map_err(|error| { diff --git a/src/openhuman/integrations/composio/ops_tests.rs b/src/openhuman/integrations/composio/ops_tests.rs index 154ead91c42..af966d53789 100644 --- a/src/openhuman/integrations/composio/ops_tests.rs +++ b/src/openhuman/integrations/composio/ops_tests.rs @@ -908,10 +908,10 @@ async fn notion_cleanup_targets_include_synced_page_sources() { let mut state = SyncState::new("notion", "conn-1"); state.mark_synced("page-a@2026-01-01T00:00:00Z"); state.mark_synced("page-b"); - let adapter = tinymemory_core::tinycortex::HostSyncAdapter::new(memory); + let adapter = tinymemory_core::tinycortex::HostSyncAdapter::new(std::sync::Arc::clone(&memory)); state.save(&adapter).await.expect("sync state should save"); - let targets = composio_memory_targets_for_connection(&config, Some("notion"), "conn-1") + let targets = composio_memory_targets_for_connection(&memory, Some("notion"), "conn-1") .await .expect("notion cleanup targets should resolve"); @@ -951,7 +951,7 @@ async fn notion_cleanup_targets_surface_corrupt_sync_state() { .await .expect("corrupt sync state should be written"); - let err = composio_memory_targets_for_connection(&config, Some("notion"), "conn-1") + let err = composio_memory_targets_for_connection(&memory, Some("notion"), "conn-1") .await .expect_err("corrupt sync state should surface"); @@ -960,12 +960,23 @@ async fn notion_cleanup_targets_surface_corrupt_sync_state() { #[tokio::test] async fn drive_cleanup_targets_are_connection_scoped() { + // The embedding seam fails loudly when unwired; same reasoning as the + // notion tests above. + crate::openhuman::memory::host_impls::install_for_tests(); let tmp = tempfile::tempdir().unwrap(); let config = test_config(&tmp); + // The drive arm never touches the store, but discovery takes the caller's + // client unconditionally — the parameter is the seam the notion tests + // inject through. + let drive_memory = std::sync::Arc::new( + MemoryClient::from_workspace_dir(config.workspace_dir.clone()) + .expect("memory client should initialise"), + ); - let targets = composio_memory_targets_for_connection(&config, Some("google_drive"), "conn-1") - .await - .expect("drive cleanup targets should resolve"); + let targets = + composio_memory_targets_for_connection(&drive_memory, Some("google_drive"), "conn-1") + .await + .expect("drive cleanup targets should resolve"); assert!(targets.contains(&MemoryCleanupTarget::Exact( SourceKind::Document, diff --git a/src/openhuman/memory/bypass_allowlist_tests.rs b/src/openhuman/memory/bypass_allowlist_tests.rs index a803e55af29..4c0bca12872 100644 --- a/src/openhuman/memory/bypass_allowlist_tests.rs +++ b/src/openhuman/memory/bypass_allowlist_tests.rs @@ -225,9 +225,14 @@ const ALLOWED: &[(&str, &str, &str)] = &[ // `MemoryGuard` over an in-memory provider rather than a raw handle. // ── Composio integration: &MemoryClientRef parameter shape ── ( - "src/openhuman/integrations/composio/ops/memory_cleanup.rs", - "MemoryClient::from_workspace_dir(", - "cleanup runs off a config workspace with no live binding", + "src/openhuman/integrations/composio/ops/connections.rs", + "active_memory_client(", + "delete_connection resolves the LIVE client for cleanup-target \ + discovery, which loads notion sync state through HostSyncAdapter — a \ + seam beneath the contract with no provider door. Replaces \ + memory_cleanup.rs constructing a second engine per delete via \ + from_workspace_dir, which started a second ingestion worker on the \ + live store every time", ), ( "src/openhuman/integrations/composio/schemas.rs", @@ -350,17 +355,37 @@ const ALLOWED: &[(&str, &str, &str)] = &[ "global::client(", "resolved only to reach profile_conn() for the fixture seed/read-back", ), - // ── Inline test module and engine seam ── - ( - "vendor/tinymemory/core/src/tinycortex/sync.rs", + // ── Inline test modules and the two sync seams ── + // + // tinymemory#18 §C1 renamed `core/src/tinycortex/` to `core/src/engine/`, + // and §B1 added `core/src/sync/pipelines/host.rs` — the engine-FREE sync + // runner, an adapter over `MemoryClient` shaped exactly like the engine + // seam it sits beside. Both are beneath the contract, not above it: they + // are what a bound driver is built FROM, which is why they name the raw + // client. Their `from_workspace_dir` hits are all inside inline + // `#[cfg(test)]` modules (the #61 connection-guard tests), which the + // scanner does not brace-track. + ( + "vendor/tinymemory/core/src/engine/sync.rs", "MemoryClient::from_workspace_dir(", "inline #[cfg(test)] module only; the scanner does not brace-track test blocks", ), ( - "vendor/tinymemory/core/src/tinycortex/sync.rs", + "vendor/tinymemory/core/src/engine/sync.rs", "global::client_if_ready(", "the TinyCortex engine seam; it sits beneath the contract, not above it", ), + ( + "vendor/tinymemory/core/src/sync/pipelines/host.rs", + "MemoryClient::from_workspace_dir(", + "inline #[cfg(test)] module only (the connection-guard tests); not brace-tracked", + ), + ( + "vendor/tinymemory/core/src/sync/pipelines/host.rs", + "global::client_if_ready(", + "the engine-free sync runner's seam over the bound client; beneath the contract, \ + the same way the engine seam beside it is", + ), ]; /// True for source files the lint deliberately does not scan. diff --git a/tests/fixtures/memory_golden/README.md b/tests/fixtures/memory_golden/README.md index 567d80bd479..47bfce6ddfc 100644 --- a/tests/fixtures/memory_golden/README.md +++ b/tests/fixtures/memory_golden/README.md @@ -5,10 +5,10 @@ | | | | --- | --- | -| Captured at commit | `cdf997b4f8a9e751c7f3c9a24920e808d14d75ed` | -| Captured on | 2026-08-10T12:26:26Z | +| Captured at commit | `01b7814f3ff81c9614ade9026f05d00c8ca4cfb5` | +| Captured on | 2026-08-19T11:05:15Z | | Generator | `regenerate_golden_fixture` in `tests/memory_golden_fixture_e2e.rs` | -| Seeder | `tinymemory_core::store::golden::seed` | +| Seeder | `openhuman_core::openhuman::memory::store::golden::seed` | ## Contents diff --git a/tests/fixtures/memory_golden/manifest.txt b/tests/fixtures/memory_golden/manifest.txt index 9b8666e92aa..ee675f87205 100644 --- a/tests/fixtures/memory_golden/manifest.txt +++ b/tests/fixtures/memory_golden/manifest.txt @@ -1,6 +1,6 @@ # GENERATED — do not hand-edit. # Derived from tests/fixtures/memory_golden/workspace/**.db by -# memory::store::golden::schema_manifest. Regenerate both together with +# memory::store_golden::schema_manifest. Regenerate both together with # scripts/regen-memory-golden-fixture.sh. # 125 schema objects across 2 db file(s). memory/memory.db index idx_episodic_session CREATE INDEX idx_episodic_session ON episodic_log(session_id, timestamp) @@ -37,7 +37,7 @@ memory/memory.db index sqlite_autoindex_user_profile_1 memory/memory.db index sqlite_autoindex_user_profile_2 memory/memory.db index sqlite_autoindex_vector_chunks_1 memory/memory.db pragma user_version 0 -memory/memory.db table conversation_segments CREATE TABLE conversation_segments ( segment_id TEXT PRIMARY KEY, session_id TEXT NOT NULL, namespace TEXT NOT NULL DEFAULT 'global', start_episodic_id INTEGER NOT NULL, end_episodic_id INTEGER, start_timestamp REAL NOT NULL, end_timestamp REAL, turn_count INTEGER NOT NULL DEFAULT 0, summary TEXT, embedding BLOB, topic_keywords TEXT, status TEXT NOT NULL DEFAULT 'open', created_at REAL NOT NULL, updated_at REAL NOT NULL, -- Per-session sequence numbers from tinycortex::memory::archivist::store, populated -- alongside start_episodic_id / end_episodic_id during the FTS5 -> md -- migration. Once STM recall switches its segment-span dedup to use -- (session_id, seq) the legacy episodic_id columns can be dropped. start_seq INTEGER, end_seq INTEGER ) +memory/memory.db table conversation_segments CREATE TABLE conversation_segments ( segment_id TEXT PRIMARY KEY, session_id TEXT NOT NULL, namespace TEXT NOT NULL DEFAULT 'global', start_episodic_id INTEGER NOT NULL, end_episodic_id INTEGER, start_timestamp REAL NOT NULL, end_timestamp REAL, turn_count INTEGER NOT NULL DEFAULT 0, summary TEXT, embedding BLOB, topic_keywords TEXT, status TEXT NOT NULL DEFAULT 'open', created_at REAL NOT NULL, updated_at REAL NOT NULL, -- Per-session sequence numbers from crate::engine::backend::archivist::store, populated -- alongside start_episodic_id / end_episodic_id during the FTS5 -> md -- migration. Once STM recall switches its segment-span dedup to use -- (session_id, seq) the legacy episodic_id columns can be dropped. start_seq INTEGER, end_seq INTEGER ) memory/memory.db table episodic_fts CREATE VIRTUAL TABLE episodic_fts USING fts5( session_id, role, content, lesson, content=episodic_log, content_rowid=id, tokenize='porter unicode61' ) memory/memory.db table episodic_fts_config CREATE TABLE 'episodic_fts_config'(k PRIMARY KEY, v) WITHOUT ROWID memory/memory.db table episodic_fts_data CREATE TABLE 'episodic_fts_data'(id INTEGER PRIMARY KEY, block BLOB) diff --git a/tests/fixtures/memory_golden/workspace/memory/memory.db b/tests/fixtures/memory_golden/workspace/memory/memory.db index 2f074423e1e..9ee39f41b52 100644 Binary files a/tests/fixtures/memory_golden/workspace/memory/memory.db and b/tests/fixtures/memory_golden/workspace/memory/memory.db differ diff --git a/tests/fixtures/memory_golden/workspace/memory_tree/chunks.db b/tests/fixtures/memory_golden/workspace/memory_tree/chunks.db index 0231cd4840f..085ae0ed287 100644 Binary files a/tests/fixtures/memory_golden/workspace/memory_tree/chunks.db and b/tests/fixtures/memory_golden/workspace/memory_tree/chunks.db differ diff --git a/tests/raw_coverage/memory_threads_raw_coverage_e2e.rs b/tests/raw_coverage/memory_threads_raw_coverage_e2e.rs index f8b2adc142f..cf6c4be0d63 100644 --- a/tests/raw_coverage/memory_threads_raw_coverage_e2e.rs +++ b/tests/raw_coverage/memory_threads_raw_coverage_e2e.rs @@ -719,8 +719,18 @@ async fn memory_source_status_counts_reader_and_composio_prefixes() { ]; upsert_chunks(&config, &chunks).expect("upsert chunks"); with_connection(&config, |conn| { + // Mark the chunk embedded the way the status query now READS it. + // Setting `mem_tree_chunks.embedding` no longer means anything: that + // legacy column is never written by the engine, which is why the + // status query used to report every chunk pending forever + // (tinymemory#59 item 2). It counts against the live + // `mem_tree_chunk_embeddings` sidecar now, so the fixture writes + // there. conn.execute( - "UPDATE mem_tree_chunks SET embedding = X'00010203' WHERE source_id = ?1", + "INSERT INTO mem_tree_chunk_embeddings \ + (chunk_id, model_signature, vector, dim, created_at) \ + SELECT id, 'test-model', X'00010203', 4, 0.0 \ + FROM mem_tree_chunks WHERE source_id = ?1", ["mem_src:src_folder:note-1"], )?; Ok(()) diff --git a/vendor/tinycortex b/vendor/tinycortex index 5fdeac984c0..8401346b574 160000 --- a/vendor/tinycortex +++ b/vendor/tinycortex @@ -1 +1 @@ -Subproject commit 5fdeac984c09d2dac65b61e92fd27e2c92ce1e6b +Subproject commit 8401346b574cacb1dc0cf6b36bc608ff5ef9f6f5 diff --git a/vendor/tinymemory b/vendor/tinymemory index dc3a7252628..f8bd9af43e3 160000 --- a/vendor/tinymemory +++ b/vendor/tinymemory @@ -1 +1 @@ -Subproject commit dc3a725262801bef521a6bde44a3b396e25469e1 +Subproject commit f8bd9af43e3d9b793eeddea7ad91741136dd563d