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() }