# Understanding the DomainEvent Taxonomy in OpenHuman's Event Bus

> Explore the DomainEvent taxonomy in OpenHuman's event bus. Discover how ten type-safe variants like Agent, Memory, and System enable decoupled communication and efficient filtering.

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

---

**The DomainEvent taxonomy in OpenHuman categorizes domain-specific events into ten type-safe variants—Agent, Memory, Thread, Tool, Channel, Cron, Skill, Web3, MCP, and System—enabling decoupled communication and efficient filtering across the application's lightweight event bus.**

The `tinyhumansai/openhuman` repository implements a lightweight, type-safe event-bus system that serves as the central nervous system for the application runtime. At the heart of this architecture lies the **DomainEvent taxonomy**, a Rust enum defined in [`src/core/events.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/events.rs) that provides a structured classification for routing domain-specific signals across agent harnesses, memory subsystems, and external integrations.

## What is the DomainEvent Taxonomy?

The **DomainEvent** enum serves as the fundamental classification system for all events traversing the OpenHuman event bus. Defined in [`src/core/events.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/events.rs), this taxonomy organizes events by their originating domain, allowing subscribers to filter and react only to relevant signals without deserializing unrelated data.

The enum comprises ten distinct variants, each representing a specific subsystem:

| Domain | Event Variant | Purpose |
|--------|---------------|---------|
| **Agent** | `Agent` | Events from the agent harness including tool execution, thought generation, and turn completion. |
| **Memory** | `Memory` | Memory subsystem events such as chunk storage, retrieval results, and diff updates. |
| **Thread** | `Thread` | Conversation thread lifecycle events including creation, deletion, and label changes. |
| **Tool** | `Tool` | Tool execution events covering start signals, progress updates, and result publication. |
| **Channel** | `Channel` | Communication layer events including inbound messages, status changes, and webhook callbacks. |
| **Cron** | `Cron` | Scheduled task events for periodic clean-ups, automation triggers, and background job completions. |
| **Skill** | `Skill` | Skills runtime events including workflow start/end and skill-registry updates. |
| **Web3** | `Web3` | Blockchain interaction events such as wallet state changes and X-402 transaction outcomes. |
| **MCP** | `Mcp` | Managed Compute Platform events including server registration and tool-call results. |
| **System** | `System` | Broad system-level signals like shutdown notifications and health-check updates. |

Each variant carries a strongly-typed payload—typically a struct such as `AgentEvent` or `MemoryEvent` defined in the same module—ensuring type safety across the event bus.

## Event Bus Communication Patterns

OpenHuman's event bus supports two primary communication patterns for interacting with the **DomainEvent** taxonomy, implemented in [`src/core/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/bus.rs).

**Fire-and-Forget Publishing**

Use `publish_global` to broadcast events to all subscribers and `subscribe_global` to receive the event stream. This pattern suits logging, monitoring, and side-effect triggers where no response is required.

**Typed Request-Response**

For synchronous interactions requiring a return value, use `register_native_global` to expose request handlers and `request_native_global` to invoke them. This pattern supports RPC-style communication with strongly-typed requests and responses.

## Working with DomainEvents in Rust

The following examples demonstrate practical usage of the DomainEvent taxonomy in application code.

### Publishing Memory Events

To broadcast a memory-related event, wrap the specific payload in the `DomainEvent` enum and invoke the global publisher:

```rust
use openhuman_core::core::events::{DomainEvent, MemoryEvent};
use openhuman_core::core::bus::publish_global;

// Create a specific memory payload
let mem_evt = MemoryEvent::ChunkStored { chunk_id: "c123".into() };

// Wrap in taxonomy enum and broadcast
publish_global(DomainEvent::Memory(mem_evt));

```

### Subscribing to Tool Events

Subscribers can pattern-match on specific **DomainEvent** variants to filter the event stream efficiently:

```rust
use openhuman_core::core::events::{DomainEvent, ToolEvent};
use openhuman_core::core::bus::subscribe_global;

let mut sub = subscribe_global();

// Filter for Tool variant only
while let Some(event) = sub.next() {
    if let DomainEvent::Tool(tool_evt) = event {
        match tool_evt {
            ToolEvent::Started { tool_name } => {
                println!("Tool started: {}", tool_name);
            }
            ToolEvent::Progress { percent } => {
                println!("Progress: {}%", percent);
            }
            _ => {}
        }
    }
}

```

### Request-Response for Cron Jobs

For synchronous job execution, use the typed request API:

```rust
use openhuman_core::core::bus::{request_native_global, NativeResponse};
use openhuman_core::core::events::{DomainEvent, CronEvent};

let request = CronEvent::RunJob { job_id: "backup".into() };
let response: NativeResponse = request_native_global(
    "cron.run_job",
    request,
);
println!("Job result: {:?}", response);

```

## Key Source Files

The following files implement the DomainEvent taxonomy and event bus infrastructure:

| File | Role |
|------|------|
| [`src/core/events.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/events.rs) | Defines the `DomainEvent` enum and domain-specific payload structs like `AgentEvent` and `MemoryEvent`. |
| [`src/core/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/bus.rs) | Implements the global publish/subscribe API including `publish_global` and `subscribe_global`. |
| [`src/core/bus_testing.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/bus_testing.rs) | Provides test utilities and harnesses for verifying event-bus behavior. |
| [`src/core/events_tests.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/events_tests.rs) | Contains unit tests ensuring each domain variant emits and handles correctly. |
| [`src/core/runtime/services.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/services.rs) | Orchestrates domain services that emit events into the bus. |

## Summary

- The **DomainEvent taxonomy** provides ten type-safe variants (`Agent`, `Memory`, `Thread`, `Tool`, `Channel`, `Cron`, `Skill`, `Web3`, `Mcp`, `System`) for categorizing events in [`src/core/events.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/events.rs).
- Each variant encapsulates a domain-specific payload, enabling efficient filtering without deserialization overhead.
- The event bus supports both asynchronous fire-and-forget patterns via `publish_global`/`subscribe_global` and synchronous request-response via `request_native_global`.
- This architecture decouples subsystems while maintaining type safety across the OpenHuman runtime.

## Frequently Asked Questions

### What is the DomainEvent taxonomy used for in OpenHuman?

The **DomainEvent taxonomy** classifies all events flowing through the OpenHuman event bus into ten distinct domains, enabling type-safe routing and filtering. It allows subsystems like the agent harness, memory store, and Web3 integrations to communicate without direct coupling.

### How do I filter specific event types in the OpenHuman event bus?

Subscribe to the global bus using `subscribe_global` from [`src/core/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/bus.rs), then pattern-match on the desired `DomainEvent` variant. This approach avoids the cost of deserializing unrelated events because filtering occurs at the enum level.

### What is the difference between publish_global and request_native_global?

`publish_global` implements fire-and-forget broadcasting where events are emitted without expecting a response, while `request_native_global` implements a typed request-response pattern suitable for RPC-style communication requiring return values.

### Where is the DomainEvent enum defined in the OpenHuman codebase?

The `DomainEvent` enum is defined in [`src/core/events.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/events.rs) within the `tinyhumansai/openhuman` repository, alongside the domain-specific payload structs such as `AgentEvent`, `MemoryEvent`, and `ToolEvent`.