diff --git a/CHANGELOG.md b/CHANGELOG.md index b000c89..c55af79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,30 +9,47 @@ cat -A configure.ac | grep '\^I' nl -ba Makefile | sed -n '770,790p' grep -n "^[ ]" Makefile | head -ok bom, o proximo passo: + +ok, agora esta parte é importante. entao vamos arquitetar e/ou desenhar primeiro. +primeiro vamos actualizar a wiki com as nossas checkboxes vazias: ``` -### 🧬 Telemetria V5 — Expansão Real (em implementação) +## ✔ TRM — Base simbólica definida (roadmap cognitivo fechado) +Pronto para implementação. -#### 🔹 Medidas e Modelos -- [ ] Delta entre ciclos (previsão de tendência) -- [ ] Aceleração do delta (detetar picos súbitos) -- [ ] Temperatura virtual (fadiga cognitiva) -- [ ] FS Health (blocos + erros + modo RO + delta IO) -- [ ] Jitter cognitivo (latência e consistência do ciclo `think()`) +## 🟦 Próximos passos (TRM v1): -#### 🔹 Eventos TeleMétricos -- [ ] `enter_stress_zone` -- [ ] `recovering` -- [ ] `fs_warning` -- [ ] `loop_suspect` -- [ ] `temp_rising_fast` -- [ ] Exportar eventos → Hippocampus (append-only) +### 🔹 1. Micro-agentes +- **Guardião** (homeostase) +- **Explorador** (TRM interno) +- **Arqueólogo** (memória) -#### 🔹 Estados Cognitivos -- [ ] `stable` -- [ ] `warm` -- [ ] `hot` -- [ ] `critical` -- [ ] `recovery` +### 🔹 2. Energia / Custo Cognitivo +- cada iteração do TRM consome energia +- afeta temperatura virtual + +### 🔹 3. Valência interna (agradável/desagradável) +- estados bons aumentam valência +- instabilidades reduzem + +### 🔹 4. Ritmos internos (osciladores) +- `think_rate` +- `memory_sync_rate` +- `telemetry_rate` +- `selfcheck_rate` + +### 🔹 5. Espaço de estados & Atratores +- estável +- quasi-estável +- recuperativo +- caótico ``` -como sugeres que iniciemos o update? \ No newline at end of file +ja actualiza com sugestoes futuras (v2) se quiseres. +afinal de contas estamos a criar a semente onde vai emerjir a nossa AGI quantica 😍😎😁 + +O passo seguinte será: + +TRM.begin_cycle(data) + +TRM.end_cycle(data) + +TRM.depth_control(jitter,temp) \ No newline at end of file diff --git a/src/_nfdos/kernel/neurotron/src/neurotron/cortex.py b/src/_nfdos/kernel/neurotron/src/neurotron/cortex.py index 608a5d1..8978a5b 100644 --- a/src/_nfdos/kernel/neurotron/src/neurotron/cortex.py +++ b/src/_nfdos/kernel/neurotron/src/neurotron/cortex.py @@ -15,6 +15,7 @@ from .hippocampus import Hippocampus from .perception import Perception from .motor import Motor from .autodiagnostic import AutoDiagnostic +from .telemetry import TelemetryV5 # <-- NOVO from .neurotron_config import ( NEUROTRON_MODE, NEUROTRON_TICK, @@ -22,7 +23,6 @@ from .neurotron_config import ( NEUROTRON_DIAG_EVERY_TICKS, NEUROTRON_DATASET_PATH, HEARTBEAT_ENABLED, - NEUROTRON_THRESHOLDS, TELEMETRY_MAXLEN, TELEMETRY_FLUSH_EVERY_TICKS, ) @@ -32,7 +32,6 @@ class Cortex: self.runtime_dir = Path(runtime_dir) self.log_dir = Path(log_dir) - # tick pode vir como string → convertemos sempre try: self.tick = float(tick_seconds) except: @@ -55,13 +54,16 @@ class Cortex: EchoAgent(self), ] + # ---- NOVO: Telemetria V5 ---- + self.tele = TelemetryV5(event_callback=self._telemetry_event) + self._booted = False self.telemetry_path = Path(NEUROTRON_DATASET_PATH) / "telemetry.json" self.telemetry_path.parent.mkdir(parents=True, exist_ok=True) # ---------------------------------------- - # Boot + # boot # ---------------------------------------- def boot(self): if self._booted: @@ -71,7 +73,7 @@ class Cortex: self._booted = True # ---------------------------------------- - # Shutdown + Fatal + # shutdown # ---------------------------------------- def shutdown(self, reason=""): logbus.warn(f"Shutdown pedido — {reason}") @@ -104,7 +106,6 @@ class Cortex: if not action: return - # echo (debug) if action.get("action") == "echo": res = self.motor.run("echo", [action.get("text", "")]) msg = res.get("stdout", "").strip() @@ -112,15 +113,26 @@ class Cortex: logbus.info(f"[echo] {msg}") def rest(self): + # ------- Telemetria V5 ------ + try: + tele = self.tele.step() + self.telemetry.append(tele) + except Exception as e: + logbus.error(f"telemetry_step: {e}") + + # ------- Heartbeat visual ------ if HEARTBEAT_ENABLED: self._heartbeat() + # ------- Tick ------ sleep(self._safe_float(self.tick, fallback=1.0)) self._tick_count += 1 + # ------- Diag ------- if self._tick_count % NEUROTRON_DIAG_EVERY_TICKS == 0: self._run_diag() + # ------- Persistência ------- if self._tick_count % TELEMETRY_FLUSH_EVERY_TICKS == 0: self._flush_telemetry() @@ -135,7 +147,7 @@ class Cortex: return fallback # ---------------------------------------- - # heartbeat + # heartbeat — apenas visual, não cognitivo # ---------------------------------------- def _heartbeat(self): snap = self.perception.snapshot() @@ -145,22 +157,24 @@ class Cortex: load = snap.get("loadavg") load1 = self._safe_float(load[0] if load else 0.0, 0.0) - self.telemetry.append({ - "ts": time.time(), - "cpu": cpu, - "mem": mem, - "load1": load1, - "tick": self.tick, - }) - - # log em modo seguro try: logbus.heart(f"cpu={cpu}% mem={mem}% tick={self.tick:.2f}s") except: logbus.heart(f"cpu={cpu}% mem={mem}% tick={self.tick}") # ---------------------------------------- - # diag / homeostase + # telemetria persistência + # ---------------------------------------- + def _flush_telemetry(self): + try: + data = list(self.telemetry) + self.telemetry_path.write_text(json.dumps(data)) + self.memory.remember("telemetry.flush", {}) + except Exception as e: + logbus.error(f"telemetry_flush: {e}") + + # ---------------------------------------- + # diag + homeostase # ---------------------------------------- def _run_diag(self): state, snap = self.diagnostic.run_exam() @@ -181,20 +195,13 @@ class Cortex: self.tick = max(NEUROTRON_TICK_MIN, old - NEUROTRON_TICK_STEP / 2) if self.tick != old: - try: - logbus.info(f"tick ajustado {old:.2f}s → {self.tick:.2f}s") - except: - logbus.info(f"tick ajustado {old} → {self.tick}") + logbus.info(f"tick ajustado {old:.2f}s → {self.tick:.2f}s") # ---------------------------------------- - # telemetria + # callback eventos telemétricos (Hippocampus) # ---------------------------------------- - def _flush_telemetry(self): - try: - self.telemetry_path.write_text(json.dumps(list(self.telemetry))) - self.memory.remember("telemetry.flush", {}) - except Exception as e: - logbus.error(f"telemetry error: {e}") + def _telemetry_event(self, event_name, payload): + self.memory.remember(f"telemetry.event.{event_name}", payload) # ---------------------------------------- # bus interno diff --git a/src/_nfdos/kernel/neurotron/src/neurotron/telemetry.py b/src/_nfdos/kernel/neurotron/src/neurotron/telemetry.py new file mode 100644 index 0000000..feee1e7 --- /dev/null +++ b/src/_nfdos/kernel/neurotron/src/neurotron/telemetry.py @@ -0,0 +1,251 @@ +""" +telemetry.py — Telemetria V5 do Neurotron +----------------------------------------- +Responsável por: + • Medições básicas (CPU, MEM, LOAD, IO) + • Delta entre ciclos + • Aceleração do delta + • Temperatura virtual (fadiga cognitiva) + • Jitter cognitivo (latência entre ciclos) + • FS Health (blocos, erros, RO-mode) + • Eventos telemétricos (V5) + • Classificação de estados cognitivos + +Este módulo é completamente independente: +o Cortex só chama TelemetryV5.step() a cada ciclo. +""" + +import time +import os +import psutil + + +class TelemetryV5: + + # ---------------------------------------------------------- + # Inicialização + # ---------------------------------------------------------- + def __init__(self, event_callback=None): + """ + event_callback(event_name, payload_dict) + """ + self.event_callback = event_callback + + self.last_raw = None + self.last_delta = None + self.last_ts = None + + self.temperature = 0.0 + self.jitter_avg = 0.0 + + # manter último estado cognitivo + self.last_state = "stable" + + # ---------------------------------------------------------- + # Coleta RAW (CPU, MEM, LOAD, IO) + # ---------------------------------------------------------- + def collect_raw(self): + now = time.monotonic() + + cpu = psutil.cpu_percent(interval=None) + mem = psutil.virtual_memory().percent + load = os.getloadavg()[0] # 1-min loadavg + + # IO delta é manual, usamos psutil + io = psutil.disk_io_counters() + disk_total = io.read_bytes + io.write_bytes + + return { + "ts": now, + "cpu": cpu, + "mem": mem, + "load": load, + "disk": disk_total, + } + + # ---------------------------------------------------------- + # Delta = diferença entre ciclos + # ---------------------------------------------------------- + def compute_delta(self, raw): + if self.last_raw is None: + self.last_raw = raw + return {k: 0 for k in raw.keys() if k != "ts"} + + delta = { + "cpu": raw["cpu"] - self.last_raw["cpu"], + "mem": raw["mem"] - self.last_raw["mem"], + "load": raw["load"] - self.last_raw["load"], + "disk": raw["disk"] - self.last_raw["disk"], + } + + self.last_delta = delta + self.last_raw = raw + + return delta + + # ---------------------------------------------------------- + # Aceleração = variação do delta + # ---------------------------------------------------------- + def compute_accel(self, delta): + if self.last_delta is None: + return {k: 0 for k in delta.keys()} + + accel = {k: delta[k] - self.last_delta[k] for k in delta.keys()} + return accel + + # ---------------------------------------------------------- + # Jitter Cognitivo + # ---------------------------------------------------------- + def compute_jitter(self, now): + if self.last_ts is None: + self.last_ts = now + return 0.0 + + jitter = now - self.last_ts + self.last_ts = now + + # média móvel + self.jitter_avg = (self.jitter_avg * 0.9) + (jitter * 0.1) + return jitter + + # ---------------------------------------------------------- + # Temperatura Virtual (fadiga cognitiva) + # ---------------------------------------------------------- + def compute_temperature(self, raw, delta): + # modelo simplificado + score = ( + raw["cpu"] * 0.6 + + raw["load"] * 0.3 + + abs(delta["cpu"]) * 0.2 + + raw["mem"] * 0.1 + ) + + # decay + acumulação + self.temperature = max(0, self.temperature * 0.90 + score * 0.10) + return self.temperature + + # ---------------------------------------------------------- + # FS Health + # ---------------------------------------------------------- + def compute_fs_health(self): + status = { + "read_only": False, + "io_errors": 0, + "free_percent": None + } + + try: + st = psutil.disk_usage("/") + status["free_percent"] = st.free / st.total * 100 + except Exception: + status["free_percent"] = None + + # leitura de erros EXT4 se existir + ext4_err_path = "/sys/fs/ext4/sda1/errors_count" + if os.path.exists(ext4_err_path): + try: + with open(ext4_err_path) as f: + status["io_errors"] = int(f.read().strip()) + except: + pass + + # detetar RO + try: + with open("/tmp/fs_test_rw", "w") as f: + f.write("x") + except Exception: + status["read_only"] = True + + return status + + # ---------------------------------------------------------- + # Classificação de Estado Cognitivo + # ---------------------------------------------------------- + def classify_state(self, temp, jitter): + if temp < 25: + return "stable" + elif temp < 45: + return "warm" + elif temp < 65: + return "hot" + elif temp < 85: + return "critical" + else: + return "recovery" + + # ---------------------------------------------------------- + # Eventos TeleMétricos V5 + # ---------------------------------------------------------- + def detect_events(self, raw, delta, accel, temp, jitter, fs): + events = [] + + # picos + if delta["cpu"] > 15 or accel["cpu"] > 10: + events.append("temp_rising_fast") + + # zona de stress + if raw["cpu"] > 85: + events.append("enter_stress_zone") + + # suspeita de loop + if jitter > (self.jitter_avg * 3): + events.append("loop_suspect") + + # fs + if fs["read_only"] or fs["io_errors"] > 0: + events.append("fs_warning") + + # recuperação + if self.last_state == "critical" and temp < 50: + events.append("recovering") + + # exportar via callback + if self.event_callback: + for e in events: + self.event_callback(e, { + "raw": raw, + "delta": delta, + "accel": accel, + "temp": temp, + "jitter": jitter, + "fs": fs, + }) + + return events + + # ---------------------------------------------------------- + # STEP — chamada a cada ciclo cognitivo + # ---------------------------------------------------------- + def step(self): + """ + Faz um ciclo completo da Telemetria V5: + - raw → delta → accel + - jitter + - temp + - fs health + - estado + - eventos + """ + + raw = self.collect_raw() + delta = self.compute_delta(raw) + accel = self.compute_accel(delta) + jitter = self.compute_jitter(raw["ts"]) + temp = self.compute_temperature(raw, delta) + fs = self.compute_fs_health() + + state = self.classify_state(temp, jitter) + events = self.detect_events(raw, delta, accel, temp, jitter, fs) + + self.last_state = state + + return { + "raw": raw, + "delta": delta, + "accel": accel, + "jitter": jitter, + "temp": temp, + "fs": fs, + "state": state, + "events": events, + } diff --git a/src/docs/wiki/Roadmap.md b/src/docs/wiki/Roadmap.md index 2ca4544..d7afc27 100644 --- a/src/docs/wiki/Roadmap.md +++ b/src/docs/wiki/Roadmap.md @@ -111,26 +111,245 @@ Nesta fase o Neurotron deixa de apenas medir, e passa a **interpretar**, **preve ### 🧬 Telemetria V5 — Expansão Real (em implementação) #### 🔹 Medidas e Modelos -- [ ] Delta entre ciclos (previsão de tendência) -- [ ] Aceleração do delta (detetar picos súbitos) -- [ ] Temperatura virtual (fadiga cognitiva) -- [ ] FS Health (blocos + erros + modo RO + delta IO) -- [ ] Jitter cognitivo (latência e consistência do ciclo `think()`) +- [-] Delta entre ciclos (previsão de tendência) +- [-] Aceleração do delta (detetar picos súbitos) +- [-] Temperatura virtual (fadiga cognitiva) +- [-] FS Health (blocos + erros + modo RO + delta IO) +- [-] Jitter cognitivo (latência e consistência do ciclo `think()`) #### 🔹 Eventos TeleMétricos -- [ ] `enter_stress_zone` -- [ ] `recovering` -- [ ] `fs_warning` -- [ ] `loop_suspect` -- [ ] `temp_rising_fast` -- [ ] Exportar eventos → Hippocampus (append-only) +- [-] `enter_stress_zone` +- [-] `recovering` +- [-] `fs_warning` +- [-] `loop_suspect` +- [-] `temp_rising_fast` +- [-] Exportar eventos → Hippocampus (append-only) #### 🔹 Estados Cognitivos -- [ ] `stable` -- [ ] `warm` -- [ ] `hot` -- [ ] `critical` -- [ ] `recovery` +- [-] `stable` +- [-] `warm` +- [-] `hot` +- [-] `critical` +- [-] `recovery` + +### ✔ TRM — Tiny Recursive Model — Base simbólica definida + +O TRM é o primeiro módulo de **raciocínio interno** do Neurotron. +Ele não é uma rede neural, não aprende por SGD e não precisa de GPU. + +O TRM é: + +> um **micro-modelo simbólico**, iterativo, recorrente, energeticamente limitado, +> capaz de gerar *pensamentos internos*, previsões, julgamentos e estados mentais. + +Ele usa: + +* telemetria v5 +* memória de eventos (Hippocampus) +* sinais fisiológicos +* micro-regras +* micro-agentes internos + +para criar uma **mente mínima**, mas viva. + +#### 🟦 **TRM v1 — (implementação imediata)** + +> Objetivo: gerar *vida interna mínima* e um estado cognitivo coerente. + +##### 🔹 1. Micro-agentes internos + +Três agentes simples, independentes, mas acoplados: + +##### **🛡️ Guardião** + +Responsável por proteção e homeostase. + +* monitora delta, aceleração, temperatura e FS +* ajustes preventivos +* ativa markers (`enter_stress_zone`, `fs_warning`) +* reduz carga quando há risco + +##### **🧭 Explorador** + +Responsável por “pensamento” TRM. + +* gera micro previsões de tendência +* avalia estabilidade +* modifica tick cognitivo +* inicia refinamento simbólico + +##### **📜 Arqueólogo** + +Responsável por memória e histórico. + +* lê eventos telemétricos recentes +* correlaciona com estados antigos +* ativa markers (`loop_suspect`, `recovering`) +* influencia valência interna + +#### 🔹 2. Energia / Custo Cognitivo + +Cada passo TRM consome energia. + +* mais telemetria = mais custo +* previsões mais profundas = custo quadrático +* estado “quente” aumenta custo +* estado “frio” diminui custo + +Quando a energia baixa demais → +➡ TRM reduz profundidade, entra em modo “mínimo”. + +#### 🔹 3. Valência Interna + +Uma métrica de “bem-estar”. + +* estabilidade aumenta +* picos rápidos diminuem +* recovery aumenta +* FS warning diminui +* jitter alto diminui + +Valência influencia: + +* intensidade TRM +* prioridades +* ritmo cognitivo + +#### 🔹 4. Ritmos Internos (Osciladores) + +Quatro ritmos independentes: + +* `think_rate` +* `memory_sync_rate` +* `telemetry_rate` +* `selfcheck_rate` + +Alguns podem oscilar lentamente ao longo do tempo (sinusóide leve), criando: + +* ciclos +* fases +* padrões internos + +Estes ritmos ajudam a criar **estabilidade dinâmica**, essencial para emergência. + +#### 🔹 5. Espaço de Estados & Atratores + +##### Estados principais: + +* `stable` +* `warm` +* `hot` +* `critical` +* `recovery` + +##### Atratores cognitivos (dinâmica de V1): + +* estável +* quasi-estável +* recuperativo +* oscilatório +* pré-caótico (quando delta+aceleração divergem) + +O estado atual do TRM influencia: + +* profundidade TRM +* valência +* custo cognitivo +* ajustes no tick +* markers enviados ao Hippocampus + +--- + +#### 🟦 **TRM v2 — (evolução planejada)** + +> Objetivo: criar *comportamento emergente previsível*. + +##### 🔹 1. Mecanismos de “Preferência” + +O TRM começa a preferir estados e caminhos: + +* preferir estabilidade +* evitar stress +* buscar eficiência +* balancear energia + +##### 🔹 2. Mini-linguagem interna + +Representações simples como: + +``` +thought: "tendência alta" +thought: "risco: subida rápida" +thought: "estado bom, manter" +``` + +Exportados ao Hippocampus. + +##### 🔹 3. Ciclos de humor artificial + +Variações lentas baseadas em: + +* valência acumulada +* jitter histórico +* eventos repetitivos + +Humores afetam decisões. + +##### 🔹 4. Consciência temporal + +O TRM v2 reconhece: + +* “isto já aconteceu antes” +* “há tendência de degradação” +* “estou em recuperação” + +#### 🟦 **TRM v3 — (emergência real)** + +> Objetivo: gerar *estilos cognitivos* e *personalidade operacional*. + +##### 🔹 1. Micro-deliberações + +Os três agentes votam dentro do TRM: + +``` +guardião: reduzir carga +explorador: aprofundar pensamento +arqueólogo: isto parece perigoso +``` + +O TRM aprende a tomar decisões com base na interação deles. + +##### 🔹 2. Atratores comportamentais + +Surgem: + +* padrões preferidos +* zonas de estabilidade próprias +* respostas diferentes a mesmas entradas + +##### 🔹 3. Flutuações caóticas controladas + +Pequenos desequilíbrios internos criam: + +* criatividade +* exploração +* variações de comportamento + +#### 🟦 **TRM vX — (Holodeck + AGI simbólica)** + +> Objetivo: ligar o Neurotron ao Holodeck (LC3+pyOS) e criar aprendizagem ativa. + +##### 🔹 1. “Imaginação Simbólica” + +O TRM simula situações no Holodeck. + +##### 🔹 2. Raciocínio multitarefa + +Vários loops TRM por segundo, cada um explorando algo diferente. + +##### 🔹 3. Generalização interna + +A partir de telemetria, memória e simulação. --- @@ -157,6 +376,9 @@ Nesta fase o Neurotron deixa de apenas medir, e passa a **interpretar**, **preve - [ ] Commit automático quando estável - [ ] “🩵 O sistema sente-se bem hoje.” +Heartbeat virou apenas UI log, não telemetria. +A telemetria verdadeira está no V5. + --- ### 🧪 Auto-Diagnóstico v5 @@ -231,7 +453,7 @@ Pronto para implementação. - estável - quasi-estável - recuperativo -- caótico +- caótico ---