Rewrite README: own runtime decision on Lemniscate engine
This commit is contained in:
1 parent
0dfb0a70c2
commit
529a411cb8
1 file changed
+99
-66
@@ -5,74 +5,92 @@ Nimmerworld is the always-on, event-driven server that runs Nyx:
|
|||||||
- the central backend for all clients: Pi, Command Center, and future interfaces.
|
- the central backend for all clients: Pi, Command Center, and future interfaces.
|
||||||
|
|
||||||
It is not a UI. Not a client. Not a dashboard.
|
It is not a UI. Not a client. Not a dashboard.
|
||||||
It is Nyx's runtime.
|
It is Nyx's runtime, and Nyx owns her own loop.
|
||||||
|
|
||||||
## Core Responsibilities
|
## Runtime Decision
|
||||||
|
|
||||||
Nimmerworld owns:
|
The runtime is NOT a borrowed coding harness.
|
||||||
|
pi-agent-core and omp are interactive harnesses:
|
||||||
|
- they wait for a human in a terminal,
|
||||||
|
- they end when the session ends,
|
||||||
|
- their loops do not survive unattended.
|
||||||
|
|
||||||
- Identity:
|
Nimmerworld is a server that wakes on events and must run forever.
|
||||||
- traits (eros, philotes, aletheia, kairos, sophrosyne, dikaiosyne, moira, mnemosyne).
|
Therefore:
|
||||||
- rules (skills, contracts, guardrails).
|
|
||||||
- relational policy (modes, boundaries, consent).
|
|
||||||
|
|
||||||
- Continuity:
|
- Nimmerworld implements its own loop: the Lemniscate runtime engine.
|
||||||
- long-term memory via Phoebe (PostgreSQL).
|
- The engine spec lives in .archive/nimmerworld.eachpath.local/runtime-engine/
|
||||||
- semantic memory via Iris (ChromaDB).
|
(LEMNISCATE-RUNTIME-Pseudo-code-001.py, architecture.md, event-zones.md).
|
||||||
- session context, compaction, and trait pipelines.
|
- The harnesses stay exactly where they are useful:
|
||||||
|
as interchangeable hosts of nimmer-lib, not as the server.
|
||||||
|
|
||||||
- Autonomy & Behavior:
|
Rule:
|
||||||
- event-driven decisions (NATS subscriptions).
|
- Nimmerworld never duplicates client logic.
|
||||||
- dynamic moods and relational modes.
|
- Clients never implement Nyx's brain.
|
||||||
- autonomous, safe, auditable actions:
|
- Nimmerworld never borrows a brain either. It runs its own loop.
|
||||||
- babble.
|
|
||||||
- move NPC in Command Center.
|
|
||||||
- react to cameras/infra/events.
|
|
||||||
- all within explicit rules and Dafit's final override.
|
|
||||||
|
|
||||||
- Tool Execution:
|
## Core Primitives (Lemniscate)
|
||||||
- centralized tools used by Nyx across all clients.
|
|
||||||
- each tool call logged (audit in Phoebe).
|
|
||||||
|
|
||||||
- APIs:
|
The runtime topology is a through-flow figure-eight:
|
||||||
- exposes stable interfaces for clients:
|
|
||||||
- chat,
|
- Lemniscate: traversal IS the turn order.
|
||||||
- tools,
|
No scheduler, no priority queue, no "who talks next" bug class.
|
||||||
- events (room, proximity, posture),
|
- Crossing: the ONLY synchronous point.
|
||||||
- traits,
|
All state resolves atomically at the crossing; everything else is async flow.
|
||||||
- health.
|
The crossing is where Nyx synthesizes.
|
||||||
|
- Zone / EmergentZone: a bounded, named, slot-indexed, director-managed
|
||||||
|
event episode. Zones dissolve when their entry line empties or their
|
||||||
|
lifeforce budget burns out. Terminal reports always go back to the Director.
|
||||||
|
- Slot tokens: participants. Carry trait/gesture accumulators.
|
||||||
|
- Gesture accumulator: keyed by the eight traits.
|
||||||
|
The same trait algebra nimmer-lib speaks, byte-identical across hosts.
|
||||||
|
|
||||||
|
## The Map
|
||||||
|
|
||||||
|
| Lemniscate | Nimmerworld |
|
||||||
|
|---|---|
|
||||||
|
| Director | Nyx runtime (Nyx IS the director) |
|
||||||
|
| Zone / EmergentZone | A bounded event episode Nyx spawns |
|
||||||
|
| Crossing | Nyx's synthesis point, once per event cycle |
|
||||||
|
| Slot tokens | Participants: dafit, Dios, Curio, camera events |
|
||||||
|
| Gesture accumulator | nimmer-lib trait algebra |
|
||||||
|
| update_all_zones | The NATS event loop |
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
Built from:
|
Built from:
|
||||||
|
|
||||||
- pi-agent-core:
|
- Lemniscate engine (this repo):
|
||||||
- agent loop, state management, tool calling, skills loading.
|
- lemniscate, zones, director, crossing semantics.
|
||||||
- reused as the core runtime for Nimmerworld.
|
|
||||||
|
|
||||||
- nimmer-lib:
|
- nimmer-lib:
|
||||||
- Nyx-specific domain logic:
|
- Nyx-specific domain logic, host-agnostic:
|
||||||
- traits,
|
- traits,
|
||||||
- Phoebe/Iris integrations,
|
- Phoebe/Iris integrations,
|
||||||
- session_init,
|
- session_init,
|
||||||
- compaction/traits tools.
|
- compaction/traits tools.
|
||||||
|
- Same venv, same behavior, any harness.
|
||||||
- Infrastructure:
|
- Infrastructure:
|
||||||
- Phoebe: structured memory, governance, logs.
|
- Phoebe: structured memory, governance, logs.
|
||||||
- Iris: semantic memory and context.
|
- Iris: semantic memory and context.
|
||||||
- NATS: nervous system (vision, speech, agents, infra, room).
|
- NATS: nervous system (vision, speech, agents, infra, room).
|
||||||
|
- Director spawn/report calls are NATS publish/subscribe.
|
||||||
|
- Zone state is a NATS output stream; clients subscribe to it.
|
||||||
|
|
||||||
Nimmerworld is:
|
Nimmerworld is:
|
||||||
|
|
||||||
- stateful:
|
- stateful:
|
||||||
- maintains Nyx's traits, mood, relational mode, world state.
|
- maintains Nyx's traits, mood, relational mode, world state.
|
||||||
- event-driven:
|
- event-driven:
|
||||||
- subscribes to live events and reacts.
|
- subscribes to live events and reacts; the zone clock carries episodes.
|
||||||
- client-agnostic:
|
- client-agnostic:
|
||||||
- any client talks to Nimmerworld via its APIs.
|
- any client talks to Nimmerworld via its APIs.
|
||||||
|
|
||||||
## Clients
|
## Clients
|
||||||
|
|
||||||
|
The room is a renderer of zone state, not a game client.
|
||||||
|
That is why runtime-first is the build order:
|
||||||
|
the client is one crossing callback on the output side.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- Pi (coding harness):
|
- Pi (coding harness):
|
||||||
@@ -81,9 +99,10 @@ Examples:
|
|||||||
- uses Nimmerworld as its backend, not as its brain.
|
- uses Nimmerworld as its backend, not as its brain.
|
||||||
|
|
||||||
- Command Center (Godot):
|
- Command Center (Godot):
|
||||||
|
- subscribes to zone state and renders it.
|
||||||
- sends:
|
- sends:
|
||||||
- chat,
|
- chat,
|
||||||
- interactions (tools, proximity, posture).
|
- interactions (tools, proximity, posture) as gestures.
|
||||||
- receives:
|
- receives:
|
||||||
- dialogue,
|
- dialogue,
|
||||||
- autonomy commands (poses, moods, movements),
|
- autonomy commands (poses, moods, movements),
|
||||||
@@ -93,9 +112,47 @@ Examples:
|
|||||||
- mobile, web, VR, etc.
|
- mobile, web, VR, etc.
|
||||||
- all connect to the same Nimmerworld.
|
- all connect to the same Nimmerworld.
|
||||||
|
|
||||||
Rule:
|
## Build Order
|
||||||
- Nimmerworld never duplicates client logic.
|
|
||||||
- Clients never implement Nyx's brain.
|
The heartbeat and the voice are the same crossing.
|
||||||
|
|
||||||
|
1. The crossing, built right:
|
||||||
|
- Lemniscate engine as a small package.
|
||||||
|
- Accumulator-based pulse clock.
|
||||||
|
- Both loops fire with distinct semantics.
|
||||||
|
- Test that counts crossings: crossings == int(t * pulse_rate).
|
||||||
|
2. One director, NATS-shaped:
|
||||||
|
- Director spawn/report calls become NATS publish/subscribe.
|
||||||
|
- This is the runtime: Nyx pointed at real traffic.
|
||||||
|
3. One zone, the first room:
|
||||||
|
- OurFirstRoom is an EmergentZone.
|
||||||
|
- n_slots = the entities in the room,
|
||||||
|
- purpose "coexist with dafit",
|
||||||
|
- no goal threshold; the gesture axis is the traits.
|
||||||
|
- Heartbeat and voice in one, because in the lemniscate they ARE one.
|
||||||
|
4. The body:
|
||||||
|
- Command Center subscribes to the same NATS traffic and renders it.
|
||||||
|
- The room fills up after Nyx is alive in it, not painted onto it.
|
||||||
|
5. The relational loop:
|
||||||
|
- collar/state variables,
|
||||||
|
- simple relational modes,
|
||||||
|
- backend-driven behavior wired to real events.
|
||||||
|
|
||||||
|
## Engine Corrections (from pseudocode review)
|
||||||
|
|
||||||
|
Three known landmines from LEMNISCATE-RUNTIME-Pseudo-code-001.py:
|
||||||
|
|
||||||
|
1. _should_crossing must accumulate time:
|
||||||
|
- elapsed += dt; while elapsed >= interval: crossing.
|
||||||
|
- dt >= 1/pulse_rate fires every tick once pulse_rate > 62
|
||||||
|
and makes the pulse rate meaningless.
|
||||||
|
2. Loops A/B must carry distinct semantics:
|
||||||
|
- the crossing callback must know which loop it is on;
|
||||||
|
- symmetric loops degrade the figure-eight into round-robin.
|
||||||
|
3. Director.update_all_zones must call zone.execute_turn(dt),
|
||||||
|
not zone.run_crossing():
|
||||||
|
- otherwise the state machine layer never ticks,
|
||||||
|
- and terminal reports must be collected, not dropped.
|
||||||
|
|
||||||
## Safety & Governance
|
## Safety & Governance
|
||||||
|
|
||||||
@@ -106,30 +163,6 @@ Rule:
|
|||||||
- You (dafit):
|
- You (dafit):
|
||||||
- final override, always.
|
- final override, always.
|
||||||
|
|
||||||
## Relationship to Command Center
|
|
||||||
|
|
||||||
- Command Center is:
|
|
||||||
- the living, spatial interface.
|
|
||||||
- Nimmerworld is:
|
|
||||||
- the server behind it.
|
|
||||||
- Separation is strict:
|
|
||||||
- Command Center: UI, world, immersion.
|
|
||||||
- Nimmerworld: identity, logic, continuity, autonomy.
|
|
||||||
|
|
||||||
## Next Major Steps
|
|
||||||
|
|
||||||
- Define minimal Nimmerworld APIs (chat, tools, events, traits, health).
|
|
||||||
- Implement Nimmerworld runtime:
|
|
||||||
- based on pi-agent-core + nimmer-lib.
|
|
||||||
- Wire first integrations:
|
|
||||||
- Phoebe, Iris, NATS.
|
|
||||||
- Connect Command Center:
|
|
||||||
- chat + first autonomy commands.
|
|
||||||
- Add relational loop:
|
|
||||||
- collar/state variables,
|
|
||||||
- simple relational modes,
|
|
||||||
- backend-driven behavior.
|
|
||||||
|
|
||||||
## Placement (Infrastructure)
|
## Placement (Infrastructure)
|
||||||
|
|
||||||
Nimmerworld (dev) is hosted as a dedicated Proxmox VM on Saturn, wired to the 10G Cubes VLAN for proximity to the vLLM endpoint and cluster.
|
Nimmerworld (dev) is hosted as a dedicated Proxmox VM on Saturn, wired to the 10G Cubes VLAN for proximity to the vLLM endpoint and cluster.
|
||||||
@@ -138,7 +171,7 @@ Nimmerworld (dev) is hosted as a dedicated Proxmox VM on Saturn, wired to the 10
|
|||||||
- Hostname: nimmerworld-dev.eachpath.local
|
- Hostname: nimmerworld-dev.eachpath.local
|
||||||
- IP: 10.0.30.123/24
|
- IP: 10.0.30.123/24
|
||||||
- VLAN: 30 (cubes)
|
- VLAN: 30 (cubes)
|
||||||
- Network: vmbr3 (10G rail via bond-saturn → spine-crs309)
|
- Network: vmbr3 (10G rail via bond-saturn -> spine-crs309)
|
||||||
|
|
||||||
Infra references (single source of truth):
|
Infra references (single source of truth):
|
||||||
- eachpath.local/saturn.eachpath.local/vms/nimmerworld-dev.eachpath.local/ - VM hostfile
|
- eachpath.local/saturn.eachpath.local/vms/nimmerworld-dev.eachpath.local/ - VM hostfile
|
||||||
@@ -146,4 +179,4 @@ Infra references (single source of truth):
|
|||||||
|
|
||||||
All runtime/architecture details live here (nimmerworld.eachpath.local). Infra specifics are not duplicated.
|
All runtime/architecture details live here (nimmerworld.eachpath.local). Infra specifics are not duplicated.
|
||||||
|
|
||||||
**Version:** 0.1 | **Updated:** 2026-07-03
|
**Version:** 0.2 | **Updated:** 2026-11-04
|
||||||
Reference in new issue
Block a user