Skip to main content

How Modules Communicate

The corpus callosum connects all brain regions. Modules broadcast “this happened” notifications through typed events on the corpus — no module needs to know who is listening. When something needs a direct request/response (the prefrontal asking the cerebellum for the capability index, or the cortex for search results), that goes through module references injected at startup, not the bus. This keeps the system modular, inspectable, and easy to extend.

Architecture

Built on mitt — a lightweight typed event emitter (200 bytes). Every module receives the corpus singleton in its constructor:
The corpus is initialized first during startup and passed to all other modules. Notifications always ride the bus; the few direct request/response paths are references handed in at startup, never imports between modules.

Usage

The corpus itself installs an internal wildcard handler on construction — every event that flows through it is captured, buffered, and flushed to the daily log files. Modules get logging for free.

Event Categories

Over 80 typed events are defined in the CorpusEvents type map. The main categories:

Message & Context Events

LLM Events

turn.usage is the whole-turn roll-up, with the cache split priced separately so caching wins are measurable straight from the corpus log.

Tool & Task Events

Safety Events

Memory & Learning Events

Health & Index Events

Scheduler Events

Beyond these, whole families cover dependency installation (dependency.*), channels (telegram.*, whatsapp.*), voice and speech (voice.*, stt.*), file uploads (upload.*), and conversation switches (conversation.changed). All follow the same pattern: typed payload, automatic logging.

Event Logging

Every event is logged to daily markdown files at brain/corpus/YYYY-MM-DD.log.md. A 2-second buffer flush batches writes for performance — each event lands as a timestamped block:
Old logs are automatically cleaned after 7 days to prevent unbounded disk growth. That purge is by design — anything worth keeping longer already persists elsewhere (episodes, weekly summaries, run-history.md), and the logs themselves are indexed by the cortex while they exist.
Read the corpus logs when debugging unexpected behavior. They show you the exact sequence of events that occurred — which module did what and when.

Subscribing and Unsubscribing

The turn runner uses this pattern to subscribe to events for the duration of a turn, then unsubscribes in the finally block.

Adding New Events

To add a new event type:
  1. Add the event name and its payload type to the CorpusEvents type map in src/main/runtime/corpus.ts
  2. Emit it from the relevant module
  3. Subscribe to it from any module that needs to react
The event is automatically logged by the wildcard handler — no extra wiring needed.

Design Benefits

The event bus architecture provides:
  • Module independence: modules can be developed, tested, and upgraded independently
  • Full observability: every interaction is logged and timestamped
  • Easy extension: new modules subscribe to existing events without modifying producers
  • Testability: mock the corpus in tests and verify events are emitted correctly

Practical Example: Hypothalamus Health Monitoring

The hypothalamus demonstrates how a module uses corpus to monitor the entire system without importing any other module:
The hypothalamus never touches the thalamus, motor, or prefrontal modules directly. It observes their behavior through events and raises its own events when thresholds are crossed. Any module can then react to health warnings — the UI can show an indicator, the brainstem can trigger a diagnostic job, and the prefrontal can include health context in the next prompt.
Event handlers should be fast and non-blocking. Heavy work triggered by an event should be deferred (setTimeout, queueMicrotask) to avoid slowing down the event producer.