6.7 KiB
Register
Central registry: sensors, gates, actuators, clients, and the links between them. Runtime decisions validate against it. Register changes are governed impulses.
Subject registry (subjects are register data, not code)
The register holds the subject map; code and tools derive their wire
names from it. The naming convention itself is registry data: flipping
it is a single switch, no engine change, and the switch itself carries
event_uuid + why (auditable v7 causality).
# subject registry (register holds it, code consumes it)
subjects:
version: 1
prefix: "nimmerverse." # <- the naming convention, one switch
map:
gate.summary: "nimmerverse.gate.summary" # core NATS, ephemeral
gate.decision: "nimmerverse.gate.decision" # core NATS, ephemeral
action.call: "nimmerverse.action.call.{}" # JetStream, per <target>
action.result: "nimmerverse.action.result" # JetStream, durable
zone.state: "nimmerverse.zone.state.>" # JetStream, clients replay-on-wake
Rules:
- Publishers and consumers derive subject strings from the registry at startup. No component hard-codes a wire subject.
- Validation once, before fan-out: an unmapped subject fails loud at startup (same pattern as class-path validation).
- Growth by declaration: new sensor/actuator/client/tool = register row
- mapped subject; the engine is untouched.
- JetStream streams are created manually or script-gated; the register refuses subjects that no backing stream exists for.
Registry scope
| Question | Registry |
|---|---|
| What sensors exist and what may they emit? | sensor registry |
| What gates exist and what are they? | gate_registry (tier, why, mode_overrides) |
| What may be emitted out? | actuator registry (animation catalog, output channels) |
| What links exist? | gate links (drives) |
| Who is listening? | client registry |
| What subjects exist and who may use them? | subject registry (see Subject registry section) |
The register is a gate layer one level up: sensors, gates and clients are admitted by declaration.
drives links
Input gates link to output gates an answer may target:
room.cam T3 drives: body.anim (sofa: T1)
dafit.chat T1 drives: body.anim, clients.chat
fire.alarm T0 drives: body.alert
Rules:
- Link visibility at L1: summary carries the link column; attention sees consequences before opening.
- Choice-list at L2: evidence return carries content plus valid output gate catalog. Answer target must be in union of opened gates'
drives. - Membership validation: valid = output gate in
drives; invalid = decision rejected, cycle re-runs. Table lookup, not judgment. - No orphan decisions: input opened with no route, or answer with no causal input, is a representation error.
Effect-side arbitration
Cycle is the transaction boundary. Two policies:
| Policy | Example | Enforcement |
|---|---|---|
| mutex | body.anim: exclusive | one effect per actuator per cycle; second call = override or queue, never both |
| priority | T0 safety > T1 reflex > T2 deliberate | higher tier supersedes; superseded reason logged |
Resolution:
- cycle closes;
- action set resolved (mutex/priority);
- surviving actions validated against
drives; - effects fire in one order, atomically, at the crossing;
- cycle closes with a complete effect record.
Open policy decisions:
- per-cycle action cap;
- supersede vs queue default;
- whether T0 safety can interrupt in-flight animation.
Debug workflows and skill store
drives may fan out:
host.keep T2 drives: host.prom, clients.status
host.keep -> host.promis a hypothesis: ping down -> metrics explain why.- A probe may sit behind a workflow: a registered state machine or debug command with parameters, answering on its own channel. Registered, tiered, why-stated, UUID-traced, reviewable.
Skill store:
- register change events teach attention in real time; summary carries what each gate's
drivescan answer. - gesture accumulator + decision UUIDs make probe effectiveness queryable.
- self-improvement is legible register change (tier shifts, link changes, new workflows), signed and reviewable.
Governance:
- diagnostics (read-only probes) run on the cycle's authority.
- remedial workflows carry the registered tier and sign.
Pod spawning and escalation ladder
Spawn is an async probe with two transactions:
- Run 1 (spawn): decision calls
pod.spawn, validated againstdrives. Action result carries spawn feedback gate link (spawn_uuid), registered at spawn time. Spawn is a register change: event_uuid + why. - Run 2 (result): pod result requested against feedback link; answer lands in next summary as impulse.
- Silence must be manufactured: absence cannot be inferred. Deadline emits a timeout impulse (event_uuid, tiered) at budget edge; escalation flag rides a real signal.
Escalation:
- ladder bounded and signed;
escalate: T2->T1is registered workflow step. - importance declared, never inferred; attention never raises tiers itself.
- ladder terminates outside runtime: at T0 the last step is escalation to operator via
clients.chat. - silence escalates inspection, never arbitration.
- escalations logged with UUIDs and superseded reasons.
Late results and orphan rule
When a tool answer arrives after its cycle closed:
- verification checks causal UUIDs; missing decision cycle = orphan = rejected.
- rejection is visible: it is an impulse into next summary.
- rejection is not silent execution: tool execution may have happened; result is discarded or re-registered by the next decision. Ingress drops results; decision stays with the runtime.
- late/orphan truth carries extra priority tier for inspection, not arbitration.
Invariant: lossless accumulation; rejection is an impulse; attention stays informed.
Consistency mechanism
- register state in Phoebe (truth), materialized in runtime RAM (validator copy), pushed as change events on NATS.
- register changes are impulses: event_uuid at creation, decision_uuid, why string; replayable v7 causality.
- registry tier-locked T0/T1: signed by operator and immutable at runtime. Runtime observes and proposes; operator signs.
Placement
- stateful = VM 123 worldserver: gate table in Phoebe, register materialized in RAM, pulse.
- broker = VM 122 nats-dev: isolated, cubes VLAN, client port 30000.
- ephemeral = k8s pods: daemons, python tools, probe workflows, spawned pods.
- no canonical state in a pod: gate state, register copy, impulse buffers live in Phoebe/123.
Control chain
operator signature
-> register (law)
-> gate state (memory)
-> attention policy (L1/L2)
-> action call (actuator)
-> body/client
No component can rewrite the layer above it.
Version: 0.6 | Updated: 2026-11-06