From 7d2dac036d2be9da421ebcfcb5e5157d73804d80 Mon Sep 17 00:00:00 2001 From: Shanu Date: Wed, 19 Aug 2026 12:38:02 +0530 Subject: [PATCH] Keep the pin-bump non-breaking: four compat surfaces the audit found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The #18 end-to-end audit's downstream dimension resolved every path OpenHuman imports (1,111 tokens across 33 shim files) against the post-#48 tree. Four tinymemory-side breaks would have surfaced at the next submodule pin bump; each gets the smallest surface that keeps the old path resolving, marked for deletion once downstream migrates. 1. `pub use engine as tinycortex` (doc-hidden) at the core root. OpenHuman re-exports `tinymemory_core::tinycortex` wholesale and 25 call sites reach through it; the §C1 rename would have made the bump a coordinated two-repo edit for zero behavioural gain. 2. `SyncAuditEntry` re-exported from the engine seam. OpenHuman's sources RPC embeds `memory::tinycortex::SyncAuditEntry` in a response type. The type stays core-owned (§B1a); only the address is preserved. 3. `extract_item_id` restored in sync_state. Deleted in §B1a as dead -- measured with too small a grep: OpenHuman's raw-coverage integration tests import and exercise it through the pin. 4. `HostSyncAdapter` also implements core's `SyncStateStore`, beside the engine trait of the same shape. Core's `SyncState::load`/`save` take the core trait now, and OpenHuman pairs that type with this adapter in its integration tests. Same KV calls; one storage, two trait names during the transition. Not fixed here, confirmed for the bump PR on OpenHuman's side: its `store_golden.rs` seeder must absorb `fts5::episodic_insert` now returning `Result` (main drift), and both its cargo workspaces need a `[patch]` entry mapping tinymemory-api's git URL to the submodule path before the vendored tinycortex resolves. Also validated by the audit's refutation pass: the reported live `MemoryClient::new_local()` caller was a stale checkout -- OpenHuman main migrated to `active_memory_client()` in openhuman#5575. cargo test -p tinymemory-core: 847 + e2e passed cargo clippy --all-targets: clean scripts/ci/engine-containment.sh: holds (the alias is `as tinycortex`, not a `tinycortex::` code path) --- core/src/engine/mod.rs | 4 +++ core/src/engine/sync.rs | 28 +++++++++++++++++++ core/src/lib.rs | 9 ++++++ .../src/sync/composio/providers/sync_state.rs | 18 ++++++++++++ 4 files changed, 59 insertions(+) diff --git a/core/src/engine/mod.rs b/core/src/engine/mod.rs index e30605b..aec048c 100644 --- a/core/src/engine/mod.rs +++ b/core/src/engine/mod.rs @@ -71,3 +71,7 @@ pub use sync::{ sync_context, HostSyncAdapter, RawCoverage, RawFileRef, RealCostAccumulator, RebuildOutcome, SourcePipelineFailure, HOST_SYNC_STATE_NAMESPACE, }; +// The audit type, under the seam path OpenHuman already names +// (`memory::tinycortex::SyncAuditEntry` embeds it in an RPC response type). +// The type itself is core-owned (#18 §B1a); only the address is preserved. +pub use crate::sync::audit::SyncAuditEntry; diff --git a/core/src/engine/sync.rs b/core/src/engine/sync.rs index 442521a..ebe6a3f 100644 --- a/core/src/engine/sync.rs +++ b/core/src/engine/sync.rs @@ -695,6 +695,34 @@ impl SyncStateStore for HostSyncAdapter { } } +/// Core's state seam, on the engine adapter. +/// +/// `SyncState` is core-owned now (#18 §B1a) and its `load`/`save` take +/// core's `SyncStateStore`; OpenHuman pairs that type with this adapter in +/// its integration tests. Same KV calls as the engine-trait impl below — +/// one storage, two trait names during the transition. +#[async_trait] +impl crate::sync::composio::providers::sync_state::SyncStateStore for HostSyncAdapter { + async fn get(&self, namespace: &str, key: &str) -> anyhow::Result> { + self.memory + .kv_get(Some(namespace), key) + .await + .map_err(anyhow::Error::msg) + } + + async fn set( + &self, + namespace: &str, + key: &str, + value: &serde_json::Value, + ) -> anyhow::Result<()> { + self.memory + .kv_set(Some(namespace), key, value) + .await + .map_err(anyhow::Error::msg) + } +} + #[async_trait] impl SyncEventSink for HostSyncAdapter { async fn emit(&self, event: SyncEvent) -> anyhow::Result<()> { diff --git a/core/src/lib.rs b/core/src/lib.rs index 8649b55..885e8df 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -40,6 +40,15 @@ pub mod diff; pub mod embedding_adapter; pub mod embedding_host; pub mod engine; +/// The engine module under its pre-#18 name. +/// +/// OpenHuman's shim re-exports `tinymemory_core::tinycortex` wholesale +/// (`memory/mod.rs`), and 25 call sites reach through that path. The rename to +/// `engine` (#18 §C1) would otherwise make the next pin bump a coordinated +/// two-repo edit for zero behavioural gain. An alias, not a module: one item +/// to delete once downstream says `engine`. +#[doc(hidden)] +pub use engine as tinycortex; pub mod events; pub mod global; pub mod ingest_pipeline; diff --git a/core/src/sync/composio/providers/sync_state.rs b/core/src/sync/composio/providers/sync_state.rs index 45459b2..2275185 100644 --- a/core/src/sync/composio/providers/sync_state.rs +++ b/core/src/sync/composio/providers/sync_state.rs @@ -193,6 +193,24 @@ impl SyncState { } } +/// First non-empty string at any of `paths` (dot-separated) in `item`. +/// +/// Removed in the §B1a move as dead within this workspace; restored because +/// OpenHuman's raw-coverage integration tests import and exercise it through +/// the pin — "dead here" was measured with too small a grep. +pub fn extract_item_id(item: &serde_json::Value, paths: &[&str]) -> Option { + paths.iter().find_map(|path| { + let value = path + .split('.') + .try_fold(item, |current, segment| current.get(segment))?; + value + .as_str() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(str::to_owned) + }) +} + fn today() -> String { Utc::now().format("%Y-%m-%d").to_string() }