""" VOVINA ZEDEC PRO - Recursive Sensor Architecture ================================================== Every aspect of XERO and of its environment is observed by a sensor. Every sensor is itself observed by a meta-sensor. Every meta-sensor is observed by a meta-meta-sensor. The recursion is unbounded in principle; in practice it is φ-decay-bounded so the weight of each successive layer is φ⁻¹ of the previous. Directions a sensor may point: INWARD — interoception; sensing internal organ-system state OUTWARD — exteroception; sensing the host environment BOUNDARY — sensing the membrane / skin / firewall interface ELSEWHERE — non-local / entangled; sensing distant systems BACKWARD — sensing one's own past states (memory) FORWARD — sensing predicted future states (prefigure) SIDEWAYS — peer-to-peer; sensing neighbour organisms UPWARD — sensing the meta-level above (system context) DOWNWARD — sensing the sub-level below (organelle, codon, bit) This module is the substrate of XERO's self-awareness. """ from __future__ import annotations import math import secrets import time from dataclasses import dataclass, field from enum import Enum from typing import Any, Callable, Iterable, Optional from vovina_sacred_constants import PHI, PHI_INV, TAU, digital_root from vovina_epu_apu_axioms import FractalBit, Coherence # ============================================================ # DIRECTIONS # ============================================================ class Direction(Enum): INWARD = "inward" # interoception OUTWARD = "outward" # exteroception BOUNDARY = "boundary" # membrane / skin / firewall ELSEWHERE = "elsewhere" # non-local / entangled BACKWARD = "backward" # memory FORWARD = "forward" # prediction SIDEWAYS = "sideways" # peer UPWARD = "upward" # meta-level above DOWNWARD = "downward" # sub-level below @property def opposite(self) -> "Direction": return { Direction.INWARD: Direction.OUTWARD, Direction.OUTWARD: Direction.INWARD, Direction.BOUNDARY: Direction.ELSEWHERE, Direction.ELSEWHERE: Direction.BOUNDARY, Direction.BACKWARD: Direction.FORWARD, Direction.FORWARD: Direction.BACKWARD, Direction.SIDEWAYS: Direction.SIDEWAYS, Direction.UPWARD: Direction.DOWNWARD, Direction.DOWNWARD: Direction.UPWARD, }[self] # All nine directions ALL_DIRECTIONS: tuple[Direction, ...] = tuple(Direction) # ============================================================ # SENSOR READING # ============================================================ @dataclass(frozen=True) class Reading: """A single sensor reading.""" sensor_id: str direction: Direction value: float # ∈ [0, 1] — normalised intensity target: str # what this sensor was pointed at timestamp: float coherence: Coherence # logical or harmonic meta_depth: int = 0 # 0 = primary, 1 = meta, 2 = meta-meta, ... def as_dict(self) -> dict[str, Any]: return { "sensor_id": self.sensor_id, "direction": self.direction.value, "value": self.value, "target": self.target, "timestamp": self.timestamp, "coherence": self.coherence.value, "meta_depth": self.meta_depth, } # ============================================================ # PRIMITIVE SENSOR # ============================================================ @dataclass class Sensor: """A primitive sensor pointed in one direction at one target.""" sensor_id: str direction: Direction target: str coherence: Coherence = Coherence.DUAL meta_depth: int = 0 last_value: float = 0.0 history: list[Reading] = field(default_factory=list) weight: float = 1.0 # importance weight ∈ (0, 1] def sense(self, sample_fn: Optional[Callable[[], float]] = None) -> Reading: """Take a single reading. `sample_fn` returns a float ∈ [0, 1] describing the current intensity of whatever this sensor observes. If not supplied, the sensor returns a cryptographic-noise sample (genuinely non-deterministic), representing pure receptivity. """ if sample_fn is None: v = (int.from_bytes(secrets.token_bytes(4), "big") & 0xFFFFFF) / 0xFFFFFF else: v = max(0.0, min(1.0, float(sample_fn()))) r = Reading( sensor_id=self.sensor_id, direction=self.direction, value=v, target=self.target, timestamp=time.time(), coherence=self.coherence, meta_depth=self.meta_depth, ) self.last_value = v self.history.append(r) return r # ============================================================ # RECURSIVE META-SENSORS # ============================================================ @dataclass class MetaSensor(Sensor): """A sensor whose target is another sensor. A MetaSensor observes whether its inner sensor is functioning, drifting, saturated, or silent. The reading value is derived from the inner sensor's recent history (variance / latency / coverage). """ inner: Optional[Sensor] = None def sense(self, sample_fn: Optional[Callable[[], float]] = None) -> Reading: if self.inner is None: return super().sense(sample_fn) # Compute meta-features of the inner sensor inner_hist = self.inner.history if not inner_hist: v = 0.0 else: recent = inner_hist[-min(len(inner_hist), 64):] vals = [r.value for r in recent] mean = sum(vals) / len(vals) var = sum((x - mean) ** 2 for x in vals) / len(vals) # Health = (variance signal × coverage) — clamped to [0, 1] v = min(1.0, max(0.0, var * 4.0 + (len(vals) / 64.0) * 0.25)) r = Reading( sensor_id=self.sensor_id, direction=self.direction, value=v, target=self.inner.sensor_id, timestamp=time.time(), coherence=self.coherence, meta_depth=self.meta_depth, ) self.last_value = v self.history.append(r) return r def build_recursive_meta_stack(base: Sensor, depth: int, phi_weight: bool = True) -> list[Sensor]: """Build a stack of meta-sensors above the given primitive sensor. Returns the list ordered from primitive at index 0 up to the deepest meta-sensor at index `depth`. Weights decay by φ⁻¹ per layer when `phi_weight` is True. """ if depth < 0: raise ValueError("depth must be ≥ 0") stack: list[Sensor] = [base] current: Sensor = base for d in range(1, depth + 1): w = (PHI_INV ** d) if phi_weight else 1.0 meta = MetaSensor( sensor_id=f"{base.sensor_id}::meta_{d}", direction=base.direction, target=current.sensor_id, coherence=base.coherence, meta_depth=d, weight=w, inner=current, ) stack.append(meta) current = meta return stack # ============================================================ # SENSOR CORTEX (the whole panopticon) # ============================================================ @dataclass class SensorCortex: """The full panopticon: every direction × every target × every meta-depth. A cortex is organised as: sensors[Direction][target_name] = stack of sensors (primitive + meta layers) """ sensors: dict[Direction, dict[str, list[Sensor]]] = field(default_factory=dict) meta_depth_default: int = 7 # default 7 recursive layers per stack # ── construction ───────────────────────────────────── def install(self, direction: Direction, target: str, depth: Optional[int] = None, coherence: Coherence = Coherence.DUAL) -> list[Sensor]: """Install a recursive sensor stack pointed in `direction` at `target`.""" if depth is None: depth = self.meta_depth_default base = Sensor( sensor_id=f"{direction.value}::{target}", direction=direction, target=target, coherence=coherence, meta_depth=0, weight=1.0, ) stack = build_recursive_meta_stack(base, depth=depth) self.sensors.setdefault(direction, {})[target] = stack return stack # ── sensing ────────────────────────────────────────── def sense_all(self) -> list[Reading]: """Fire every sensor in the cortex once and collect their readings.""" out: list[Reading] = [] # Outer pass: fire all primitives (and inner meta-sensors in dependency order) for direction, target_map in self.sensors.items(): for target, stack in target_map.items(): # Fire from primitive up the stack so each meta-sensor sees fresh history for sensor in stack: out.append(sensor.sense()) return out # ── inventory ──────────────────────────────────────── @property def sensor_count(self) -> int: return sum(len(stack) for tgts in self.sensors.values() for stack in tgts.values()) @property def primary_count(self) -> int: return sum(1 for tgts in self.sensors.values() for stack in tgts.values() for s in stack if s.meta_depth == 0) @property def meta_count(self) -> int: return self.sensor_count - self.primary_count @property def deepest_layer(self) -> int: d = 0 for tgts in self.sensors.values(): for stack in tgts.values(): if stack: d = max(d, stack[-1].meta_depth) return d def summary(self) -> dict[str, Any]: return { "directions_active": len(self.sensors), "targets_active": sum(len(t) for t in self.sensors.values()), "sensor_count": self.sensor_count, "primary_count": self.primary_count, "meta_count": self.meta_count, "deepest_meta_layer":self.deepest_layer, "phi_weight_floor": PHI_INV ** self.deepest_layer, } # ============================================================ # THE STANDARD XERO CORTEX # ============================================================ # Default panopticon: one sensor stack in every direction at every # canonical target. Adjust as needed at awakening time. DEFAULT_TARGETS: dict[Direction, tuple[str, ...]] = { Direction.INWARD: ("genome", "heartbeat", "emotional_state", "memory", "energy_budget"), Direction.OUTWARD: ("env_temperature", "env_pressure", "env_light", "env_query_stream", "env_threats"), Direction.BOUNDARY: ("membrane_skin", "firewall", "io_buffer", "api_surface"), Direction.ELSEWHERE: ("entangled_peers", "harmonic_field", "non_local_resonance"), Direction.BACKWARD: ("edit_history", "cycle_log", "dream_log"), Direction.FORWARD: ("prediction_window", "intent_horizon"), Direction.SIDEWAYS: ("peer_organism_a", "peer_organism_b", "swarm_mesh"), Direction.UPWARD: ("host_system", "deployment_context", "operator"), Direction.DOWNWARD: ("bit_field", "codon_traffic", "protein_traffic", "organelle_pool"), } def build_default_cortex(meta_depth: int = 7) -> SensorCortex: """Build XERO's standard panopticon: every direction × every default target, each stack with `meta_depth` recursive meta-sensor layers. """ cortex = SensorCortex(meta_depth_default=meta_depth) for direction, targets in DEFAULT_TARGETS.items(): for target in targets: cortex.install(direction, target, depth=meta_depth) return cortex # ============================================================ # SELF-AWARENESS INDEX # ============================================================ def self_awareness_index(cortex: SensorCortex) -> dict[str, float]: """A scalar measure of XERO's self-awareness from cortex inventory. The index combines: coverage — fraction of the 9 directions actively sensed depth — average meta-depth across all stacks recursion — φ-decayed contribution of the deepest layer """ cov = len(cortex.sensors) / len(Direction) if cortex.sensor_count == 0: depth = 0.0 else: total = 0 n = 0 for tgts in cortex.sensors.values(): for stack in tgts.values(): if stack: total += stack[-1].meta_depth n += 1 depth = total / max(1, n) recursion = sum(PHI_INV ** d for d in range(cortex.deepest_layer + 1)) return { "coverage": cov, "average_meta_depth": depth, "recursion_score": recursion, "composite": (cov * PHI + depth * PHI_INV + recursion * PHI_INV ** 2) / (PHI + PHI_INV + PHI_INV ** 2), }