berna-r8 / code /dynamic_birth.py
muhamedkamil's picture
Upload folder using huggingface_hub
d997548 verified
Raw History Blame Contribute Delete
4.86 kB
"""
Dynamic cell birth — logic for creating new cells when new knowledge
patterns emerge during training.
Design:
- A "new pattern" = activation fingerprint that has low similarity
(< threshold) to all patterns currently tracked by any cell.
- When detected: create a new cell that SHARES the neuron range of
a parent cell (logical birth, not physical).
- The new cell gets:
* Fresh DNA (mutated from parent)
* Its own fp_history
* Registered in plexus as a new node
* Recorded in CognitiveLog
"""
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional, Tuple
from cells.saturation import Cell, MAX_CELLS_TOTAL
from cells.dna_kernel import DNA, mutate_dna, random_dna
# Global config
NEW_PATTERN_THRESHOLD = 0.70 # similarity below this = new pattern
MIN_SIMILAR_TO_ANY = 0.75 # if similarity to any cell's signature < this → potential birth
BIRTH_COOLDOWN_STEPS = 100 # min steps between births for the same layer
class BirthRegistry:
"""Tracks births and enforces cooldown."""
def __init__(self):
self.last_birth_step = {} # layer_idx -> step
self.birth_counter = 0
def can_birth(self, layer_idx: int, current_step: int) -> bool:
last = self.last_birth_step.get(layer_idx, -10**9)
return (current_step - last) >= BIRTH_COOLDOWN_STEPS
def mark_birth(self, layer_idx: int, current_step: int):
self.last_birth_step[layer_idx] = current_step
self.birth_counter += 1
def birth_from_pattern(
parent_cell: Cell,
parent_dna: DNA,
new_pattern_sig: str,
step: int,
model_uuid: str = "mother-001",
registry: Optional[BirthRegistry] = None,
) -> Tuple[Cell, DNA]:
"""
Create a new cell from a parent, sharing its neuron range.
Returns:
(new_cell, new_dna)
"""
if registry is not None and not registry.can_birth(parent_cell.layer_idx, step):
return None, None
# Cell ID: extension of parent
child_index = parent_cell.splits + 1
new_id = f"{parent_cell.cell_id}-b{child_index:02d}"
new_cell = Cell(
cell_id=new_id,
layer_idx=parent_cell.layer_idx,
neuron_start=parent_cell.neuron_start,
neuron_end=parent_cell.neuron_end,
state="active",
parent_id=parent_cell.cell_id,
created_at=datetime.now(timezone.utc).isoformat(),
last_updated_step=step,
fp_history=[new_pattern_sig],
pattern_sig=new_pattern_sig,
)
# Mutated DNA from parent
new_dna = mutate_dna(parent_dna, rate=0.03)
new_dna.cell_id = new_id
if registry is not None:
registry.mark_birth(parent_cell.layer_idx, step)
return new_cell, new_dna
def find_birth_candidate(
pattern_sig: str,
cells_in_layer: list,
hamming_similarity_fn,
threshold: float = MIN_SIMILAR_TO_ANY,
) -> Optional[Cell]:
"""
Find a cell whose pattern_sig is closest to the new pattern.
If even the closest is below threshold, return None (no good parent).
Otherwise, return the closest cell as candidate parent.
"""
best = None
best_sim = -1.0
for c in cells_in_layer:
if c.state != "active":
continue
if not c.pattern_sig:
# Cell has no pattern yet — can be parent
return c
sim = hamming_similarity_fn(pattern_sig, c.pattern_sig)
if sim > best_sim:
best_sim = sim
best = c
if best is None:
return None
if best_sim < threshold:
# No cell is close enough — skip birth (pattern too foreign)
return None
return best
if __name__ == "__main__":
# Standalone test
import sys
sys.path.insert(0, "/data/berna-r7/core/code")
from cognitive_log import pattern_signature, hamming_similarity
# Build a fake parent
parent = Cell(cell_id="test-000", layer_idx=0,
neuron_start=0, neuron_end=1536)
parent_dna = random_dna(parent.cell_id, seed=42)
reg = BirthRegistry()
new_cell, new_dna = birth_from_pattern(
parent_cell=parent,
parent_dna=parent_dna,
new_pattern_sig="abcdef0123456789",
step=100,
registry=reg,
)
print(f"Birth OK: {new_cell.cell_id} (parent={new_cell.parent_id})")
print(f"DNA signature: {new_dna.signature[:16]}")
print(f"Births in registry: {reg.birth_counter}")
# Second birth same layer within cooldown → rejected
new_cell2, _ = birth_from_pattern(
parent_cell=parent,
parent_dna=parent_dna,
new_pattern_sig="1234567890abcdef",
step=150, # only 50 steps later
registry=reg,
)
print(f"Cooldown block: {new_cell2 is None}")
# R8 anti-explosion cap (added 12 Oct 2026)
MAX_CELLS_PER_LAYER = 120
# R8 anti-explosion cap