# OpenHuman DomainSet Harness vs Full: Runtime Presets Explained

> Understand OpenHuman DomainSet harness vs full. Harness initializes core layers for embedded use, while full enables all domains for the complete desktop experience. Learn the difference.

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

---

**`DomainSet::harness()` initializes only the core agent, memory, and security layers required for embedded library usage, while `DomainSet::full()` enables every domain family—including flows, web3, media, and voice—for the complete desktop experience.**

OpenHuman's modular runtime architecture separates domain configuration into the `DomainSet` axis, which determines which controller families are registered at startup. Choosing between `DomainSet::harness()` and `DomainSet::full()` directly impacts binary size, startup latency, and available RPC capabilities in the tinyhumansai/openhuman codebase.

## What is DomainSet in OpenHuman?

The `DomainSet` struct, defined in **[`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs)**, acts as a declarative filter for domain families—logical groupings of controllers, stores, subscribers, and agent tools. Unlike the orthogonal `ServiceSet` axis (which controls background services like UI or sockets), `DomainSet` governs which code modules are compiled into the runtime and exposed via the internal RPC system.

Within [`builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/builder.rs), the struct provides static preset constructors that hardcode specific family combinations. These presets ensure that embedding scenarios receive only required dependencies while full desktop builds retain all product features.

## DomainSet::full() – The Complete Runtime

`DomainSet::full()` represents the default **"all families"** configuration used by the shipped OpenHuman desktop application. When instantiated, this preset registers every available domain family:

- **`agent`** – Core turn orchestration and harness logic
- **`memory`** – Vector DB and persistent document stores
- **`threads`** – Conversational threading models
- **`config`** – User-scoped configuration handling
- **`security`** – Policy gates, key-rings, and approval workflows
- **`flows`** – Visual flow execution engines
- **`skills`** – Skill registry and tool dispatch
- **`web3`**, **`media`**, **`channels`**, **`mcp`**, **`voice`** – Product-specific integrations

In **[`src/tui/runner.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/tui/runner.rs)**, the desktop TUI process invokes `DomainSet::full()` to ensure all RPC controllers (such as `openhuman.flows_*` or `openhuman.web3_*`) are available to the user interface. Attempting to access any family method with this preset returns the expected controller; no "unknown method" errors occur for product features.

## DomainSet::harness() – The Minimal Embedding Preset

`DomainSet::harness()` provides a **lean, library-optimized** preset documented in **[`src/embed/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/embed/mod.rs)**. This configuration intentionally excludes all product-only families to minimize binary size and dependency trees.

**Included families:**
- `agent`
- `memory`
- `threads`
- `config`
- `security`

**Excluded families:**
- `flows`, `skills`, `web3`, `media`, `channels`, `mcp`, `voice`

When building a core with `DomainSet::harness()`, any RPC call targeting an excluded family (e.g., `openhuman.flows_run`) returns an **"unknown method"** error because the controller was never registered. This behavior is deliberate—it creates a capability boundary that prevents embedded instances from accessing desktop-only tools like cryptocurrency wallets or media pipelines.

## Key Differences at a Glance

| Characteristic | `DomainSet::full()` | `DomainSet::harness()` |
|----------------|---------------------|------------------------|
| **Primary Use** | Desktop TUI, full product | Library embeds, server processes |
| **Agent Tools** | All available | Core only (no flows/skills) |
| **Binary Impact** | Larger, more dependencies | Smaller, faster initialization |
| **RPC Availability** | All methods exposed | Limited to agent/memory/security |
| **Source Location** | [`src/tui/runner.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/tui/runner.rs) | [`src/embed/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/embed/mod.rs) |

## Practical Implementation Examples

The following patterns from **[`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs)** demonstrate how each preset configures the `CoreBuilder`:

```rust
// Full desktop stack - all families enabled
let core_full = openhuman_core::CoreBuilder::new()
    .domains(openhuman_core::DomainSet::full())
    .services(openhuman_core::ServiceSet::desktop())
    .build()
    .await?;

```

In this configuration, the runtime registers controllers for every domain, allowing the agent to invoke web3 tools, execute flows, and manage media channels.

```rust
// Lightweight harness - core families only
let harness = openhuman_core::CoreBuilder::new()
    .domains(openhuman_core::DomainSet::harness())
    .services(openhuman_core::ServiceSet::none())
    .build()
    .await?;

```

This embeddable core excludes all product families. While the agent retains memory persistence and security policy enforcement (as verified in **[`src/openhuman/tools/ops_tests_part_04_tests.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops_tests_part_04_tests.rs)**), attempts to trigger flow automation or voice processing will fail with an RPC routing error.

## Architectural Implications

Beyond feature availability, the choice between these presets affects three critical runtime characteristics:

**Binary Size and Startup Cost**
`DomainSet::harness()` eliminates the code, assets, and native dependencies associated with excluded families. This reduction is essential when embedding OpenHuman into CLI tools or constrained serverless environments where cold-start latency matters.

**Capability Safety**
In **[`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs)**, tool visibility is gated by both the active `DomainSet` and the `ToolGroup` axis. Because `harness()` excludes entire family controllers, it provides a hardware-level guarantee that embedded instances cannot accidentally invoke a cryptocurrency transaction or external media sink, even if the agent's prompt requests it.

**Testability**
The test suite in **[`ops_tests_part_04_tests.rs`](https://github.com/tinyhumansai/openhuman/blob/main/ops_tests_part_04_tests.rs)** explicitly validates that `DomainSet::harness()` retains essential capabilities (agent reasoning, memory retrieval) while correctly omitting product-specific tool groups. This ensures library consumers receive a predictable, minimal API surface.

## Summary

- **`DomainSet::full()`** enables every domain family (agent, memory, flows, web3, voice, etc.) and is used for the complete desktop TUI experience.
- **`DomainSet::harness()`** restricts the runtime to core families—agent, memory, threads, config, and security—excluding product-only features.
- Preset selection impacts binary size, startup speed, and RPC method availability.
- Definitions reside in **[`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs)**, with usage examples in **[`src/tui/runner.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/tui/runner.rs)** (full) and **[`src/embed/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/embed/mod.rs)** (harness).
- Tool filtering logic in **[`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs)** enforces capability boundaries based on the active preset.

## Frequently Asked Questions

### What happens if I call a flows method using DomainSet::harness()?

The RPC system will return an "unknown method" error. Because `DomainSet::harness()` excludes the `flows` family from registration in **[`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs)**, no controller exists to handle the request. This is the intended behavior for library embeddings that should not access desktop automation features.

### Can I switch presets after building the Core?

No. The `DomainSet` is immutable once the `CoreBuilder` completes initialization in **[`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs)**. Domain families are registered at startup to optimize memory layout and dependency injection. To change capabilities, you must instantiate a new Core with the alternative preset.

### Is DomainSet::harness() the same as DomainSet::none()?

No. `DomainSet::none()` (if available) would register zero families, whereas `harness()` explicitly includes the five core families required for autonomous agent operation: agent, memory, threads, config, and security. As confirmed by **[`ops_tests_part_04_tests.rs`](https://github.com/tinyhumansai/openhuman/blob/main/ops_tests_part_04_tests.rs)**, harness retains critical tool capabilities that `none` would remove.

### How does this interact with ToolGroup filtering?

ToolGroup filtering operates within the constraints of the active DomainSet. In **[`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs)**, the runtime first checks if a tool's domain family is present (via DomainSet), then applies ToolGroup permissions. A `harness()` core cannot access a tool even if its ToolGroup allows it, because the underlying family controller was never loaded.