Files
nimmerworld.eachpath.local/architecture/register.md
T

127 lines
5.3 KiB
Markdown

# Register
Central registry: sensors, gates, actuators, clients, and the links between them. Runtime decisions validate against it. Register changes are governed impulses.
## 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 |
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:
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.5 | Updated: 2026-11-04