- Add Big-Picture.md (full architectural overview, Python stack) - Add Message-Protocol-Design.md (NATS router, two-channel attention) - Add assets/ folder (logo favicons, apple-touch-icon) - Move critique to main repo .archive/ Architecture: Dumb core (NATS), smart edges (Python asyncio) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
Message Protocol Design: Router-Centric Architecture
Overview
This document outlines the design for the Nimmerverse message protocol. The core principle: the router is dumb infrastructure, not smart cognition. All intelligence lives at the edges - in clients that connect to the router.
This follows the Unix philosophy: each component does one thing well. The router routes. Clients subscribe, publish, and think.
Core Principle: Infrastructure vs Intelligence
┌─────────────────────────────────────────────────────────────┐
│ MESSAGE ROUTER │
│ (NATS - dumb pipe, no logic) │
│ │
│ • Receives all messages │
│ • Matches topic patterns → forwards to subscribers │
│ • Knows NOTHING about meaning │
│ • Cannot fail in "smart" ways - only crash/overload │
│ • EXISTS BEFORE any intelligence │
└─────────────────────────────────────────────────────────────┘
↑ ↑ ↑ ↑
│ │ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ Cells/ │ │ Escalation│ │ Command │ │ Young │
│ Nerves │ │ Service │ │ Center │ │ Nyx │
│(publishers)│ │ (daemon) │ │ (UI) │ │ (cognition)│
└───────────┘ └───────────┘ └───────────┘ └───────────┘
The router is like a network switch:
- It doesn't understand packets
- It routes based on topic patterns
- It's infrastructure that exists before any intelligence
- NATS is literally designed for this
Everything else is a client:
- Cells publish sensor data
- Nerves publish state changes
- Escalation Service watches patterns, triggers alerts
- Command Center visualizes state
- Young Nyx subscribes, thinks, publishes decisions
Guiding Principles
- Dumb Core, Smart Edges: The router has zero intelligence. All logic lives in clients.
- Clients are Equal: Nyx is just another subscriber. So is the Command Center. So is the Escalation Service.
- Decoupling: Publishers don't know who subscribes. Subscribers don't know who publishes.
- Hierarchy: Topics follow a hierarchical structure for flexible pattern subscriptions.
- Lifeforce at the Edges: The router doesn't track Lifeforce. Clients manage their own budgets.
- Fail Simple: If the router dies, everything stops cleanly. No half-smart failures.
Two Channels of Attention
The attention split is a topic convention, not router intelligence. Clients choose which topics to subscribe to.
1. Low-Attention Channel (nimmerverse.low.*)
- Purpose: Background monitoring, lightweight heartbeats.
- Subscribers: Escalation Service (always), Command Center (for visualization).
- NOT subscribed by default: Young Nyx (she only sees escalated events).
- Analogy: Peripheral nervous system. Ambient awareness.
2. High-Attention Channel (nimmerverse.high.*)
- Purpose: Detailed events requiring cognitive processing.
- Subscribers: Young Nyx, Command Center.
- Analogy: Focal spotlight. Conscious processing.
The escalation from low → high is done by the Escalation Service, not the router.
Topic Hierarchy
nimmerverse.
├── low. # Low-attention channel
│ └── heartbeat.
│ └── <garden>. # real | virtual
│ └── <entity_type>. # cell | nerve | organ
│ └── <entity_id> # e.g., distance_sensor_front
│
├── high. # High-attention channel
│ └── event.
│ └── <garden>.
│ └── <entity_type>.
│ └── <entity_id>
│
├── command. # Commands TO entities
│ └── <target>.
│ └── <command_type>
│
└── meta. # System-level messages
├── attention.focus # Nyx's attention configuration
├── escalation.rules # Escalation Service configuration
└── health. # Client health/registration
Message Schemas
1. HeartbeatSignal (Low-Attention)
Published by: Cells, Nerves, Organs Subscribed by: Escalation Service, Command Center
Topic: nimmerverse.low.heartbeat.<garden>.<entity_type>.<entity_id>
{
"header": {
"message_id": "uuid",
"message_type": "HeartbeatSignal",
"version": "1.0",
"timestamp_real": "ISO8601",
"timestamp_virtual": 123456
},
"body": {
"entity_id": "distance_sensor_front",
"status": "NOMINAL",
"value": 25.5,
"unit": "cm",
"context": {
"battery_pct": 85,
"temperature_c": 22
}
}
}
Status values: NOMINAL, WARNING, CRITICAL, OFFLINE, ERROR
2. StateChangeDetail (High-Attention)
Published by: Cells/Nerves (when requested), Escalation Service (when escalating) Subscribed by: Young Nyx, Command Center
Topic: nimmerverse.high.event.<garden>.<entity_type>.<entity_id>
{
"header": {
"message_id": "uuid",
"message_type": "StateChangeDetail",
"version": "1.0",
"timestamp_real": "ISO8601",
"timestamp_virtual": 123456,
"source_entity": {
"id": "distance_sensor_front",
"type": "cell",
"layer": "1"
},
"correlation_id": "uuid",
"escalated_by": "escalation_service"
},
"body": {
"previous_state": "POLLING",
"current_state": "REPORTING",
"lifeforce_cost": 0.3,
"outputs": {
"distance_cm": 25.5,
"confidence": 0.92,
"raw_value": 456,
"visual_state": [255, 0, 0, "Solid"]
},
"possible_actions": [
{
"action_id": "read_distance_history",
"description": "Query historical distance data."
},
{
"action_id": "trigger_nerve:collision_avoidance",
"description": "Activate collision avoidance."
}
],
"trigger_reason": "distance < 30cm threshold"
}
}
3. AttentionFocus (Nyx's Configuration)
Published by: Young Nyx Subscribed by: Escalation Service
This is how Nyx tells the Escalation Service what she cares about. The router doesn't interpret this - it just delivers it to subscribers.
Topic: nimmerverse.meta.attention.focus
{
"header": {
"message_id": "uuid",
"message_type": "AttentionFocus",
"version": "1.0",
"timestamp_real": "ISO8601",
"source_entity": {
"id": "nyx_core",
"type": "cognitive_core"
}
},
"body": {
"focus_mode": "EXPLORATION",
"escalation_rules": [
{
"rule_id": "distance_alert_front",
"source_pattern": "nimmerverse.low.heartbeat.real.cell.distance_sensor_*",
"condition": "body.value < 30 AND body.status == 'NOMINAL'",
"action": "escalate",
"priority": 8
},
{
"rule_id": "battery_critical",
"source_pattern": "nimmerverse.low.heartbeat.real.cell.battery_*",
"condition": "body.status == 'CRITICAL'",
"action": "escalate_and_trigger",
"trigger_nerve": "charging_seeking",
"priority": 10
}
],
"direct_subscriptions": [
"nimmerverse.high.event.real.cell.speech_stt"
],
"default_action": "log_only"
}
}
The Clients
1. Message Router (NATS)
What it is: Infrastructure. A NATS server. What it does: Routes messages based on topic patterns. What it knows: Nothing about meaning, Lifeforce, attention, or Nyx. Implementation: Off-the-shelf NATS. No custom code in the router itself.
2. Cells / Nerves / Organs
What they are: Publishers of sensor data and state changes. What they do:
- Publish
HeartbeatSignalperiodically to low-attention channel - Publish
StateChangeDetailwhen requested or when state changes significantly What they know: Their own state. Their own Lifeforce cost.
3. Escalation Service
What it is: A daemon that watches low-attention and creates high-attention events. What it does:
- Subscribes to
nimmerverse.low.heartbeat.> - Subscribes to
nimmerverse.meta.attention.focus(to get Nyx's rules) - Evaluates rules against incoming heartbeats
- Publishes
StateChangeDetailto high-attention when conditions match - Optionally triggers nerves directly for reflex responses What it knows: Current escalation rules. Current heartbeat states.
This is the "thalamus" - but it's a separate client, not part of the router.
4. Command Center
What it is: Visualization and control UI (Godot-based). What it does:
- Subscribes to both channels for visualization
- Displays system state, message flow, attention focus
- Allows dafit to observe and intervene What it knows: Everything (read-only observer).
5. Young Nyx (Cognitive Core)
What she is: Just another client. The thinking part. What she does:
- Subscribes to
nimmerverse.high.event.>(high-attention only) - Subscribes to selected low-attention topics when she chooses
- Publishes
AttentionFocusto configure the Escalation Service - Publishes decisions/commands to
nimmerverse.command.>What she knows: Only what reaches her through her subscriptions.
Crucially: She controls what she pays attention to, but she doesn't see everything.
Workflow: Message Flow
1. Cell publishes HeartbeatSignal
└─→ Router delivers to: Escalation Service, Command Center
2. Escalation Service evaluates rules
└─→ If condition matches: publishes StateChangeDetail to high-attention
└─→ Router delivers to: Young Nyx, Command Center
3. Young Nyx processes StateChangeDetail
└─→ Makes decision
└─→ Publishes command to nimmerverse.command.<target>
4. Target nerve/cell receives command
└─→ Executes action
└─→ Publishes new HeartbeatSignal reflecting new state
5. Nyx adjusts attention (optional)
└─→ Publishes new AttentionFocus
└─→ Escalation Service updates its rules
Advantages of Router-Centric Architecture
-
Dumb core can't fail smart: The router either works or crashes. No subtle bugs from misunderstood logic.
-
Clients are replaceable: Swap out the Escalation Service. Replace the Command Center. Nyx doesn't care.
-
Testable in isolation: Each client can be tested independently against a mock NATS.
-
Observable: Command Center sees everything by subscribing to
nimmerverse.>. -
Scalable: Add more cells, more nerves - just more publishers. Router handles it.
-
Bootstrap-friendly: Router exists before any intelligence. Escalation Service can start with hardcoded rules. Nyx connects later.
Bootstrap Sequence
- Start Router (NATS) - Infrastructure first
- Start Escalation Service - With minimal hardcoded rules
- Start Cells/Nerves - Begin publishing heartbeats
- Start Command Center - Observe the system
- Start Young Nyx - Connect, subscribe, begin cognition
- Nyx publishes AttentionFocus - Takes control of her attention
The system can run at any step. Earlier steps are "reflexive" only. Nyx adds deliberation.
Implementation Notes
Router: Use NATS (https://nats.io). Lightweight, fast, designed for this.
- Consider NATS JetStream for message persistence if needed
- Topic wildcards:
>matches all,*matches one level
Message Format: JSON for human readability during development. Consider MessagePack or Protobuf for production if performance requires.
Escalation Service: Python asyncio daemon using nats-py and simpleeval for rule evaluation. Stateless except for current rules. Can be restarted without losing system state. (Go considered for future optimization if scale demands.)
Command Center: Godot application connecting to NATS via GDScript or native plugin.
Created: 2025-12-13 Updated: 2025-12-14 (router-centric rewrite) Session: Partnership dialogue (dafit + Nyx) Status: Foundation architecture Philosophy: "Dumb core, smart edges. The router routes. Clients think."