# Loadable Native Modules in OpenHuman: Architecture, Security, and Implementation Guide

> Discover how OpenHuman uses loadable native modules to offload heavyweight tasks securely. Learn about their architecture, security, and implementation in this comprehensive guide.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: architecture
- Published: 2026-08-31

---

**Loadable native modules in OpenHuman are dynamically loaded `cdylib` binaries that offload heavyweight capabilities—such as document codecs, language runtimes, and external connectors—while maintaining strict dependency boundaries and runtime isolation through the TinyBus contract system.**

OpenHuman's core is architected as a single, lightweight Rust binary that hosts essential domains like agent orchestration, memory management, and web chat. However, resource-intensive functionality gets delegated to **loadable native modules**, compiled separately as `cdylib` artifacts. This design pattern keeps the core lean while enabling powerful, independently updatable extensions.

## How Loadable Native Modules Work in OpenHuman

A loadable native module implements the **TinyBus module ABI** and communicates with the core through a formally defined contract in the `‑bus` crate. The core manages module lifecycles through SHA‑256‑verified releases, dynamic loading via `dlopen`, and broker-mediated message passing.

### The Module Loading Pipeline

The typical execution flow spans five stages:

1. **Configuration check** – `Config::modules.enabled` in [`src/openhuman/config/schema/modules.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/config/schema/modules.rs) determines whether module loading is permitted.

2. **Registry lookup** – [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs) holds an immutable table of approved releases with pinned digests.

3. **Policy publication** – On startup, the core publishes a module policy via `modules::memory::set_modules_policy`.

4. **Lazy loading** – The first RPC call requiring a module triggers `dlopen`. The broker instantiates a private TinyBus channel isolating the module from global event publication.

5. **Contract-based communication** – All calls route through the `‑bus` crate, with shared type definitions ensuring compile‑time compatibility.

## Three Core Benefits of Native Modules

### Dependency Boundary Enforcement

Heavy crates—PDF parsers, DOCX processors, image codecs—compile into separate modules rather than bloating the core binary. The `modules::registry` implementation pins exact release digests, allowing independent updates without core redeployment.

### Runtime Isolation Without Processes

Each module runs in‑process but behind a TinyBus broker. The broker traps errors, panics, and timeouts, preventing a buggy native module from terminating the entire application. This achieves isolation overhead lower than process boundaries while maintaining safety.

### Clean Feature-Gate Semantics

The `modules` Cargo feature toggles entire module families. When disabled, related RPC methods return **unknown‑method** rather than **disabled‑error**, preserving API cleanliness. The core checks `config.modules.enabled` before installing any policy.

## Key Source Files and Responsibilities

| File | Role |
|------|------|
| [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs) | Immutable table of trusted module releases with SHA‑256 digests |
| [`src/openhuman/modules/memory.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/memory.rs) | Reference implementation; publishes module policy via TinyBus |
| [`src/openhuman/config/schema/modules.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/config/schema/modules.rs) | Runtime configuration struct for enabling module loading |
| [`src/openhuman/modules/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/mod.rs) | Public façade re‑exports and TinyBus broker bridging |
| [`gitbooks/developing/architecture.md`](https://github.com/tinyhumansai/openhuman/blob/main/gitbooks/developing/architecture.md) | High‑level architecture documentation for module boundaries |

## Configuration and Code Examples

### Enabling Modules in Configuration

```toml
[modules]
enabled = true          # Allow loading of native modules

```

### Publishing a Module Policy Programmatically

```rust
use std::sync::Arc;
use openhuman_core::openhuman::modules::memory::set_modules_policy;

// Build policy from workspace configuration
let policy = Arc::new(my_module_policy);
set_modules_policy(policy);

```

### Invoking Module RPC Methods

```rust
let client = core_rpc_client::new(...);
let result: DocumentResult = client
    .call("documents_generate", json!({ "format": "pdf", "input": "Hello" }))
    .await?;

```

When the `documents` module is compiled out (feature `modules` disabled), this call returns **unknown‑method** because the controller was never registered—maintaining consistent error semantics.

## Contract Safety: Compile-Time API Compatibility

The module's public API lives entirely within a **‑bus crate**. Any method rename, signature change, or payload type modification triggers a compile‑time error on the core side. This eliminates an entire class of runtime version mismatches that plague traditional plugin systems.

## Summary

- **Loadable native modules** keep OpenHuman's core binary minimal by offloading heavy, optional capabilities to separately compiled `cdylib` artifacts.

- **TinyBus contracts** (`‑bus` crate) enforce compile‑time API compatibility and broker-mediated runtime isolation.

- **SHA‑256 release verification** and immutable registry entries in [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs) ensure only trusted code executes.

- **Feature-gate flexibility** allows clean inclusion or exclusion of module families without API pollution.

- Three architectural benefits dominate: **dependency boundaries**, **runtime isolation**, and **clean feature semantics**.

## Frequently Asked Questions

### What format must OpenHuman native modules use?

Native modules must compile as `cdylib` (C-compatible dynamic libraries) that implement the TinyBus module ABI. The core uses standard `dlopen` to load these artifacts at runtime, then bridges them into the TinyBus messaging fabric.

### How does OpenHuman prevent malicious modules from executing?

The [`src/openhuman/modules/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/modules/registry.rs) file maintains an immutable, compile‑time table of approved releases. Each entry includes a SHA‑256 digest; the core verifies downloaded modules against these digests before loading. Additionally, the TinyBus broker restricts each module to a private communication channel that cannot publish global events.

### Can I disable module loading entirely?

Yes. Set `config.modules.enabled = false` in your configuration, or compile without the `modules` Cargo feature. In both cases, module-dependent RPC calls return `unknown‑method` rather than explicit errors, keeping client code resilient to deployment differences.

### What happens when a native module crashes or hangs?

The TinyBus broker intercepts panics, errors, and timeouts from loaded modules. A failing module returns structured errors to callers without propagating the failure to the core process, maintaining overall system stability even with misbehaving extensions.