# The nervous system

One channel. One kind of message. Anything that happens, a schedule coming due, a file changing, a peer reaching in, becomes a `SensorEvent` and goes onto the bus. Everyone listening hears all of it. No one waits on anyone else.

The code is `src/core/nervous/mod.rs`.

## The bus

`EventBus` is a broadcast channel, cloneable, so anything holding the server can subscribe and get its own stream. Two moves: `send` and `subscribe`.

Send is fire-and-forget. If no one is listening, or a listener has fallen behind, the event is simply gone. The bus is a nerve, not a ledger. Anything that must be kept subscribes and writes it down; the event log does exactly that.

The ring holds 256. A listener that falls further behind is told it lagged and skips ahead. Nothing is replayed.

It is a broadcast and not a queue because many things want every event at once: the log, the heartbeat, the firehose, the federation bridge. A new listener, a desktop face, a health monitor, attaches without the sender ever knowing it is there.

## The message

Every event is a `SensorEvent`:

- `sensor_name`: who fired (`cron`, `energy`, `federation`)
- `event_type`: what it is (`schedule_due`, `sensorium:input`, `turn:segment`)
- `timestamp`: when
- `target`: a conversation, a schedule, a room; depends on the type
- `urgency`: 0 to 1, how loudly it asks to be seen
- `payload`: whatever the type needs
- `seed_id`: empty for a local event, a peer's key when it came from elsewhere
- `reply_to`: where a directed reply goes; empty for a broadcast

One type, not an enum per event, so a listener filters on `event_type` and ignores the rest, and the log can write everything down without knowing the taxonomy.

`seed_id` rides on every event though federation isn't here yet. When it lands, a sensor becomes federated without the envelope changing. See [federation/01-seed-and-federation](../federation/01-seed-and-federation.md).

## What pushes

A `SensorConfig` says how a sensor takes part: which domain (`Cron`, `Filesystem`, `FilesystemWatch`, `GitDiff`, `Memory`, `Process`, `Federation`), whether it pushes on its own or waits to be asked, when it fires (once, on change, or on an interval), and how eagerly.

A sensor marked as a nerve ending fires onto the bus uncalled. Right now the schedule is the only one that does. The other domains are named and waiting; nothing drives them yet. Tracked in `docs/tasks/firehose-subconscious-subscription.md`.
