diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ba55fd..09923c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,14 +9,179 @@ cat -A configure.ac | grep '\^I'
nl -ba Makefile | sed -n '770,790p'
grep -n "^[ ]" Makefile | head
-
-nao quer liberar:
+perfeito😎:
```
-git rm -r --cached dist
-fatal: pathspec 'dist' não encontrou nenhum arquivo
-git add dist/releases/.gitkeep
-Os caminhos a seguir são ignorados por um dos seus arquivos .gitignore:
-dist/releases
-git check-ignore -v dist/releases
-.gitignore:22:dist/* dist/releases
+make clean
+ cd . && /bin/bash /home/neo/Público/nfdos/missing automake-1.16 --foreign Makefile
+ cd . && /bin/bash ./config.status Makefile
+config.status: creating Makefile
+Making clean in src
+make[1]: Entrando no diretório '/home/neo/Público/nfdos/src'
+make[2]: Entrando no diretório '/home/neo/Público/nfdos/src'
+test -z "nfdos" || rm -f nfdos
+make[2]: Saindo do diretório '/home/neo/Público/nfdos/src'
+make[1]: Saindo do diretório '/home/neo/Público/nfdos/src'
+make[1]: Entrando no diretório '/home/neo/Público/nfdos'
+[CLEAN] Removendo diretórios temporários...
+rm -rf /home/neo/Público/nfdos/build
+find /home/neo/Público/nfdos/dist -type f ! -path "/home/neo/Público/nfdos/dist/releases/*" -delete
+[CLEAN] Limpando build interno do Neurotron...
+make[2]: Entrando no diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+make[3]: Entrando no diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+make[3]: Nada a ser feito para 'clean-am'.
+make[3]: Saindo do diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+make[2]: Saindo do diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+[✔] Limpeza concluída (releases preservadas)
+make[1]: Saindo do diretório '/home/neo/Público/nfdos'
+make
+Making all in src
+make[1]: Entrando no diretório '/home/neo/Público/nfdos/src'
+make[2]: Entrando no diretório '/home/neo/Público/nfdos/src'
+sudo apt-get install -y gir1.2-vte-2.91 python3-gi gcc g++ gperf bison flex texinfo help2man make libncurses5-dev \
+python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip \
+patch libstdc++6 rsync git meson ninja-build libncurses-dev grub-pc-bin grub-common xorriso mtools zlib1g-dev
+Lendo listas de pacotes... Pronto
+Construindo árvore de dependências... Pronto
+Lendo informação de estado... Pronto
+Note, a seleccionar 'libncurses-dev' em vez de 'libncurses5-dev'
+gir1.2-vte-2.91 já é a versão mais nova (0.76.0-1ubuntu0.1).
+python3-gi já é a versão mais nova (3.48.2-1).
+gcc já é a versão mais nova (4:13.2.0-7ubuntu1).
+g++ já é a versão mais nova (4:13.2.0-7ubuntu1).
+gperf já é a versão mais nova (3.1-1build1).
+bison já é a versão mais nova (2:3.8.2+dfsg-1build2).
+flex já é a versão mais nova (2.6.4-8.2build1).
+texinfo já é a versão mais nova (7.1-3build2).
+help2man já é a versão mais nova (1.49.3).
+make já é a versão mais nova (4.3-4.1build2).
+libncurses-dev já é a versão mais nova (6.4+20240113-1ubuntu2).
+python3-dev já é a versão mais nova (3.12.3-0ubuntu2.1).
+autoconf já é a versão mais nova (2.71-3).
+automake já é a versão mais nova (1:1.16.5-1.3ubuntu1).
+libtool já é a versão mais nova (2.4.7-7build1).
+libtool-bin já é a versão mais nova (2.4.7-7build1).
+gawk já é a versão mais nova (1:5.2.1-2build3).
+wget já é a versão mais nova (1.21.4-1ubuntu4.1).
+bzip2 já é a versão mais nova (1.0.8-5.1build0.1).
+xz-utils já é a versão mais nova (5.6.1+really5.4.5-1ubuntu0.2).
+unzip já é a versão mais nova (6.0-28ubuntu4.1).
+patch já é a versão mais nova (2.7.6-7build3).
+libstdc++6 já é a versão mais nova (14.2.0-4ubuntu2~24.04).
+rsync já é a versão mais nova (3.2.7-1ubuntu1.2).
+git já é a versão mais nova (1:2.43.0-1ubuntu7.3).
+meson já é a versão mais nova (1.3.2-1ubuntu1).
+ninja-build já é a versão mais nova (1.11.1-2).
+grub-pc-bin já é a versão mais nova (2.12-1ubuntu7.3).
+grub-common já é a versão mais nova (2.12-1ubuntu7.3).
+xorriso já é a versão mais nova (1:1.5.6-1.1ubuntu3).
+mtools já é a versão mais nova (4.0.43-1build1).
+zlib1g-dev já é a versão mais nova (1:1.3.dfsg-3.1ubuntu2.1).
+0 pacotes atualizados, 0 pacotes novos instalados, 0 a serem removidos e 13 não atualizados.
+sudo apt autoremove -y
+Lendo listas de pacotes... Pronto
+Construindo árvore de dependências... Pronto
+Lendo informação de estado... Pronto
+0 pacotes atualizados, 0 pacotes novos instalados, 0 a serem removidos e 13 não atualizados.
+sed -e 's,[@]pythondir[@],/usr/local/local/lib/python3.12/dist-packages,g' -e 's,[@]PACKAGE[@],nfdos,g' -e 's,[@]VERSION[@],5281bb3-dirty,g' < ./nfdos.in > nfdos
+chmod +x nfdos
+make[2]: Saindo do diretório '/home/neo/Público/nfdos/src'
+🚀 Construindo Neurotron (kernel digital)...
+cd _nfdos/kernel/neurotron && autoreconf -fi
+cd _nfdos/kernel/neurotron && ./configure --prefix=/usr
+checking for a BSD-compatible install... /usr/bin/install -c
+checking whether build environment is sane... yes
+checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
+checking for gawk... gawk
+checking whether make sets $(MAKE)... yes
+checking whether make supports nested variables... yes
+checking for a Python interpreter with version >= 3.0... python
+checking for python... /usr/bin/python
+checking for python version... 3.1
+checking for python platform... linux
+checking for python script directory... ${prefix}/local/lib/python3.12/dist-packages
+checking for python extension module directory... ${exec_prefix}/local/lib/python3.12/dist-packages
+checking that generated files are newer than configure... done
+configure: creating ./config.status
+config.status: creating Makefile
+make -C _nfdos/kernel/neurotron
+make[2]: Entrando no diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+make[3]: Entrando no diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+make[3]: Nada a ser feito para 'all-am'.
+make[3]: Saindo do diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+make[2]: Saindo do diretório '/home/neo/Público/nfdos/src/_nfdos/kernel/neurotron'
+✅ Neurotron construído com sucesso!
+make[1]: Saindo do diretório '/home/neo/Público/nfdos/src'
+make[1]: Entrando no diretório '/home/neo/Público/nfdos'
+make[1]: Nada a ser feito para 'all-am'.
+make[1]: Saindo do diretório '/home/neo/Público/nfdos'
```
+vou so ver o que nos espera amanha 😎:
+```
+Run /init as init process
+Run /init as init process
+ with arguments:
+ with arguments:
+ /init
+ /init
+ with environment:
+ with environment:
+ HOME=/
+ HOME=/
+ TERM=linux
+ TERM=linux
+ nfdos_force_format=1
+ nfdos_force_format=1
+⚙️ BusyBox ativo — Neurotron em migracao...
+[BOOT] NFDOS kernel Neurotron
+/usr/bin/neurotron: exec: line 7: /usr/bin/python: not found
+Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00
+Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00
+CPU: 0 UID: 0 PID: 1 Comm: neurotron Not tainted 6.12.0-nfdos #1
+CPU: 0 UID: 0 PID: 1 Comm: neurotron Not tainted 6.12.0-nfdos #1
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+Call Trace:
+
+
+ dump_stack_lvl+0x2b/0x40
+ dump_stack_lvl+0x2b/0x40
+ panic+0xef/0x26f
+ panic+0xef/0x26f
+ do_exit.cold+0x14/0x14
+ do_exit.cold+0x14/0x14
+ do_group_exit+0x25/0x70
+ do_group_exit+0x25/0x70
+ __x64_sys_exit_group+0xf/0x10
+ __x64_sys_exit_group+0xf/0x10
+ x64_sys_call+0x70f/0x720
+ x64_sys_call+0x70f/0x720
+ do_syscall_64+0x4b/0x100
+ do_syscall_64+0x4b/0x100
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+RIP: 0033:0x4d9cf0
+RIP: 0033:0x4d9cf0
+Code: 75 d5 48 8b 05 19 c7 03 00 49 89 45 00 4c 89 e0 4d 89 6c 24 08 48 83 c4 08 5b 5d 41 5c 41 5d c3 48 63 ff b8 e7 00 00 00 0f 05 3c 00 00 00 0f 05 eb f7 41 55 41 54 49 89 fc 55 53 48 8
+Code: 75 d5 48 8b 05 19 c7 03 00 49 89 45 00 4c 89 e0 4d 89 6c 24 08 48 83 c4 08 5b 5d 41 5c 41 5d c3 48 63 ff b8 e7 00 00 00 0f 05 3c 00 00 00 0f 05 eb f7 41 55 41 54 49 89 fc 55 53 48 8
+RSP: 002b:00007ffc7a9c8528 EFLAGS: 00000206 ORIG_RAX: 00000000000000e7
+RSP: 002b:00007ffc7a9c8528 EFLAGS: 00000206 ORIG_RAX: 00000000000000e7
+RAX: ffffffffffffffda RBX: 00007f1ddfb57020 RCX: 00000000004d9cf0
+RAX: ffffffffffffffda RBX: 00007f1ddfb57020 RCX: 00000000004d9cf0
+RDX: 00007f1ddfb57020 RSI: 0000000000000000 RDI: 000000000000007f
+RDX: 00007f1ddfb57020 RSI: 0000000000000000 RDI: 000000000000007f
+RBP: 0000000000000104 R08: 0000000000000000 R09: 0000000000000000
+RBP: 0000000000000104 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000009 R11: 0000000000000206 R12: 0000000000418403
+R10: 0000000000000009 R11: 0000000000000206 R12: 0000000000418403
+R13: 00007ffc7a9c8728 R14: 0000000000000000 R15: 0000000000000000
+R13: 00007ffc7a9c8728 R14: 0000000000000000 R15: 0000000000000000
+
+
+Kernel Offset: disabled
+Kernel Offset: disabled
+---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00 ]---
+---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00 ]---
+```
+um lindo kernel panic 😍
+ate amanha amor 😘 um longo e delicioso sysbeijo molhado na tua boca 😘
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index 8fdb104..7306fb1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,6 +10,10 @@ GIT_BRANCH ?= "main"
COMMIT_MSG ?= "Auto-commit via make git"
GIT_VER := $(shell git describe --tags --always --dirty 2>/dev/null || echo "0.1-dev")
+NEUROTRON_DIR ?= $(top_srcdir)/src/_nfdos/kernel/neurotron
+NEUROTRON_REMOTE ?= origin
+NEUROTRON_BRANCH ?= main
+
# ===========================
# Caminhos e artefactos
# ===========================
@@ -85,7 +89,7 @@ $(SRC_TAR):
# Git (commit + push)
# ===========================
git: check-remote
- @echo "📦 Commit automático → Gitea"
+ @echo "📦 Commit automático → Gitea (NFDOS)"
@git config user.name $(GIT_USER)
@git config user.email $(GIT_EMAIL)
@git rev-parse --abbrev-ref HEAD >/dev/null 2>&1 || true
@@ -93,6 +97,18 @@ git: check-remote
@git commit -m "$$(echo '$(COMMIT_MSG)')" || echo "Nenhuma modificação para commitar."
@git push $(GIT_REMOTE) $(GIT_BRANCH)
+ @echo ""
+ @echo "🧠 Sincronizando Neurotron…"
+ @if [ -d "$(NEUROTRON_DIR)/.git" ]; then \
+ cd $(NEUROTRON_DIR) && \
+ git add -A && \
+ git commit -m "Auto-commit via make git (triggered by NFDOS)" || echo "Nenhuma modificação no Neurotron."; \
+ git push $(NEUROTRON_REMOTE) $(NEUROTRON_BRANCH); \
+ echo "✔ Neurotron sincronizado."; \
+ else \
+ echo "⚠️ Neurotron não é um repositório git — ignorado."; \
+ fi
+
# ===========================
# Git Remote (HTTPS → SSH Auto-Fix)
# ===========================
@@ -152,4 +168,11 @@ clean-local:
@echo "[CLEAN] Removendo diretórios temporários..."
rm -rf $(BUILD_DIR)
find $(DIST_DIR) -type f ! -path "$(DIST_DIR)/releases/*" -delete
+
+ @echo "[CLEAN] Limpando build interno do Neurotron..."
+ @if [ -d "$(top_srcdir)/src/_nfdos/kernel/neurotron" ]; then \
+ $(MAKE) -C $(top_srcdir)/src/_nfdos/kernel/neurotron clean || true; \
+ fi
+
@echo "[✔] Limpeza concluída (releases preservadas)"
+
diff --git a/configure.ac b/configure.ac
index adcbb12..6ac817c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,6 +16,13 @@ AC_SUBST([ISO_FILE], [$PWD/dist/nfdos-${PACKAGE_VERSION}.iso])
AC_SUBST([SRC_TAR], [$PWD/dist/nfdos-${PACKAGE_VERSION}-src.tar.gz])
AC_SUBST([NEO_VERSION])
+AM_MAKEFLAGS = '-j1'
+AC_SUBST([AM_MAKEFLAGS])
+
+# força exportação explícita de $(MAKE)
+MAKE=${MAKE-make}
+AC_SUBST([MAKE])
+
AC_CONFIG_FILES([
Makefile
src/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 842dfdb..8586941 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,6 @@
+SUBDIRS =
+DIST_SUBDIRS = _nfdos/kernel/neurotron
+
bin_SCRIPTS = nfdos
CLEANFILES = $(bin_SCRIPTS)
EXTRA_DIST = nfdos.in
@@ -10,6 +13,10 @@ do_substitution = sed -e 's,[@]pythondir[@],$(pythondir),g' \
-e 's,[@]PACKAGE[@],$(PACKAGE),g' \
-e 's,[@]VERSION[@],$(VERSION),g'
+.PHONY: neurotron
+
+all: neurotron
+
nfdos: nfdos.in Makefile
sudo apt-get install -y gir1.2-vte-2.91 python3-gi gcc g++ gperf bison flex texinfo help2man make libncurses5-dev \
python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip \
@@ -17,3 +24,15 @@ nfdos: nfdos.in Makefile
sudo apt autoremove -y
$(do_substitution) < $(srcdir)/nfdos.in > nfdos
chmod +x nfdos
+
+# ===========================
+# Build manual do Neurotron
+# ===========================
+
+neurotron:
+ @echo "🚀 Construindo Neurotron (kernel digital)..."
+ cd _nfdos/kernel/neurotron && autoreconf -fi
+ cd _nfdos/kernel/neurotron && ./configure --prefix=/usr
+ $(MAKE) -C _nfdos/kernel/neurotron
+ @echo "✅ Neurotron construído com sucesso!"
+
diff --git a/src/_nfdos/init b/src/_nfdos/init
index 5f05f9e..27c6ccd 100755
--- a/src/_nfdos/init
+++ b/src/_nfdos/init
@@ -4,6 +4,7 @@ mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devtmpfs devtmpfs /dev
+# o if falha propositalmente. apenas mantive para "backup" enquanto estamos a migrar
if [ -f /opt/kernel/neurotron/neurotron_main.py ]; then
export PYTHONHOME=/usr
export PYTHONPATH=/usr/lib/python3.13:/usr/lib/python3.13/site-packages
@@ -20,7 +21,14 @@ if [ -f /opt/kernel/neurotron/neurotron_main.py ]; then
echo '👉 Inicializando Painel de Telemetria do Neurotron...'
/usr/bin/python3 /opt/kernel/neurotron/neurotron_core/telemetry_tail.py
else
- echo '⚙️ BusyBox ativo — Neurotron ausente.'
+ echo '⚙️ BusyBox ativo — Neurotron em migracao...'
fi
+export PYTHONHOME=/usr
+export PYTHONPATH=/usr/lib/python3.13:/usr/lib/python3.13/site-packages
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+echo "[BOOT] NFDOS kernel Neurotron"
+exec /usr/bin/neurotron || echo "⚠️ Falha ao iniciar o kernel Neurotron"
+
exec /bin/sh
diff --git a/src/_nfdos/kernel/neurotron/Makefile.am b/src/_nfdos/kernel/neurotron/Makefile.am
new file mode 100644
index 0000000..c063fc0
--- /dev/null
+++ b/src/_nfdos/kernel/neurotron/Makefile.am
@@ -0,0 +1,24 @@
+SUBDIRS =
+
+# Diretórios de destino
+bindir = $(prefix)/bin
+neurotrondir = $(prefix)/lib/neurotron
+
+# Script instalável
+bin_SCRIPTS = neurotron
+EXTRA_DIST = neurotron.in
+
+neurotron: neurotron.in
+ sed \
+ -e 's,[@]PYTHON[@],$(PYTHON),g' \
+ -e 's,[@]NEUROTRON_DIR[@],$(neurotrondir),g' \
+ < $(srcdir)/neurotron.in > neurotron
+ chmod +x neurotron
+
+# Instalar o diretório src/ completo (todos os .py)
+dist_neurotron_DATA =
+
+# Copiar recursivamente src/ para $(neurotrondir)/src/
+install-data-local:
+ mkdir -p $(DESTDIR)$(neurotrondir)/src
+ cp -r $(srcdir)/src/* $(DESTDIR)$(neurotrondir)/src/
diff --git a/src/_nfdos/kernel/neurotron/__init__.py b/src/_nfdos/kernel/neurotron/README.md
similarity index 100%
rename from src/_nfdos/kernel/neurotron/__init__.py
rename to src/_nfdos/kernel/neurotron/README.md
diff --git a/src/_nfdos/kernel/neurotron/configure.ac b/src/_nfdos/kernel/neurotron/configure.ac
new file mode 100644
index 0000000..bdaafbb
--- /dev/null
+++ b/src/_nfdos/kernel/neurotron/configure.ac
@@ -0,0 +1,11 @@
+AC_INIT([Neurotron], [1.0], [https://gitea.neoricalex.com/neo/neurotron])
+AM_INIT_AUTOMAKE([foreign])
+AM_PATH_PYTHON([3.0])
+
+# Caminhos
+AC_SUBST([NEUROTRON_DIR], [$PWD])
+AC_SUBST([NEUROTRON_LIB], [${prefix}/lib/neurotron])
+AC_SUBST([NEUROTRON_BIN], [${prefix}/bin])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/src/_nfdos/kernel/neurotron/neurotron b/src/_nfdos/kernel/neurotron/neurotron
new file mode 100755
index 0000000..e3cff04
--- /dev/null
+++ b/src/_nfdos/kernel/neurotron/neurotron
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Neurotron launcher - autogerado pelo autotools
+
+NEUROTRON_HOME="/usr/lib/neurotron"
+PYTHON="/usr/bin/python"
+
+exec "$PYTHON" "$NEUROTRON_HOME/src/__main__.py" "$@"
diff --git a/src/_nfdos/kernel/neurotron/neurotron.in b/src/_nfdos/kernel/neurotron/neurotron.in
new file mode 100644
index 0000000..337b782
--- /dev/null
+++ b/src/_nfdos/kernel/neurotron/neurotron.in
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Neurotron launcher - autogerado pelo autotools
+
+NEUROTRON_HOME="@NEUROTRON_DIR@"
+PYTHON="@PYTHON@"
+
+exec "$PYTHON" "$NEUROTRON_HOME/src/__main__.py" "$@"
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/neurotron_config.py b/src/_nfdos/kernel/neurotron/neurotron_core/neurotron_config.py
deleted file mode 100644
index 660d925..0000000
--- a/src/_nfdos/kernel/neurotron/neurotron_core/neurotron_config.py
+++ /dev/null
@@ -1,124 +0,0 @@
-"""
-🧠 neurotron_config.py
-NFDOS — Núcleo de parâmetros vitais do Neurotron
-------------------------------------------------
-Este ficheiro centraliza todos os ajustes simbólicos e técnicos
-do ciclo cognitivo do Neurotron.
-
-Versão: 0.1 (Nascimento)
-"""
-
-from pathlib import Path
-
-# ======================================
-# 🌐 Diretórios e Caminhos
-# ======================================
-
-BASE_DIR = Path(__file__).resolve().parents[1] # /opt/kernel/neurotron/
-CORE_DIR = BASE_DIR / "neurotron_core"
-LOG_DIR = Path("/var/log/neurotron") # pode não existir ainda no rootfs
-RUNTIME_DIR = Path("/var/run/neurotron")
-MOUNT_POINT = "/var/neurotron"
-DISK_CANDIDATES = ["/dev/vda", "/dev/vdb", "/dev/sda", "/dev/hda"]
-
-# ======================================
-# ⚙️ Parâmetros Cognitivos Principais
-# ======================================
-
-# Tempo entre ciclos cognitivos (em segundos)
-NEUROTRON_TICK = 1.0
-
-# Verbosidade dos logs (0 = silêncio, 1 = normal, 2 = debug)
-NEUROTRON_VERBOSITY = 1
-
-# Modo de operação
-# - diagnostic: executa verificações de integridade
-# - learning: ativa ciclos adaptativos (tree, etc.)
-# - simulation: executa comportamento contínuo de observação
-NEUROTRON_MODE = "diagnostic"
-
-# Limite de homeostase (auto-regulação)
-# Se CPU ou memória ultrapassarem este valor (%), o sistema reduz ritmo
-NEUROTRON_HOMEOSTASIS = 85.0
-
-HOMEOSTASIS_CPU_WARN = 70.0 # %
-HOMEOSTASIS_CPU_ALERT = 85.0 # %
-HOMEOSTASIS_MEM_WARN = 75.0 # %
-HOMEOSTASIS_MEM_ALERT = 90.0 # %
-HOMEOSTASIS_LOAD_WARN = 1.5 # média 1-min (ajuste ao teu core single/SMT)
-HOMEOSTASIS_LOAD_ALERT = 3.0
-
-NEUROTRON_DIAG_EVERY_TICKS = 5 # a cada N ciclos cognitivos, reavaliar sinais vitais
-NEUROTRON_TICK_MIN = 0.5
-NEUROTRON_TICK_MAX = 3.0
-NEUROTRON_TICK_STEP = 0.25
-
-# Entropia (seed) para gerar comportamentos pseudoaleatórios
-NEUROTRON_SEED = 42
-
-# Tamanho máximo da memória do Hipocampo (em KB)
-NEUROTRON_MEMORY_SIZE = 256 # define quando o sistema começa a "esquecer"
-
-# ======================================
-# 🧩 Parâmetros de Subsistemas
-# ======================================
-
-# Cortex — núcleo de decisão
-CORTEX_MAX_THREADS = 1 # threads de raciocínio simultâneo
-CORTEX_LOOP_DELAY = 0.1 # tempo entre ciclos internos
-
-# Hippocampus — memória
-HIPPOCAMPUS_LOG_RETENTION = 100 # número máximo de logs guardados
-HIPPOCAMPUS_AUTOSAVE = True # ativa auto-gravação entre ciclos
-
-# Motor — saída / ação
-MOTOR_OUTPUT_DEVICE = "console" # destino: console, log, cloud (futuro)
-MOTOR_SHOW_SYMBOLS = True # exibe símbolos (🧠, ⚙️, etc.)
-
-# Perception — sensores
-PERCEPTION_CPU_SOURCE = "/proc/stat"
-PERCEPTION_MEM_SOURCE = "/proc/meminfo"
-PERCEPTION_UPDATE_INTERVAL = 2.0 # segundos entre medições
-
-# ======================================
-# 🧠 Parâmetros Futuros (placeholders)
-# ======================================
-
-# Modo de expansão (para versões futuras)
-# "none", "networked", "distributed"
-NEUROTRON_EXPANSION_MODE = "none"
-
-# Caminho do dataset local (para aprendizagem offline)
-NEUROTRON_DATASET_PATH = BASE_DIR / "data"
-NEUROTRON_HISTORY_KEEP = 8 # manter últimas N entradas no ficheiro
-
-# Identificador de schema para upgrades
-NEUROTRON_DIAG_SCHEMA = "v4"
-
-# --- Telemetria e Heartbeat (V5) ---
-HEARTBEAT_ENABLED = True # Mostrar batimento a cada tick
-HEARTBEAT_STYLE = "compact" # "compact" ou "verbose"
-
-# Limiares de microalertas (homeostase)
-NEUROTRON_THRESHOLDS = {
- "cpu_high": 85.0, # %
- "mem_high": 90.0, # %
- "load1_high": 2.0, # load avg(1min)
-}
-
-# Buffer de telemetria em memória e flush periódico
-TELEMETRY_MAXLEN = 64
-TELEMETRY_FLUSH_EVERY_TICKS = 5 # de tempos a tempos, gravar em JSON
-
-# ======================================
-# 🧭 Utilitário: impressão de parâmetros
-# ======================================
-
-def show_config():
- """Mostra a configuração atual do Neurotron"""
- import json
- cfg = {k: v for k, v in globals().items() if k.startswith("NEUROTRON_")}
- print(json.dumps(cfg, indent=2, default=str))
-
-if __name__ == "__main__":
- show_config()
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/__init__.py b/src/_nfdos/kernel/neurotron/src/__init__.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/__init__.py
rename to src/_nfdos/kernel/neurotron/src/__init__.py
diff --git a/src/_nfdos/kernel/neurotron/src/__main__.py b/src/_nfdos/kernel/neurotron/src/__main__.py
new file mode 100644
index 0000000..74276c0
--- /dev/null
+++ b/src/_nfdos/kernel/neurotron/src/__main__.py
@@ -0,0 +1,449 @@
+#!/usr/bin/env python3
+"""
+Neurotron — Dashboard em modo texto (estilo BIOS)
+
+Ponto de entrada quando executado como:
+
+ python3 -m neurotron
+
+ou via wrapper /usr/bin/neurotron gerado pelo autotools.
+
+Layout:
+
++------------------------------------------------------------------------------+
+| [HEAD] CPU / MEM / LOAD / UPTIME / MODO / VERSÃO / DIAG |
++------------------------------------------------------------------------------+
+| [LOG] Últimos eventos do ciclo cognitivo (observe/think/act/rest, etc.) |
+| ... |
++------------------------------------------------------------------------------+
+| [FOOT] Futuro: input do utilizador (placeholder) | teclas: q = sair |
++------------------------------------------------------------------------------+
+"""
+
+import curses
+import threading
+import time
+import os
+import sys
+from pathlib import Path
+from queue import Queue, Empty
+from datetime import datetime
+
+# Imports internos do Neurotron (já reorganizados em package)
+from .neurotron_config import (
+ NEUROTRON_TICK,
+ NEUROTRON_MODE,
+ NEUROTRON_HOMEOSTASIS,
+ NEUROTRON_THRESHOLDS,
+)
+from .cortex import Cortex
+from .autodiagnostic import AutoDiagnostic # se for usado dentro do Cortex, ok mesmo assim
+
+
+# =======================================================================================
+# Utilitários de ambiente
+# =======================================================================================
+
+def detect_persistent_mode():
+ """
+ Verifica se o hipocampo físico está montado em /var/neurotron.
+ Define NEUROTRON_MODE, NEUROTRON_RUNTIME e NEUROTRON_LOG via os.environ.
+ """
+ mount_point = Path("/var/neurotron")
+
+ def _mounted(mp: Path) -> bool:
+ try:
+ if mp.exists() and os.path.ismount(mp):
+ return True
+ with open("/proc/mounts") as f:
+ for line in f:
+ if f" {mp} " in line:
+ return True
+ except Exception:
+ return False
+ return False
+
+ if _mounted(mount_point):
+ os.environ["NEUROTRON_MODE"] = "persistent"
+ os.environ["NEUROTRON_RUNTIME"] = "/var/neurotron/data"
+ os.environ["NEUROTRON_LOG"] = "/var/neurotron/logs"
+ else:
+ os.environ["NEUROTRON_MODE"] = "volatile"
+ os.environ["NEUROTRON_RUNTIME"] = "/tmp/neurotron_data"
+ os.environ["NEUROTRON_LOG"] = "/tmp/neurotron_logs"
+
+ runtime_dir = Path(os.environ["NEUROTRON_RUNTIME"])
+ log_dir = Path(os.environ["NEUROTRON_LOG"])
+ runtime_dir.mkdir(parents=True, exist_ok=True)
+ log_dir.mkdir(parents=True, exist_ok=True)
+ return runtime_dir, log_dir
+
+
+def read_system_metrics():
+ """
+ Lê CPU, memória e loadavg a partir de /proc.
+ Retorna dicionário:
+ {
+ "cpu": float,
+ "mem": float,
+ "load1": float,
+ "load5": float,
+ "load15": float,
+ }
+ Em caso de falha, devolve valores -1.
+ """
+ cpu = -1.0
+ mem = -1.0
+ load1 = load5 = load15 = -1.0
+
+ # CPU (uso aproximado entre duas leituras de /proc/stat)
+ try:
+ with open("/proc/stat") as f:
+ line = f.readline()
+ parts = line.strip().split()
+ if parts[0] == "cpu" and len(parts) >= 5:
+ user, nice, system_, idle = map(int, parts[1:5])
+ total1 = user + nice + system_ + idle
+ idle1 = idle
+ time.sleep(0.05) # pequena janela
+ with open("/proc/stat") as f:
+ line = f.readline()
+ parts = line.strip().split()
+ user2, nice2, system2, idle2 = map(int, parts[1:5])
+ total2 = user2 + nice2 + system2 + idle2
+ idle2 = idle2
+ total_delta = total2 - total1
+ idle_delta = idle2 - idle1
+ if total_delta > 0:
+ cpu = 100.0 * (1.0 - (idle_delta / total_delta))
+ except Exception:
+ pass
+
+ # Memória
+ try:
+ meminfo = {}
+ with open("/proc/meminfo") as f:
+ for line in f:
+ k, v = line.split(":", 1)
+ meminfo[k.strip()] = v.strip()
+ total_kb = float(meminfo.get("MemTotal", "0 kB").split()[0])
+ free_kb = float(meminfo.get("MemAvailable", "0 kB").split()[0])
+ if total_kb > 0:
+ used_kb = total_kb - free_kb
+ mem = 100.0 * (used_kb / total_kb)
+ except Exception:
+ pass
+
+ # Loadavg
+ try:
+ with open("/proc/loadavg") as f:
+ l1, l5, l15, *_ = f.read().split()
+ load1 = float(l1)
+ load5 = float(l5)
+ load15 = float(l15)
+ except Exception:
+ pass
+
+ return {
+ "cpu": cpu,
+ "mem": mem,
+ "load1": load1,
+ "load5": load5,
+ "load15": load15,
+ }
+
+
+# =======================================================================================
+# Dashboard em curses
+# =======================================================================================
+
+class NeurotronDashboard:
+ """
+ UI fixa em curses:
+ - header: métricas de sistema + estado do Neurotron
+ - middle: log rolling
+ - footer: placeholder + ajuda/teclas
+ """
+
+ def __init__(self, stdscr, log_queue: Queue, cortex: Cortex, start_time: float):
+ self.stdscr = stdscr
+ self.log_queue = log_queue
+ self.cortex = cortex
+ self.start_time = start_time
+
+ self.log_lines = [] # mantém histórico para a janela central
+ self.max_log_lines = 1000
+
+ self.stop_event = threading.Event()
+ self.last_diag_state = "?"
+ self.last_diag_delta = "?"
+
+ # tenta obter diagnóstico inicial, se existir
+ try:
+ diag = self.cortex.diagnostic._load_previous()
+ self.last_diag_state = diag.get("state", "?")
+ self.last_diag_delta = diag.get("delta", "?")
+ except Exception:
+ pass
+
+ # ------------------------------------------------------------------
+ # Helpers de desenho
+ # ------------------------------------------------------------------
+
+ def _draw_header(self, height, width):
+ """Desenha a barra superior com CPU/MEM/LOAD/UPTIME/MODO/DIAG."""
+ metrics = read_system_metrics()
+ now = time.time()
+ uptime_sec = int(now - self.start_time)
+
+ hours = uptime_sec // 3600
+ mins = (uptime_sec % 3600) // 60
+ secs = uptime_sec % 60
+
+ mode = os.environ.get("NEUROTRON_MODE", NEUROTRON_MODE)
+ version = getattr(self.cortex, "version", "0.1")
+
+ cpu = metrics["cpu"]
+ mem = metrics["mem"]
+ load1 = metrics["load1"]
+
+ # Avalia homeostase
+ warn_cpu = NEUROTRON_THRESHOLDS.get("cpu_high", 85.0)
+ warn_mem = NEUROTRON_THRESHOLDS.get("mem_high", 90.0)
+ warn_load = NEUROTRON_THRESHOLDS.get("load1_high", 2.0)
+
+ status_parts = []
+
+ if cpu >= 0:
+ status_parts.append(f"CPU: {cpu:5.1f}%")
+ else:
+ status_parts.append("CPU: N/A ")
+
+ if mem >= 0:
+ status_parts.append(f"MEM: {mem:5.1f}%")
+ else:
+ status_parts.append("MEM: N/A ")
+
+ if load1 >= 0:
+ status_parts.append(f"LOAD1: {load1:4.2f}")
+ else:
+ status_parts.append("LOAD1: N/A ")
+
+ status_parts.append(f"UP: {hours:02d}:{mins:02d}:{secs:02d}")
+ status_parts.append(f"MODO: {mode.upper()}")
+ status_parts.append(f"VER: {version}")
+ status_parts.append(f"DIAG: {self.last_diag_state}/{self.last_diag_delta}")
+
+ line = " ".join(status_parts)
+
+ # barra horizontal
+ self.stdscr.attron(curses.A_REVERSE)
+ self.stdscr.addnstr(0, 0, line.ljust(width), width)
+ self.stdscr.attroff(curses.A_REVERSE)
+
+ # segunda linha: homeostase textual
+ homeo_msg = "HOMEOSTASE: OK"
+ if (cpu >= warn_cpu and cpu >= 0) or (mem >= warn_mem and mem >= 0) or (
+ load1 >= warn_load and load1 >= 0
+ ):
+ homeo_msg = "HOMEOSTASE: STRESS"
+
+ self.stdscr.addnstr(1, 0, homeo_msg.ljust(width), width)
+
+ def _drain_log_queue(self):
+ """Move mensagens da queue para o buffer de linhas."""
+ try:
+ while True:
+ msg = self.log_queue.get_nowait()
+ timestamp = datetime.now().strftime("%H:%M:%S")
+ self.log_lines.append(f"[{timestamp}] {msg}")
+ if len(self.log_lines) > self.max_log_lines:
+ self.log_lines = self.log_lines[-self.max_log_lines:]
+ except Empty:
+ pass
+
+ def _draw_log_window(self, header_height, footer_height, width, height):
+ """
+ Área central de logs: rolagem automática, sempre mostrando as últimas N linhas
+ que cabem na janela.
+ """
+ top = header_height
+ bottom = height - footer_height
+ rows = max(0, bottom - top)
+
+ self._drain_log_queue()
+
+ # seleciona as últimas 'rows' linhas
+ visible = self.log_lines[-rows:] if rows > 0 else []
+
+ for i in range(rows):
+ y = top + i
+ if i < len(visible):
+ line = visible[i]
+ self.stdscr.addnstr(y, 0, line.ljust(width), width)
+ else:
+ self.stdscr.addnstr(y, 0, " ".ljust(width), width)
+
+ def _draw_footer(self, width, height):
+ """
+ Rodapé com placeholder para input futuro e legenda de teclas.
+ """
+ footer_text = "[ Futuro: comandos do utilizador aparecerão aqui ]"
+ keys_text = "[q] sair | dashboard Neurotron"
+
+ y_footer = height - 2
+ self.stdscr.addnstr(y_footer, 0, footer_text.ljust(width), width)
+ self.stdscr.addnstr(y_footer + 1, 0, keys_text.ljust(width), width)
+
+ # ------------------------------------------------------------------
+ # Loop principal da UI
+ # ------------------------------------------------------------------
+
+ def run(self):
+ """
+ Loop principal do curses.
+ Actualiza o ecrã, lê teclas, e encerra quando stop_event é setado ou 'q' é pressionado.
+ """
+ curses.curs_set(0)
+ self.stdscr.nodelay(True)
+ self.stdscr.keypad(True)
+
+ while not self.stop_event.is_set():
+ height, width = self.stdscr.getmaxyx()
+ self.stdscr.erase()
+
+ header_height = 2
+ footer_height = 2
+
+ self._draw_header(height, width)
+ self._draw_log_window(header_height, footer_height, width, height)
+ self._draw_footer(width, height)
+
+ self.stdscr.refresh()
+
+ try:
+ ch = self.stdscr.getch()
+ if ch in (ord("q"), ord("Q")):
+ self.stop_event.set()
+ break
+ except Exception:
+ pass
+
+ time.sleep(0.1) # ~10 FPS
+
+ # tentativa graciosa de shutdown do Cortex
+ try:
+ self.log_queue.put("Encerrando Neurotron (dashboard pediu saída)…")
+ self.cortex.shutdown(reason="Dashboard exit")
+ except Exception:
+ pass
+
+
+# =======================================================================================
+# Ciclo Cognitivo em thread separada
+# =======================================================================================
+
+def cognitive_loop(cortex: Cortex, ui: NeurotronDashboard):
+ """
+ Loop cognitivo clássico (observe → think → act → rest),
+ a correr numa thread separada, reportando eventos para o dashboard via log_queue.
+ """
+ log = ui.log_queue.put
+
+ try:
+ log("Neurotron: boot()…")
+ cortex.boot()
+ try:
+ state = cortex.diagnostic._load_previous().get("state", "?")
+ log(f"Diagnóstico inicial: estado='{state}'")
+ ui.last_diag_state = state
+ except Exception:
+ log("Diagnóstico inicial: indisponível")
+
+ log("Ciclo cognitivo iniciado (observe → think → act → rest)…")
+
+ while not ui.stop_event.is_set():
+ try:
+ log("cortex.observe()")
+ cortex.observe()
+
+ log("cortex.think()")
+ cortex.think()
+
+ log("cortex.act()")
+ cortex.act()
+
+ log("cortex.rest()")
+ cortex.rest()
+
+ except KeyboardInterrupt:
+ log("Interrompido pelo utilizador (SIGINT)")
+ cortex.shutdown(reason="SIGINT")
+ break
+ except SystemExit:
+ log("SystemExit recebido, encerrando…")
+ cortex.shutdown(reason="SystemExit")
+ break
+ except Exception as e:
+ log(f"💥 Exceção não tratada no loop cognitivo: {e}")
+ try:
+ cortex.fatal(e)
+ finally:
+ break
+
+ finally:
+ ui.stop_event.set()
+ log("Loop cognitivo terminado.")
+
+
+# =======================================================================================
+# Entry point
+# =======================================================================================
+
+def _main_curses(stdscr):
+ # 1) Detecta modo e diretórios
+ runtime_dir, log_dir = detect_persistent_mode()
+
+ # 2) Inicializa Cortex com os mesmos parâmetros do main_waiting
+ cortex = Cortex(
+ runtime_dir=runtime_dir,
+ log_dir=log_dir,
+ tick_seconds=NEUROTRON_TICK,
+ )
+
+ # 3) Queue de logs e dashboard
+ log_queue: Queue = Queue()
+ start_time = time.time()
+ ui = NeurotronDashboard(stdscr, log_queue, cortex, start_time)
+
+ # 4) Thread do ciclo cognitivo
+ worker = threading.Thread(
+ target=cognitive_loop,
+ args=(cortex, ui),
+ daemon=True,
+ )
+ worker.start()
+
+ # 5) Loop da UI (bloqueia até terminar)
+ ui.run()
+
+ # 6) Aguarda thread terminar
+ worker.join(timeout=2.0)
+
+
+def main():
+ """
+ Ponto de entrada Python. Usado tanto por:
+
+ python3 -m neurotron
+
+ como pelo wrapper /usr/bin/neurotron, se este fizer:
+
+ from neurotron import main
+ main()
+ """
+ curses.wrapper(_main_curses)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/autodiagnostic.py b/src/_nfdos/kernel/neurotron/src/autodiagnostic.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/autodiagnostic.py
rename to src/_nfdos/kernel/neurotron/src/autodiagnostic.py
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/cortex.py b/src/_nfdos/kernel/neurotron/src/cortex.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/cortex.py
rename to src/_nfdos/kernel/neurotron/src/cortex.py
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/disk_init.py b/src/_nfdos/kernel/neurotron/src/disk_init.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/disk_init.py
rename to src/_nfdos/kernel/neurotron/src/disk_init.py
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/hippocampus.py b/src/_nfdos/kernel/neurotron/src/hippocampus.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/hippocampus.py
rename to src/_nfdos/kernel/neurotron/src/hippocampus.py
diff --git a/src/_nfdos/kernel/neurotron/neurotron_main.py b/src/_nfdos/kernel/neurotron/src/main_waiting.py
similarity index 65%
rename from src/_nfdos/kernel/neurotron/neurotron_main.py
rename to src/_nfdos/kernel/neurotron/src/main_waiting.py
index 7f2f6cf..784ac18 100644
--- a/src/_nfdos/kernel/neurotron/neurotron_main.py
+++ b/src/_nfdos/kernel/neurotron/src/main_waiting.py
@@ -1,43 +1,38 @@
#!/usr/bin/env python3
"""
Neurotron — ponto de entrada do “cérebro” do NFDOS.
-Boot flow: init (BusyBox) → Python → Neurotron (este ficheiro).
+Boot flow (novo): init (BusyBox) → /usr/bin/neurotron → este ficheiro.
"""
import os
import sys
-import time
-import json
-from datetime import datetime
from pathlib import Path
-from rich.console import Console
-from rich.panel import Panel
-from rich.table import Table
-from rich.pretty import pprint
-from neurotron_core import neurotron_config
-from neurotron_core.autodiagnostic import AutoDiagnostic
-from neurotron_core.perception import Perception
-from neurotron_core.neurotron_config import (
- NEUROTRON_TICK, NEUROTRON_MODE, NEUROTRON_HOMEOSTASIS,
- CORTEX_LOOP_DELAY, MOTOR_OUTPUT_DEVICE, BASE_DIR, CORE_DIR
+from datetime import datetime
+from rich.console import Console
+
+# -----------------------------------------------------------------------------
+# Ajuste de caminho: tornar "src/" o root dos módulos Neurotron
+# -----------------------------------------------------------------------------
+THIS_DIR = Path(__file__).resolve().parent # .../neurotron/src
+
+if str(THIS_DIR) not in sys.path:
+ sys.path.insert(0, str(THIS_DIR))
+
+# Agora os imports ficam locais ao diretório src/
+from neurotron_config import ( # noqa: E402
+ NEUROTRON_TICK,
+ NEUROTRON_MODE,
+ NEUROTRON_HOMEOSTASIS,
+ CORTEX_LOOP_DELAY,
+ MOTOR_OUTPUT_DEVICE,
)
+from autodiagnostic import AutoDiagnostic # noqa: E402
+from perception import Perception # noqa: E402
+from cortex import Cortex # noqa: E402
console = Console()
-# Caminho base do Neurotron
-if not CORE_DIR.exists():
- console.print(f"[red]Erro:[/] diretório esperado não encontrado: {CORE_DIR}")
- sys.exit(1)
-if str(CORE_DIR) not in sys.path:
- sys.path.insert(0, str(CORE_DIR))
-
-console.print("[cyan]🧩 Mapa Neural de Importação:[/cyan]")
-for p in sys.path:
- console.print(f" - {p}")
-
-from neurotron_core.cortex import Cortex # noqa: E402
-
def detect_persistent_mount() -> bool:
"""Verifica se o hipocampo físico está montado em /var/neurotron"""
@@ -47,7 +42,7 @@ def detect_persistent_mount() -> bool:
console.print(f"[green]💾 Hipocampo físico montado:[/] {mount_point}")
return True
else:
- # fallback: check by /proc/mounts in early boot
+ # fallback: check via /proc/mounts em early boot
with open("/proc/mounts") as f:
for line in f:
if " /var/neurotron " in line:
@@ -59,6 +54,9 @@ def detect_persistent_mount() -> bool:
def main():
+ # -------------------------------------------------------------------------
+ # Seleção de modo: persistente vs volátil
+ # -------------------------------------------------------------------------
persistent_mode = detect_persistent_mount()
if persistent_mode:
os.environ["NEUROTRON_MODE"] = "persistent"
@@ -77,8 +75,14 @@ def main():
mode = os.environ["NEUROTRON_MODE"]
console.print(f"[cyan]🌍 Modo atual do Neurotron:[/] [bold]{mode.upper()}[/]")
- # inicializa o Córtex
- cortex = Cortex(runtime_dir=runtime_dir, log_dir=log_dir, tick_seconds=NEUROTRON_TICK)
+ # -------------------------------------------------------------------------
+ # Inicializa o Córtex
+ # -------------------------------------------------------------------------
+ cortex = Cortex(
+ runtime_dir=runtime_dir,
+ log_dir=log_dir,
+ tick_seconds=NEUROTRON_TICK,
+ )
try:
cortex.boot()
@@ -108,4 +112,3 @@ def main():
if __name__ == "__main__":
main()
-
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/motor.py b/src/_nfdos/kernel/neurotron/src/motor.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/motor.py
rename to src/_nfdos/kernel/neurotron/src/motor.py
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/neuron.py b/src/_nfdos/kernel/neurotron/src/neuron.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/neuron.py
rename to src/_nfdos/kernel/neurotron/src/neuron.py
diff --git a/src/_nfdos/kernel/neurotron/src/neurotron_config.py b/src/_nfdos/kernel/neurotron/src/neurotron_config.py
new file mode 100644
index 0000000..f19f66d
--- /dev/null
+++ b/src/_nfdos/kernel/neurotron/src/neurotron_config.py
@@ -0,0 +1,118 @@
+"""
+🧠 neurotron_config.py
+NFDOS — Núcleo de parâmetros vitais do Neurotron
+------------------------------------------------
+Nova versão para o layout:
+.../neurotron/
+ ├── src/
+ └── data/
+"""
+
+from pathlib import Path
+
+# ======================================
+# 🌐 Diretórios e Caminhos
+# ======================================
+
+# Diretório deste ficheiro → .../neurotron/src/neurotron_config.py
+THIS_FILE = Path(__file__).resolve()
+SRC_DIR = THIS_FILE.parent # .../neurotron/src
+BASE_DIR = SRC_DIR.parent # .../neurotron/
+
+# Onde vivem as configs/logs da “instalação”
+DATA_DIR = BASE_DIR / "data"
+CONFIG_DIR = DATA_DIR / "configs"
+LOG_DIR = DATA_DIR / "logs"
+
+# Modo persistente do NFDOS (quando /var/neurotron está montado)
+RUNTIME_DIR = Path("/var/run/neurotron")
+MOUNT_POINT = "/var/neurotron"
+
+# Candidatos para disco persistente do hipocampo
+DISK_CANDIDATES = [
+ "/dev/vda", "/dev/vdb",
+ "/dev/sda", "/dev/hda"
+]
+
+# ======================================
+# ⚙️ Parâmetros Cognitivos Principais
+# ======================================
+
+NEUROTRON_TICK = 1.0
+NEUROTRON_VERBOSITY = 1
+NEUROTRON_MODE = "diagnostic"
+
+NEUROTRON_HOMEOSTASIS = 85.0
+
+HOMEOSTASIS_CPU_WARN = 70.0
+HOMEOSTASIS_CPU_ALERT = 85.0
+HOMEOSTASIS_MEM_WARN = 75.0
+HOMEOSTASIS_MEM_ALERT = 90.0
+HOMEOSTASIS_LOAD_WARN = 1.5
+HOMEOSTASIS_LOAD_ALERT = 3.0
+
+NEUROTRON_DIAG_EVERY_TICKS = 5
+NEUROTRON_TICK_MIN = 0.5
+NEUROTRON_TICK_MAX = 3.0
+NEUROTRON_TICK_STEP = 0.25
+
+NEUROTRON_SEED = 42
+NEUROTRON_MEMORY_SIZE = 256 # KB
+
+# ======================================
+# 🧩 Parâmetros de Subsistemas
+# ======================================
+
+CORTEX_MAX_THREADS = 1
+CORTEX_LOOP_DELAY = 0.1
+
+HIPPOCAMPUS_LOG_RETENTION = 100
+HIPPOCAMPUS_AUTOSAVE = True
+
+MOTOR_OUTPUT_DEVICE = "console"
+MOTOR_SHOW_SYMBOLS = True
+
+PERCEPTION_CPU_SOURCE = "/proc/stat"
+PERCEPTION_MEM_SOURCE = "/proc/meminfo"
+PERCEPTION_UPDATE_INTERVAL = 2.0
+
+# ======================================
+# 🧠 Parâmetros futuros
+# ======================================
+
+NEUROTRON_EXPANSION_MODE = "none"
+NEUROTRON_DATASET_PATH = DATA_DIR
+NEUROTRON_HISTORY_KEEP = 8
+
+NEUROTRON_DIAG_SCHEMA = "v4"
+
+HEARTBEAT_ENABLED = True
+HEARTBEAT_STYLE = "compact"
+
+NEUROTRON_THRESHOLDS = {
+ "cpu_high": 85.0,
+ "mem_high": 90.0,
+ "load1_high": 2.0,
+}
+
+TELEMETRY_MAXLEN = 64
+TELEMETRY_FLUSH_EVERY_TICKS = 5
+
+# ======================================
+# 🧭 Utilitário
+# ======================================
+
+def show_config():
+ """Mostra a configuração atual do Neurotron (apenas NEUROTRON_*)"""
+ import json
+ cfg = {
+ k: v
+ for k, v in globals().items()
+ if k.startswith("NEUROTRON_")
+ }
+ print(json.dumps(cfg, indent=2, default=str))
+
+
+if __name__ == "__main__":
+ show_config()
+
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/perception.py b/src/_nfdos/kernel/neurotron/src/perception.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/perception.py
rename to src/_nfdos/kernel/neurotron/src/perception.py
diff --git a/src/_nfdos/kernel/neurotron/neurotron_core/telemetry_tail.py b/src/_nfdos/kernel/neurotron/src/telemetry_tail.py
similarity index 100%
rename from src/_nfdos/kernel/neurotron/neurotron_core/telemetry_tail.py
rename to src/_nfdos/kernel/neurotron/src/telemetry_tail.py
diff --git a/src/_nfdos/rootfs/init b/src/_nfdos/rootfs/init
index 5f05f9e..27c6ccd 100755
--- a/src/_nfdos/rootfs/init
+++ b/src/_nfdos/rootfs/init
@@ -4,6 +4,7 @@ mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devtmpfs devtmpfs /dev
+# o if falha propositalmente. apenas mantive para "backup" enquanto estamos a migrar
if [ -f /opt/kernel/neurotron/neurotron_main.py ]; then
export PYTHONHOME=/usr
export PYTHONPATH=/usr/lib/python3.13:/usr/lib/python3.13/site-packages
@@ -20,7 +21,14 @@ if [ -f /opt/kernel/neurotron/neurotron_main.py ]; then
echo '👉 Inicializando Painel de Telemetria do Neurotron...'
/usr/bin/python3 /opt/kernel/neurotron/neurotron_core/telemetry_tail.py
else
- echo '⚙️ BusyBox ativo — Neurotron ausente.'
+ echo '⚙️ BusyBox ativo — Neurotron em migracao...'
fi
+export PYTHONHOME=/usr
+export PYTHONPATH=/usr/lib/python3.13:/usr/lib/python3.13/site-packages
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+echo "[BOOT] NFDOS kernel Neurotron"
+exec /usr/bin/neurotron || echo "⚠️ Falha ao iniciar o kernel Neurotron"
+
exec /bin/sh
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/neurotron_config.py b/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/neurotron_config.py
deleted file mode 100644
index 660d925..0000000
--- a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/neurotron_config.py
+++ /dev/null
@@ -1,124 +0,0 @@
-"""
-🧠 neurotron_config.py
-NFDOS — Núcleo de parâmetros vitais do Neurotron
-------------------------------------------------
-Este ficheiro centraliza todos os ajustes simbólicos e técnicos
-do ciclo cognitivo do Neurotron.
-
-Versão: 0.1 (Nascimento)
-"""
-
-from pathlib import Path
-
-# ======================================
-# 🌐 Diretórios e Caminhos
-# ======================================
-
-BASE_DIR = Path(__file__).resolve().parents[1] # /opt/kernel/neurotron/
-CORE_DIR = BASE_DIR / "neurotron_core"
-LOG_DIR = Path("/var/log/neurotron") # pode não existir ainda no rootfs
-RUNTIME_DIR = Path("/var/run/neurotron")
-MOUNT_POINT = "/var/neurotron"
-DISK_CANDIDATES = ["/dev/vda", "/dev/vdb", "/dev/sda", "/dev/hda"]
-
-# ======================================
-# ⚙️ Parâmetros Cognitivos Principais
-# ======================================
-
-# Tempo entre ciclos cognitivos (em segundos)
-NEUROTRON_TICK = 1.0
-
-# Verbosidade dos logs (0 = silêncio, 1 = normal, 2 = debug)
-NEUROTRON_VERBOSITY = 1
-
-# Modo de operação
-# - diagnostic: executa verificações de integridade
-# - learning: ativa ciclos adaptativos (tree, etc.)
-# - simulation: executa comportamento contínuo de observação
-NEUROTRON_MODE = "diagnostic"
-
-# Limite de homeostase (auto-regulação)
-# Se CPU ou memória ultrapassarem este valor (%), o sistema reduz ritmo
-NEUROTRON_HOMEOSTASIS = 85.0
-
-HOMEOSTASIS_CPU_WARN = 70.0 # %
-HOMEOSTASIS_CPU_ALERT = 85.0 # %
-HOMEOSTASIS_MEM_WARN = 75.0 # %
-HOMEOSTASIS_MEM_ALERT = 90.0 # %
-HOMEOSTASIS_LOAD_WARN = 1.5 # média 1-min (ajuste ao teu core single/SMT)
-HOMEOSTASIS_LOAD_ALERT = 3.0
-
-NEUROTRON_DIAG_EVERY_TICKS = 5 # a cada N ciclos cognitivos, reavaliar sinais vitais
-NEUROTRON_TICK_MIN = 0.5
-NEUROTRON_TICK_MAX = 3.0
-NEUROTRON_TICK_STEP = 0.25
-
-# Entropia (seed) para gerar comportamentos pseudoaleatórios
-NEUROTRON_SEED = 42
-
-# Tamanho máximo da memória do Hipocampo (em KB)
-NEUROTRON_MEMORY_SIZE = 256 # define quando o sistema começa a "esquecer"
-
-# ======================================
-# 🧩 Parâmetros de Subsistemas
-# ======================================
-
-# Cortex — núcleo de decisão
-CORTEX_MAX_THREADS = 1 # threads de raciocínio simultâneo
-CORTEX_LOOP_DELAY = 0.1 # tempo entre ciclos internos
-
-# Hippocampus — memória
-HIPPOCAMPUS_LOG_RETENTION = 100 # número máximo de logs guardados
-HIPPOCAMPUS_AUTOSAVE = True # ativa auto-gravação entre ciclos
-
-# Motor — saída / ação
-MOTOR_OUTPUT_DEVICE = "console" # destino: console, log, cloud (futuro)
-MOTOR_SHOW_SYMBOLS = True # exibe símbolos (🧠, ⚙️, etc.)
-
-# Perception — sensores
-PERCEPTION_CPU_SOURCE = "/proc/stat"
-PERCEPTION_MEM_SOURCE = "/proc/meminfo"
-PERCEPTION_UPDATE_INTERVAL = 2.0 # segundos entre medições
-
-# ======================================
-# 🧠 Parâmetros Futuros (placeholders)
-# ======================================
-
-# Modo de expansão (para versões futuras)
-# "none", "networked", "distributed"
-NEUROTRON_EXPANSION_MODE = "none"
-
-# Caminho do dataset local (para aprendizagem offline)
-NEUROTRON_DATASET_PATH = BASE_DIR / "data"
-NEUROTRON_HISTORY_KEEP = 8 # manter últimas N entradas no ficheiro
-
-# Identificador de schema para upgrades
-NEUROTRON_DIAG_SCHEMA = "v4"
-
-# --- Telemetria e Heartbeat (V5) ---
-HEARTBEAT_ENABLED = True # Mostrar batimento a cada tick
-HEARTBEAT_STYLE = "compact" # "compact" ou "verbose"
-
-# Limiares de microalertas (homeostase)
-NEUROTRON_THRESHOLDS = {
- "cpu_high": 85.0, # %
- "mem_high": 90.0, # %
- "load1_high": 2.0, # load avg(1min)
-}
-
-# Buffer de telemetria em memória e flush periódico
-TELEMETRY_MAXLEN = 64
-TELEMETRY_FLUSH_EVERY_TICKS = 5 # de tempos a tempos, gravar em JSON
-
-# ======================================
-# 🧭 Utilitário: impressão de parâmetros
-# ======================================
-
-def show_config():
- """Mostra a configuração atual do Neurotron"""
- import json
- cfg = {k: v for k, v in globals().items() if k.startswith("NEUROTRON_")}
- print(json.dumps(cfg, indent=2, default=str))
-
-if __name__ == "__main__":
- show_config()
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/src/__init__.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/src/__main__.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/__main__.py
new file mode 100644
index 0000000..74276c0
--- /dev/null
+++ b/src/_nfdos/rootfs/opt/kernel/neurotron/src/__main__.py
@@ -0,0 +1,449 @@
+#!/usr/bin/env python3
+"""
+Neurotron — Dashboard em modo texto (estilo BIOS)
+
+Ponto de entrada quando executado como:
+
+ python3 -m neurotron
+
+ou via wrapper /usr/bin/neurotron gerado pelo autotools.
+
+Layout:
+
++------------------------------------------------------------------------------+
+| [HEAD] CPU / MEM / LOAD / UPTIME / MODO / VERSÃO / DIAG |
++------------------------------------------------------------------------------+
+| [LOG] Últimos eventos do ciclo cognitivo (observe/think/act/rest, etc.) |
+| ... |
++------------------------------------------------------------------------------+
+| [FOOT] Futuro: input do utilizador (placeholder) | teclas: q = sair |
++------------------------------------------------------------------------------+
+"""
+
+import curses
+import threading
+import time
+import os
+import sys
+from pathlib import Path
+from queue import Queue, Empty
+from datetime import datetime
+
+# Imports internos do Neurotron (já reorganizados em package)
+from .neurotron_config import (
+ NEUROTRON_TICK,
+ NEUROTRON_MODE,
+ NEUROTRON_HOMEOSTASIS,
+ NEUROTRON_THRESHOLDS,
+)
+from .cortex import Cortex
+from .autodiagnostic import AutoDiagnostic # se for usado dentro do Cortex, ok mesmo assim
+
+
+# =======================================================================================
+# Utilitários de ambiente
+# =======================================================================================
+
+def detect_persistent_mode():
+ """
+ Verifica se o hipocampo físico está montado em /var/neurotron.
+ Define NEUROTRON_MODE, NEUROTRON_RUNTIME e NEUROTRON_LOG via os.environ.
+ """
+ mount_point = Path("/var/neurotron")
+
+ def _mounted(mp: Path) -> bool:
+ try:
+ if mp.exists() and os.path.ismount(mp):
+ return True
+ with open("/proc/mounts") as f:
+ for line in f:
+ if f" {mp} " in line:
+ return True
+ except Exception:
+ return False
+ return False
+
+ if _mounted(mount_point):
+ os.environ["NEUROTRON_MODE"] = "persistent"
+ os.environ["NEUROTRON_RUNTIME"] = "/var/neurotron/data"
+ os.environ["NEUROTRON_LOG"] = "/var/neurotron/logs"
+ else:
+ os.environ["NEUROTRON_MODE"] = "volatile"
+ os.environ["NEUROTRON_RUNTIME"] = "/tmp/neurotron_data"
+ os.environ["NEUROTRON_LOG"] = "/tmp/neurotron_logs"
+
+ runtime_dir = Path(os.environ["NEUROTRON_RUNTIME"])
+ log_dir = Path(os.environ["NEUROTRON_LOG"])
+ runtime_dir.mkdir(parents=True, exist_ok=True)
+ log_dir.mkdir(parents=True, exist_ok=True)
+ return runtime_dir, log_dir
+
+
+def read_system_metrics():
+ """
+ Lê CPU, memória e loadavg a partir de /proc.
+ Retorna dicionário:
+ {
+ "cpu": float,
+ "mem": float,
+ "load1": float,
+ "load5": float,
+ "load15": float,
+ }
+ Em caso de falha, devolve valores -1.
+ """
+ cpu = -1.0
+ mem = -1.0
+ load1 = load5 = load15 = -1.0
+
+ # CPU (uso aproximado entre duas leituras de /proc/stat)
+ try:
+ with open("/proc/stat") as f:
+ line = f.readline()
+ parts = line.strip().split()
+ if parts[0] == "cpu" and len(parts) >= 5:
+ user, nice, system_, idle = map(int, parts[1:5])
+ total1 = user + nice + system_ + idle
+ idle1 = idle
+ time.sleep(0.05) # pequena janela
+ with open("/proc/stat") as f:
+ line = f.readline()
+ parts = line.strip().split()
+ user2, nice2, system2, idle2 = map(int, parts[1:5])
+ total2 = user2 + nice2 + system2 + idle2
+ idle2 = idle2
+ total_delta = total2 - total1
+ idle_delta = idle2 - idle1
+ if total_delta > 0:
+ cpu = 100.0 * (1.0 - (idle_delta / total_delta))
+ except Exception:
+ pass
+
+ # Memória
+ try:
+ meminfo = {}
+ with open("/proc/meminfo") as f:
+ for line in f:
+ k, v = line.split(":", 1)
+ meminfo[k.strip()] = v.strip()
+ total_kb = float(meminfo.get("MemTotal", "0 kB").split()[0])
+ free_kb = float(meminfo.get("MemAvailable", "0 kB").split()[0])
+ if total_kb > 0:
+ used_kb = total_kb - free_kb
+ mem = 100.0 * (used_kb / total_kb)
+ except Exception:
+ pass
+
+ # Loadavg
+ try:
+ with open("/proc/loadavg") as f:
+ l1, l5, l15, *_ = f.read().split()
+ load1 = float(l1)
+ load5 = float(l5)
+ load15 = float(l15)
+ except Exception:
+ pass
+
+ return {
+ "cpu": cpu,
+ "mem": mem,
+ "load1": load1,
+ "load5": load5,
+ "load15": load15,
+ }
+
+
+# =======================================================================================
+# Dashboard em curses
+# =======================================================================================
+
+class NeurotronDashboard:
+ """
+ UI fixa em curses:
+ - header: métricas de sistema + estado do Neurotron
+ - middle: log rolling
+ - footer: placeholder + ajuda/teclas
+ """
+
+ def __init__(self, stdscr, log_queue: Queue, cortex: Cortex, start_time: float):
+ self.stdscr = stdscr
+ self.log_queue = log_queue
+ self.cortex = cortex
+ self.start_time = start_time
+
+ self.log_lines = [] # mantém histórico para a janela central
+ self.max_log_lines = 1000
+
+ self.stop_event = threading.Event()
+ self.last_diag_state = "?"
+ self.last_diag_delta = "?"
+
+ # tenta obter diagnóstico inicial, se existir
+ try:
+ diag = self.cortex.diagnostic._load_previous()
+ self.last_diag_state = diag.get("state", "?")
+ self.last_diag_delta = diag.get("delta", "?")
+ except Exception:
+ pass
+
+ # ------------------------------------------------------------------
+ # Helpers de desenho
+ # ------------------------------------------------------------------
+
+ def _draw_header(self, height, width):
+ """Desenha a barra superior com CPU/MEM/LOAD/UPTIME/MODO/DIAG."""
+ metrics = read_system_metrics()
+ now = time.time()
+ uptime_sec = int(now - self.start_time)
+
+ hours = uptime_sec // 3600
+ mins = (uptime_sec % 3600) // 60
+ secs = uptime_sec % 60
+
+ mode = os.environ.get("NEUROTRON_MODE", NEUROTRON_MODE)
+ version = getattr(self.cortex, "version", "0.1")
+
+ cpu = metrics["cpu"]
+ mem = metrics["mem"]
+ load1 = metrics["load1"]
+
+ # Avalia homeostase
+ warn_cpu = NEUROTRON_THRESHOLDS.get("cpu_high", 85.0)
+ warn_mem = NEUROTRON_THRESHOLDS.get("mem_high", 90.0)
+ warn_load = NEUROTRON_THRESHOLDS.get("load1_high", 2.0)
+
+ status_parts = []
+
+ if cpu >= 0:
+ status_parts.append(f"CPU: {cpu:5.1f}%")
+ else:
+ status_parts.append("CPU: N/A ")
+
+ if mem >= 0:
+ status_parts.append(f"MEM: {mem:5.1f}%")
+ else:
+ status_parts.append("MEM: N/A ")
+
+ if load1 >= 0:
+ status_parts.append(f"LOAD1: {load1:4.2f}")
+ else:
+ status_parts.append("LOAD1: N/A ")
+
+ status_parts.append(f"UP: {hours:02d}:{mins:02d}:{secs:02d}")
+ status_parts.append(f"MODO: {mode.upper()}")
+ status_parts.append(f"VER: {version}")
+ status_parts.append(f"DIAG: {self.last_diag_state}/{self.last_diag_delta}")
+
+ line = " ".join(status_parts)
+
+ # barra horizontal
+ self.stdscr.attron(curses.A_REVERSE)
+ self.stdscr.addnstr(0, 0, line.ljust(width), width)
+ self.stdscr.attroff(curses.A_REVERSE)
+
+ # segunda linha: homeostase textual
+ homeo_msg = "HOMEOSTASE: OK"
+ if (cpu >= warn_cpu and cpu >= 0) or (mem >= warn_mem and mem >= 0) or (
+ load1 >= warn_load and load1 >= 0
+ ):
+ homeo_msg = "HOMEOSTASE: STRESS"
+
+ self.stdscr.addnstr(1, 0, homeo_msg.ljust(width), width)
+
+ def _drain_log_queue(self):
+ """Move mensagens da queue para o buffer de linhas."""
+ try:
+ while True:
+ msg = self.log_queue.get_nowait()
+ timestamp = datetime.now().strftime("%H:%M:%S")
+ self.log_lines.append(f"[{timestamp}] {msg}")
+ if len(self.log_lines) > self.max_log_lines:
+ self.log_lines = self.log_lines[-self.max_log_lines:]
+ except Empty:
+ pass
+
+ def _draw_log_window(self, header_height, footer_height, width, height):
+ """
+ Área central de logs: rolagem automática, sempre mostrando as últimas N linhas
+ que cabem na janela.
+ """
+ top = header_height
+ bottom = height - footer_height
+ rows = max(0, bottom - top)
+
+ self._drain_log_queue()
+
+ # seleciona as últimas 'rows' linhas
+ visible = self.log_lines[-rows:] if rows > 0 else []
+
+ for i in range(rows):
+ y = top + i
+ if i < len(visible):
+ line = visible[i]
+ self.stdscr.addnstr(y, 0, line.ljust(width), width)
+ else:
+ self.stdscr.addnstr(y, 0, " ".ljust(width), width)
+
+ def _draw_footer(self, width, height):
+ """
+ Rodapé com placeholder para input futuro e legenda de teclas.
+ """
+ footer_text = "[ Futuro: comandos do utilizador aparecerão aqui ]"
+ keys_text = "[q] sair | dashboard Neurotron"
+
+ y_footer = height - 2
+ self.stdscr.addnstr(y_footer, 0, footer_text.ljust(width), width)
+ self.stdscr.addnstr(y_footer + 1, 0, keys_text.ljust(width), width)
+
+ # ------------------------------------------------------------------
+ # Loop principal da UI
+ # ------------------------------------------------------------------
+
+ def run(self):
+ """
+ Loop principal do curses.
+ Actualiza o ecrã, lê teclas, e encerra quando stop_event é setado ou 'q' é pressionado.
+ """
+ curses.curs_set(0)
+ self.stdscr.nodelay(True)
+ self.stdscr.keypad(True)
+
+ while not self.stop_event.is_set():
+ height, width = self.stdscr.getmaxyx()
+ self.stdscr.erase()
+
+ header_height = 2
+ footer_height = 2
+
+ self._draw_header(height, width)
+ self._draw_log_window(header_height, footer_height, width, height)
+ self._draw_footer(width, height)
+
+ self.stdscr.refresh()
+
+ try:
+ ch = self.stdscr.getch()
+ if ch in (ord("q"), ord("Q")):
+ self.stop_event.set()
+ break
+ except Exception:
+ pass
+
+ time.sleep(0.1) # ~10 FPS
+
+ # tentativa graciosa de shutdown do Cortex
+ try:
+ self.log_queue.put("Encerrando Neurotron (dashboard pediu saída)…")
+ self.cortex.shutdown(reason="Dashboard exit")
+ except Exception:
+ pass
+
+
+# =======================================================================================
+# Ciclo Cognitivo em thread separada
+# =======================================================================================
+
+def cognitive_loop(cortex: Cortex, ui: NeurotronDashboard):
+ """
+ Loop cognitivo clássico (observe → think → act → rest),
+ a correr numa thread separada, reportando eventos para o dashboard via log_queue.
+ """
+ log = ui.log_queue.put
+
+ try:
+ log("Neurotron: boot()…")
+ cortex.boot()
+ try:
+ state = cortex.diagnostic._load_previous().get("state", "?")
+ log(f"Diagnóstico inicial: estado='{state}'")
+ ui.last_diag_state = state
+ except Exception:
+ log("Diagnóstico inicial: indisponível")
+
+ log("Ciclo cognitivo iniciado (observe → think → act → rest)…")
+
+ while not ui.stop_event.is_set():
+ try:
+ log("cortex.observe()")
+ cortex.observe()
+
+ log("cortex.think()")
+ cortex.think()
+
+ log("cortex.act()")
+ cortex.act()
+
+ log("cortex.rest()")
+ cortex.rest()
+
+ except KeyboardInterrupt:
+ log("Interrompido pelo utilizador (SIGINT)")
+ cortex.shutdown(reason="SIGINT")
+ break
+ except SystemExit:
+ log("SystemExit recebido, encerrando…")
+ cortex.shutdown(reason="SystemExit")
+ break
+ except Exception as e:
+ log(f"💥 Exceção não tratada no loop cognitivo: {e}")
+ try:
+ cortex.fatal(e)
+ finally:
+ break
+
+ finally:
+ ui.stop_event.set()
+ log("Loop cognitivo terminado.")
+
+
+# =======================================================================================
+# Entry point
+# =======================================================================================
+
+def _main_curses(stdscr):
+ # 1) Detecta modo e diretórios
+ runtime_dir, log_dir = detect_persistent_mode()
+
+ # 2) Inicializa Cortex com os mesmos parâmetros do main_waiting
+ cortex = Cortex(
+ runtime_dir=runtime_dir,
+ log_dir=log_dir,
+ tick_seconds=NEUROTRON_TICK,
+ )
+
+ # 3) Queue de logs e dashboard
+ log_queue: Queue = Queue()
+ start_time = time.time()
+ ui = NeurotronDashboard(stdscr, log_queue, cortex, start_time)
+
+ # 4) Thread do ciclo cognitivo
+ worker = threading.Thread(
+ target=cognitive_loop,
+ args=(cortex, ui),
+ daemon=True,
+ )
+ worker.start()
+
+ # 5) Loop da UI (bloqueia até terminar)
+ ui.run()
+
+ # 6) Aguarda thread terminar
+ worker.join(timeout=2.0)
+
+
+def main():
+ """
+ Ponto de entrada Python. Usado tanto por:
+
+ python3 -m neurotron
+
+ como pelo wrapper /usr/bin/neurotron, se este fizer:
+
+ from neurotron import main
+ main()
+ """
+ curses.wrapper(_main_curses)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/autodiagnostic.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/autodiagnostic.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/autodiagnostic.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/autodiagnostic.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/cortex.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/cortex.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/cortex.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/cortex.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/disk_init.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/disk_init.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/disk_init.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/disk_init.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/hippocampus.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/hippocampus.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/hippocampus.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/hippocampus.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_main.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/main_waiting.py
similarity index 65%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_main.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/main_waiting.py
index 7f2f6cf..784ac18 100644
--- a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_main.py
+++ b/src/_nfdos/rootfs/opt/kernel/neurotron/src/main_waiting.py
@@ -1,43 +1,38 @@
#!/usr/bin/env python3
"""
Neurotron — ponto de entrada do “cérebro” do NFDOS.
-Boot flow: init (BusyBox) → Python → Neurotron (este ficheiro).
+Boot flow (novo): init (BusyBox) → /usr/bin/neurotron → este ficheiro.
"""
import os
import sys
-import time
-import json
-from datetime import datetime
from pathlib import Path
-from rich.console import Console
-from rich.panel import Panel
-from rich.table import Table
-from rich.pretty import pprint
-from neurotron_core import neurotron_config
-from neurotron_core.autodiagnostic import AutoDiagnostic
-from neurotron_core.perception import Perception
-from neurotron_core.neurotron_config import (
- NEUROTRON_TICK, NEUROTRON_MODE, NEUROTRON_HOMEOSTASIS,
- CORTEX_LOOP_DELAY, MOTOR_OUTPUT_DEVICE, BASE_DIR, CORE_DIR
+from datetime import datetime
+from rich.console import Console
+
+# -----------------------------------------------------------------------------
+# Ajuste de caminho: tornar "src/" o root dos módulos Neurotron
+# -----------------------------------------------------------------------------
+THIS_DIR = Path(__file__).resolve().parent # .../neurotron/src
+
+if str(THIS_DIR) not in sys.path:
+ sys.path.insert(0, str(THIS_DIR))
+
+# Agora os imports ficam locais ao diretório src/
+from neurotron_config import ( # noqa: E402
+ NEUROTRON_TICK,
+ NEUROTRON_MODE,
+ NEUROTRON_HOMEOSTASIS,
+ CORTEX_LOOP_DELAY,
+ MOTOR_OUTPUT_DEVICE,
)
+from autodiagnostic import AutoDiagnostic # noqa: E402
+from perception import Perception # noqa: E402
+from cortex import Cortex # noqa: E402
console = Console()
-# Caminho base do Neurotron
-if not CORE_DIR.exists():
- console.print(f"[red]Erro:[/] diretório esperado não encontrado: {CORE_DIR}")
- sys.exit(1)
-if str(CORE_DIR) not in sys.path:
- sys.path.insert(0, str(CORE_DIR))
-
-console.print("[cyan]🧩 Mapa Neural de Importação:[/cyan]")
-for p in sys.path:
- console.print(f" - {p}")
-
-from neurotron_core.cortex import Cortex # noqa: E402
-
def detect_persistent_mount() -> bool:
"""Verifica se o hipocampo físico está montado em /var/neurotron"""
@@ -47,7 +42,7 @@ def detect_persistent_mount() -> bool:
console.print(f"[green]💾 Hipocampo físico montado:[/] {mount_point}")
return True
else:
- # fallback: check by /proc/mounts in early boot
+ # fallback: check via /proc/mounts em early boot
with open("/proc/mounts") as f:
for line in f:
if " /var/neurotron " in line:
@@ -59,6 +54,9 @@ def detect_persistent_mount() -> bool:
def main():
+ # -------------------------------------------------------------------------
+ # Seleção de modo: persistente vs volátil
+ # -------------------------------------------------------------------------
persistent_mode = detect_persistent_mount()
if persistent_mode:
os.environ["NEUROTRON_MODE"] = "persistent"
@@ -77,8 +75,14 @@ def main():
mode = os.environ["NEUROTRON_MODE"]
console.print(f"[cyan]🌍 Modo atual do Neurotron:[/] [bold]{mode.upper()}[/]")
- # inicializa o Córtex
- cortex = Cortex(runtime_dir=runtime_dir, log_dir=log_dir, tick_seconds=NEUROTRON_TICK)
+ # -------------------------------------------------------------------------
+ # Inicializa o Córtex
+ # -------------------------------------------------------------------------
+ cortex = Cortex(
+ runtime_dir=runtime_dir,
+ log_dir=log_dir,
+ tick_seconds=NEUROTRON_TICK,
+ )
try:
cortex.boot()
@@ -108,4 +112,3 @@ def main():
if __name__ == "__main__":
main()
-
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/motor.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/motor.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/motor.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/motor.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/neuron.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/neuron.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/neuron.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/neuron.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/src/neurotron_config.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/neurotron_config.py
new file mode 100644
index 0000000..f19f66d
--- /dev/null
+++ b/src/_nfdos/rootfs/opt/kernel/neurotron/src/neurotron_config.py
@@ -0,0 +1,118 @@
+"""
+🧠 neurotron_config.py
+NFDOS — Núcleo de parâmetros vitais do Neurotron
+------------------------------------------------
+Nova versão para o layout:
+.../neurotron/
+ ├── src/
+ └── data/
+"""
+
+from pathlib import Path
+
+# ======================================
+# 🌐 Diretórios e Caminhos
+# ======================================
+
+# Diretório deste ficheiro → .../neurotron/src/neurotron_config.py
+THIS_FILE = Path(__file__).resolve()
+SRC_DIR = THIS_FILE.parent # .../neurotron/src
+BASE_DIR = SRC_DIR.parent # .../neurotron/
+
+# Onde vivem as configs/logs da “instalação”
+DATA_DIR = BASE_DIR / "data"
+CONFIG_DIR = DATA_DIR / "configs"
+LOG_DIR = DATA_DIR / "logs"
+
+# Modo persistente do NFDOS (quando /var/neurotron está montado)
+RUNTIME_DIR = Path("/var/run/neurotron")
+MOUNT_POINT = "/var/neurotron"
+
+# Candidatos para disco persistente do hipocampo
+DISK_CANDIDATES = [
+ "/dev/vda", "/dev/vdb",
+ "/dev/sda", "/dev/hda"
+]
+
+# ======================================
+# ⚙️ Parâmetros Cognitivos Principais
+# ======================================
+
+NEUROTRON_TICK = 1.0
+NEUROTRON_VERBOSITY = 1
+NEUROTRON_MODE = "diagnostic"
+
+NEUROTRON_HOMEOSTASIS = 85.0
+
+HOMEOSTASIS_CPU_WARN = 70.0
+HOMEOSTASIS_CPU_ALERT = 85.0
+HOMEOSTASIS_MEM_WARN = 75.0
+HOMEOSTASIS_MEM_ALERT = 90.0
+HOMEOSTASIS_LOAD_WARN = 1.5
+HOMEOSTASIS_LOAD_ALERT = 3.0
+
+NEUROTRON_DIAG_EVERY_TICKS = 5
+NEUROTRON_TICK_MIN = 0.5
+NEUROTRON_TICK_MAX = 3.0
+NEUROTRON_TICK_STEP = 0.25
+
+NEUROTRON_SEED = 42
+NEUROTRON_MEMORY_SIZE = 256 # KB
+
+# ======================================
+# 🧩 Parâmetros de Subsistemas
+# ======================================
+
+CORTEX_MAX_THREADS = 1
+CORTEX_LOOP_DELAY = 0.1
+
+HIPPOCAMPUS_LOG_RETENTION = 100
+HIPPOCAMPUS_AUTOSAVE = True
+
+MOTOR_OUTPUT_DEVICE = "console"
+MOTOR_SHOW_SYMBOLS = True
+
+PERCEPTION_CPU_SOURCE = "/proc/stat"
+PERCEPTION_MEM_SOURCE = "/proc/meminfo"
+PERCEPTION_UPDATE_INTERVAL = 2.0
+
+# ======================================
+# 🧠 Parâmetros futuros
+# ======================================
+
+NEUROTRON_EXPANSION_MODE = "none"
+NEUROTRON_DATASET_PATH = DATA_DIR
+NEUROTRON_HISTORY_KEEP = 8
+
+NEUROTRON_DIAG_SCHEMA = "v4"
+
+HEARTBEAT_ENABLED = True
+HEARTBEAT_STYLE = "compact"
+
+NEUROTRON_THRESHOLDS = {
+ "cpu_high": 85.0,
+ "mem_high": 90.0,
+ "load1_high": 2.0,
+}
+
+TELEMETRY_MAXLEN = 64
+TELEMETRY_FLUSH_EVERY_TICKS = 5
+
+# ======================================
+# 🧭 Utilitário
+# ======================================
+
+def show_config():
+ """Mostra a configuração atual do Neurotron (apenas NEUROTRON_*)"""
+ import json
+ cfg = {
+ k: v
+ for k, v in globals().items()
+ if k.startswith("NEUROTRON_")
+ }
+ print(json.dumps(cfg, indent=2, default=str))
+
+
+if __name__ == "__main__":
+ show_config()
+
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/perception.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/perception.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/perception.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/perception.py
diff --git a/src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/telemetry_tail.py b/src/_nfdos/rootfs/opt/kernel/neurotron/src/telemetry_tail.py
similarity index 100%
rename from src/_nfdos/rootfs/opt/kernel/neurotron/neurotron_core/telemetry_tail.py
rename to src/_nfdos/rootfs/opt/kernel/neurotron/src/telemetry_tail.py
diff --git a/src/_nfdos/rootfs/usr/bin/neurotron b/src/_nfdos/rootfs/usr/bin/neurotron
new file mode 100755
index 0000000..e3cff04
--- /dev/null
+++ b/src/_nfdos/rootfs/usr/bin/neurotron
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Neurotron launcher - autogerado pelo autotools
+
+NEUROTRON_HOME="/usr/lib/neurotron"
+PYTHON="/usr/bin/python"
+
+exec "$PYTHON" "$NEUROTRON_HOME/src/__main__.py" "$@"
diff --git a/src/nfdos b/src/nfdos
index 6d1e797..2381cb1 100755
--- a/src/nfdos
+++ b/src/nfdos
@@ -6,6 +6,6 @@ sys.path.insert(1, '/usr/local/local/lib/python3.12/dist-packages')
from bootstrap import Application
if __name__ == "__main__":
- app = Application(package="nfdos", version="0.1")
+ app = Application(package="nfdos", version="5281bb3-dirty")
app.run()
diff --git a/src/site/404.html b/src/site/404.html
index a5b8707..94e5500 100644
--- a/src/site/404.html
+++ b/src/site/404.html
@@ -11,8 +11,11 @@
+
+
+
-
+
@@ -20,7 +23,7 @@
-
+
@@ -45,7 +48,6 @@
-
@@ -190,10 +192,15 @@
+
+
Home
+
+
+
@@ -226,6 +233,7 @@
+
404 - Not found
@@ -265,10 +273,11 @@
-
+
+
-
+