Files

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:

  1. Publishers and consumers derive subject strings from the registry at startup. No component hard-codes a wire subject.
  2. Validation once, before fan-out: an unmapped subject fails loud at startup (same pattern as class-path validation).
  3. Growth by declaration: new sensor/actuator/client/tool = register row
    • mapped subject; the engine is untouched.
  4. 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.

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:

  1. Link visibility at L1: summary carries the link column; attention sees consequences before opening.
  2. Choice-list at L2: evidence return carries content plus valid output gate catalog. Answer target must be in union of opened gates' drives.
  3. Membership validation: valid = output gate in drives; invalid = decision rejected, cycle re-runs. Table lookup, not judgment.
  4. 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:

  1. cycle closes;
  2. action set resolved (mutex/priority);
  3. surviving actions validated against drives;
  4. effects fire in one order, atomically, at the crossing;
  5. 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.prom is 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 drives can 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 against drives. 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->T1 is 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