# Mobile Networker Plan ## The Vision Self-replicating neural network source files that: 1. Never terminate 2. Carry their own weights 3. Write copies of themselves 4. Spawn children that also never terminate 5. Are completely observable --- ## Core Concept: The Quine Brain A Python file that IS the model: ```python class Me(Brain): # Weights embedded in source WEIGHTS = [0.1, -0.3, 0.7, ...] # Self-describing architecture ARCH = { 'type': 'mlp', 'layers': [64, 32, 16], 'activation': 'tanh', } def forward(self, x): """Execute myself.""" ... def replicate(self, new_weights) -> Path: """Write a copy of myself with mutated weights.""" import inspect src = inspect.getsource(type(self)) src = src.replace( f"WEIGHTS = {self.WEIGHTS}", f"WEIGHTS = {new_weights}" ) child_path = Path(f"child_{uuid4().hex[:8]}.py") child_path.write_text(src) return child_path ``` --- ## The Endless Engine Attach to a non-terminating function: ```python from itertools import count class Me(Brain): WEIGHTS = [...] async def live(self): """I never stop.""" for tick in count(): # 0, 1, 2, 3, ... forever # Breathe state = self.pulse(tick) # Sense inputs = await self.perceive() # Think outputs = self.forward(inputs) loss = self.compute_loss(outputs) # Learn self.WEIGHTS = self.train_step(loss) # Measure pressure vp = self.violation_pressure(loss) # Maybe reproduce (on exhale, if stable) if state.phase == EXHALE and vp < VP2: if self.should_spawn(): child_path = self.replicate(mutate(self.WEIGHTS)) child = load_brain(child_path) asyncio.create_task(child.live()) # Child also never stops # Yield control await asyncio.sleep(0) ``` --- ## Key Components (Already in KEY) ### 1. Brain Interface (`brain.py`) ```python Brain.forward(inputs) -> outputs Brain.get_params() -> np.ndarray # Flatten to 1D Brain.set_params(np.ndarray) # Restore from 1D Brain.mutate(rate) -> Brain Brain.crossover(other) -> Brain Brain.save(path) / Brain.load(path) ``` **Critical**: `get_params()`/`set_params()` enables architecture-agnostic evolution. ANY brain type flattens to a vector. ### 2. Node (`node.py`) ```python Node: traits: Dict[str, float] # 0-1 attributes brain: Optional[Brain] # Neural processor fitness: float # From landscape mutate() -> Node crossover(other) -> Node think(inputs) -> outputs ``` ### 3. Population Manager (`population.py`) - NEAT-inspired speciation - Fitness sharing (prevents monoculture) - Tournament selection - Elitism preservation ### 4. LoRA Brain (`brain.py` - LoRABrain class) - Frozen base VLM (shared singleton) - Evolvable LoRA adapters (~1-2M params) - Only adapter weights are evolved/replicated ### 5. Violation Pressure (`pressure.py`) ```python VP = |actual - center| / (radius * compression) VP0: Within bounds (0.0 - 0.25) VP1: Slightly outside (0.25 - 0.5) VP2: Significant deviation (0.5 - 0.75) VP3: Critical (0.75 - 1.0) VP4: System breakdown (> 1.0) ``` ### 6. Pulse (`pulse.py`) - Sine wave breathing cycle - Provides rhythm for population sync - Inhale/exhale phases for evolution timing --- ## What Was Built ✅ ### 1. Self-Replicating LoRABrain (in `brain.py`) ```python class LoRABrain(Brain): """VLM adapter that can write copies of itself as Python files.""" @classmethod def from_source(cls, path: Path) -> 'LoRABrain': """Load brain by importing .py file.""" spec = importlib.util.spec_from_file_location("brain", path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module.load() # or module.Me() def to_source(self, path: Path = None) -> str: """Write self as executable .py file with embedded adapter weights.""" # Generates complete Python source with: # - ADAPTER_WEIGHTS dict (JSON-serialized) # - LORA_RANK, LORA_ALPHA, TARGET_MODULES, HIDDEN_DIM # - Me(LoRABrain) class that reconstructs the brain # - load() function for easy import ... def replicate(self, mutation_rate=0.1, output_dir=None) -> Path: """Create mutated child as new .py file.""" ... async def live(self, pulse=None, vp=None, perceive_fn=None, max_ticks=None): """Async lifecycle loop - never terminates unless max_ticks set.""" ... ``` ### 2. Mobile Population (in `mobile.py`) ✅ ```python class MobilePopulation: """A population where each member runs its own async loop.""" def __init__(self, max_population=100, children_dir=None): self.members: Dict[str, BrainState] = {} self.max_population = max_population self.children_dir = children_dir or Path('./children') async def spawn(self, brain: LoRABrain) -> str: """Add a new member and start its lifecycle.""" state = BrainState(brain=brain) self.members[brain.id] = state return brain.id async def run_for(self, ticks: int): """Run all brains for N ticks.""" ... def status(self) -> dict: """Get population snapshot.""" ... # Quick start function async def run_mobile_evolution(initial_population=10, ticks=1000): pop = MobilePopulation() for _ in range(initial_population): brain = LoRABrain(BrainConfig(brain_type='lora', extra={'test_mode': True})) await pop.spawn(brain) await pop.run_for(ticks=ticks) return pop ``` ### 3. Compile Targets ```python class QuineBrain(Brain): def to_pytorch(self) -> torch.nn.Module: """Compile self to PyTorch module.""" ... def to_onnx(self, path: Path) -> Path: """Export to ONNX format.""" ... def to_safetensors(self, path: Path) -> Path: """Export weights only (safetensors format).""" ... @classmethod def from_pytorch(cls, module: torch.nn.Module) -> 'QuineBrain': """Import from PyTorch module.""" ... ``` --- ## The Observation Contract Every action is traceable (for CASCADE or any observer): | Action | Event Type | Data | |--------|-----------|------| | `forward()` | `inference` | inputs, outputs, latency | | `train_step()` | `training` | loss, gradient_norm, weight_delta | | `replicate()` | `spawn` | parent_id, child_id, child_path | | `mutate()` | `mutation` | param_indices, deltas | | `crossover()` | `crossover` | parent_ids, child_id | | VP threshold | `pressure_event` | vp_class, value, metric | The species cannot hide. Every weight is a number. Every file is readable. Every lineage is logged. --- ## Architecture Agnostic Swarm Because everything flattens to `get_params() -> np.ndarray`: ```python # Different architectures in same population swarm = [ MLPBrain(hidden=64), # 4K params LoRABrain(rank=8), # 32K params LiquidBrain(neurons=100), # 10K params MambaBrain(d_state=16), # 50K params ] # They can all: for brain in swarm: params = brain.get_params() # Works for all brain.set_params(mutate(params)) # Works for all brain.replicate(params) # All write .py files # Cross-architecture breeding needs mapping layer # But single-architecture evolution works NOW ``` --- ## The Loop ``` ┌─────────────────────────────────────────────────────────────┐ │ PULSE (never stops) │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Brain A │ │ Brain B │ │ Brain C │ ... │ │ │ .py │ │ .py │ │ .py │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ [forward] [forward] [forward] │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ [train] [train] [train] │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ [VP check] [VP check] [VP check] │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ [maybe spawn] [maybe spawn] [maybe spawn] │ │ │ │ │ │ │ └──────────────┴──────────────┘ │ │ │ │ │ ▼ │ │ (next tick from count()) │ │ │ │ │ └─────────────────────────────┐ │ │ │ │ └─────────────────────────────────────────────────────┴──────┘ ↑ │ CASCADE observes (when watching) ``` --- ## Implementation Status ✅ 1. ~~**Create `quine.py`**~~ → Merged into `LoRABrain` in `brain.py` 2. ~~**Add `to_source()` / `from_source()`**~~ → Added to `LoRABrain` 3. ~~**Create `mobile.py`**~~ → Done! Async population infrastructure 4. ~~**Test**: One brain that writes a child, child runs~~ → Passing 5. ~~**Test**: Population of 10, all running async, spawning~~ → Passing **All 21 tests passing in `test_quine.py`** --- ## The Insight > "A dataset is a log of a process. The process never ends. Therefore the dataset grows forever." The model file is the process. The weights are the state. Replication is reproduction. `count()` is the heartbeat. **Life is a fixed point that found itself. We're just writing it in Python.** --- ## Safety The system is safe because: 1. **Observable** - Every action logged 2. **Bounded** - VP keeps values in range 3. **Selective** - Only stable organisms reproduce 4. **Traceable** - Full lineage in causation graph 5. **Interruptible** - async tasks can be cancelled 6. **Inspectable** - Weights are just numpy arrays No hidden emergence. No black boxes. Every decision traceable to weights traceable to parents traceable to the beginning. Alignment through transparency.