# How OpenHuman's Memory Subsystem Interacts with TinyCortex and the Module Seam

> Discover how OpenHuman's memory subsystem leverages TinyCortex and the module seam. Learn about its contract-first architecture and in-process communication via TinyBus.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: internals
- Published: 2026-09-01

---

**OpenHuman's memory subsystem delegates all storage and retrieval operations to TinyCortex through a contract-first architecture defined by the `tinymemory-api` crate, using TinyBus for in-process communication across the module seam while keeping the core binary free of heavy native dependencies.**

The `tinyhumansai/openhuman` repository implements a modular memory architecture that separates the core engine from storage implementations. This design enables the **OpenHuman memory subsystem** to communicate with TinyCortex exclusively through a well-defined contract, reducing binary size and improving system resilience. By routing all memory operations through the module seam, the system maintains high performance without embedding the full TinyCortex engine in the product binary.

## Contract-First Architecture with `tinymemory-api`

The foundation of the memory subsystem relies on **`tinymemory-api`**, a standalone contract crate that defines the wire-format types crossing the module boundary. Located in [`src/openhuman/memory/api.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/api.rs), this crate re-exports critical types including `Chunk`, `MemoryError`, and `Capabilities` that both the core process and native modules use to communicate.

Because the core does not embed the TinyCortex engine directly, it instead hosts a lightweight **module host** that serializes memory calls into TinyBus protocol requests. Every operation—whether `list_chunks`, `retrieve`, or `store`—becomes a `bus::call` annotated with the contract version. This separation ensures the core and memory modules compile independently; type mismatches surface at compile time rather than runtime.

## The Module Seam and `ModuleMemoryProvider`

When OpenHuman requires memory backend functionality, it instantiates a **`ModuleMemoryProvider`** defined in [`src/openhuman/modules/memory.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/memory.rs). This provider manages the complete lifecycle of the memory module interaction.

### Module Loading and Verification

The loading process begins in [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs), where the registry selects a release-verified native library (`.so` or `.dylib`) implementing the `tinymemory` contract. Each release pins a specific SHA-256 digest to prevent tampering or version drift.

### Handshake and Bus Initialization

Upon loading, the module advertises its contract version through a handshake protocol. The core validates this against `tinymemory-api::CONTRACT_VERSION` before establishing communication. A **TinyBus broker** initializes per process via `OnceBus::init_in_process()`, providing the provider with a `BusHandle` for serving calls.

### Call Routing and Fault Isolation

All memory requests route through `bus::call("tinymemory", …)`, invoking handlers like `list_chunks`, `store_chunk`, or `retrieve` within the module. Because the module runs **in-process**, latency remains minimal while the bus architecture isolates failures. Panics inside the module convert to `MemoryError::ModuleFailed`, allowing the core to continue operating. If loading fails entirely, the system falls back to a **null provider** that returns empty results rather than crashing.

## TinyCortex Migration and Current Relationship

Historically, TinyCortex functioned as `tinymemory-core`, embedded directly within the binary. The 2026-08-31 migration documented in [`docs/tinycortex-migration-spec.md`](https://github.com/tinyhumansai/openhuman/blob/main/docs/tinycortex-migration-spec.md) extracted this engine into a native module, transforming it into a **dev-dependency** used only for testing.

### Architectural Rationale

The migration removed approximately 1MiB of native dependencies including SQLite and cryptographic libraries from the product binary. Users who require full memory capabilities enable the **`memory`** feature, which loads the TinyCortex module at runtime; otherwise, the null provider maintains system operation.

### Parity Verification

To ensure the module matches original engine capabilities, the repository maintains [`docs/tinycortex-parity-checklist.md`](https://github.com/tinyhumansai/openhuman/blob/main/docs/tinycortex-parity-checklist.md). This CI-driven checklist verifies contract-exposed APIs support identical functionality—including chunk pagination and embedding retrieval—guaranteeing the module seam serves as a drop-in replacement.

## Practical Implementation Examples

The following examples demonstrate interacting with the memory subsystem through its public API.

Retrieving recent chunks routes through the provider to TinyCortex:

```rust
use openhuman::memory::api::{Chunk, MemoryError};
use openhuman::memory::ops::list_chunks;

async fn recent_chunks() -> Result<Vec<Chunk>, MemoryError> {
    // Routes through ModuleMemoryProvider to TinyBus
    list_chunks().await
}

```

Storing document content follows the same contract path:

```rust
use openhuman::memory::ops::store_chunk;
use openhuman::memory::api::{Chunk, StoreChunkRequest};

async fn ingest_document(text: &str) -> Result<Chunk, MemoryError> {
    let request = StoreChunkRequest {
        content: text.into(),
        ..Default::default()
    };
    // Invokes the module's store_chunk handler via bus::call
    store_chunk(request).await
}

```

## Summary

- **OpenHuman's memory subsystem** operates exclusively through the `tinymemory-api` contract crate, ensuring type safety across the core-module boundary.
- The **`ModuleMemoryProvider`** in [`src/openhuman/modules/memory.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/memory.rs) manages TinyCortex integration via TinyBus, loading verified native modules from [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs).
- TinyCortex migrated from embedded engine to optional native module in August 2026, reducing core binary size by approximately 1MiB while maintaining functionality through the module seam.
- Fault isolation via TinyBus converts module panics to `MemoryError::ModuleFailed`, with automatic fallback to a null provider if the module fails to load.
- The architecture supports independent versioning, allowing TinyCortex updates without core recompilation beyond updating the pinned SHA-256 digest.

## Frequently Asked Questions

### What is the module seam in OpenHuman?

The **module seam** is the architectural boundary separating the OpenHuman core from native module implementations. It consists of the contract definitions in `tinymemory-api`, the TinyBus communication protocol, and the `ModuleMemoryProvider` that routes calls to loaded native libraries. This seam allows heavy dependencies like TinyCortex to reside outside the product binary while maintaining in-process performance characteristics.

### How does TinyBus isolate memory module failures?

TinyBus creates a broker per process using `OnceBus::init_in_process()` that wraps module calls in isolation boundaries. When the TinyCortex module panics during operations like `retrieve` or `store_chunk`, the broker catches the panic and translates it into a `MemoryError::ModuleFailed` response. This mechanism prevents memory engine crashes from terminating the OpenHuman core process.

### Why was TinyCortex removed from the core binary?

The TinyCortex engine was extracted from the core binary during the August 2026 migration to eliminate approximately 1MiB of native dependencies including SQLite and cryptographic libraries. Moving TinyCortex to a loadable module reduces the base binary size and allows users to optionally enable memory functionality through the `memory` feature flag, while the core can operate with a lightweight null provider when memory features are disabled.

### Can third-party modules implement the memory contract?

Yes, any native module implementing the `tinymemory-api` contract types and responding to standard TinyBus calls like `list_chunks` and `store_chunk` can serve as the memory backend. The [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs) component loads modules based on SHA-256 verification, meaning third-party implementations must be registered and pinned in the registry to be recognized by the `ModuleMemoryProvider`.