Síntoma: el screenshot del usuario en la VPS Hetzner mostraba systemd
booteando y se quedaba congelado en el último printk del kernel justo
antes del switch-root. arje-zero arrancaba bien pero su salida iba al
serial invisible.
Causa: el cmdline traía `console=tty1 console=ttyS0,115200` — y el
kernel hace que `/dev/console` apunte al ÚLTIMO `console=`, así toda la
salida de stdout/stderr de arje-zero (tracing + banner de la rescue
shell) caía en ttyS0 (serial), no en la VGA que muestra noVNC.
Dos arreglos:
- Orden de consolas invertido en el menuentry → `/dev/console` = tty1
(lo que efectivamente se ve en la consola web del proveedor).
- arje-zero también escribe a `/dev/kmsg` (ring buffer del kernel), que
el kernel hace eco a TODAS las consolas registradas — el mecanismo
que usa systemd para que sus mensajes salgan tanto en VGA como en
serial. Defense in depth: el banner de rescue y un eco temprano
«despierta como PID 1» aparecen sí o sí en cualquier consola.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diagnóstico: en el VPS Fedora arje-zero caía como PID 1 y el cmdline
traía `panic=10`, así que el kernel rebooteaba cada 10 s. Tres causas
encadenadas, todas arregladas:
1) **Cmdline `ro` + sin `/run` tmpfs.** El menuentry montaba `/` como
sólo lectura (systemd lo remonta rw temprano; arje no). Sin eso, el
socket del bus interno se intenta crear sobre un FS de sólo lectura
y falla con EROFS → spawn_bus devuelve Err → PID 1 sale → kernel
panic. arje-kernel ahora remonta `/` rw en el bootstrap y monta
`/run`, `/tmp`, `/dev/pts`, `/dev/shm` como tmpfs — superficies
escribibles aunque la raíz quede ro.
2) **PID 1 saliendo en cualquier `?`.** Doctrina dura nueva: PID 1
NUNCA puede salir. Cualquier error de arranque ahora cae a una
`emergency_shell()` que imprime el diagnóstico en `/dev/console`,
abre `/bin/sh` y, si la shell muere, la reabre — así el operador
puede reparar en vez de mirar la máquina reiniciarse en bucle.
3) **El script no conocía grub2 (Fedora).** `install-arje-as-init.sh`
sólo probaba `update-grub` (Debian) y `grub-mkconfig` (Arch). Ahora
detecta `grub2-mkconfig` y resuelve el `grub.cfg` correcto
(UEFI/BIOS, fedora/redhat/centos/almalinux/rocky). El menuentry
también pasa de `ro` a `rw` — el remount es belt-and-suspenders.
Mismo arreglo en `uninstall-arje.sh`.
Renaser intacto: estos cambios son Linux-side puro (arje-kernel y
arje-zero usan nix/libc/tracing); renaser sólo comparte mirada-layout y
formato, ninguno tocado.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Nuevo crate `crates/init/arje-absorb`: lee la configuración de un init
clásico y la traduce a una Tarjeta Semilla (Card JSON) con cada
servicio como hija genesis de arje-zero. El paso «absorber» de la
migración a arje — para no perder los servicios al cambiar de init.
- Absorbers: sysvinit (/etc/inittab), runit (runsvdir o /etc/sv),
dinit (/etc/dinit.d), openrc (/etc/runlevels). Autodetección.
- Modelo intermedio ForeignService → Card vía brahman-card (validado).
- `--with-carmen`: agrega carmen-dm (gestor de login gráfico).
- CLI: --from/--root/--output/--label/--with-carmen. 24 tests, clippy
limpio.
`scripts/migrate-to-arje.sh`: orquesta absorber → validar → (carmen:
compila+instala mirada dinámico) → install-arje-as-init.sh. El init
viejo queda intacto; arje se elige en GRUB. --dry-run no toca nada.
systemd no se absorbe (units no son texto trivial) — para systemd
sigue la capa de shims + seeds/arje-host.card.json.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Dos ChildPreExec nuevos en el hook declarativo pre-execve:
- MountOverlay { target, options } — monta OverlayFS (capa base RO +
capa de sesión RW + workdir).
- PivotRoot { new_root, put_old, old_root_after } — bind-mount de
new_root sobre sí mismo + pivot_root + chdir("/") + umount2 lazy
(MNT_DETACH) del root viejo.
Builders ergonómicos en ChildSetup:
- with_overlay(lower, upper, work, merged)
- with_pivot_root(new_root, put_old_name)
Ambas ops corren en el hijo post-clone, dentro del mount namespace,
async-signal-safe (solo libc, sin allocator). Las consumirán mirada
(compositor Wayland) y matilda Ghost para rootfs aislados.
19 tests arje-incarnate verdes (3 nuevos: builders overlay/pivot).
cargo check --workspace verde. Pendiente: integration test en entorno
con namespaces reales.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Errores detectados al auditar afirmaciones técnicas contra el código:
1. minga-vfs: NO está relacionado con Mónadas (esas son de akasha).
Es FUSE que proyecta el índice de minga (git semántico) como
filesystem, resolviendo paths virtuales a blobs por hash.
2. protocol/SDD.md: Card tiene 19 campos, no 6. Añadido bloque con
anatomía completa del struct.
3. STATUS.md: LOC por capa corregidos contra wc -l real
- protocol: 6,260 → 7,278
- init: ~3,600 → 4,301
- compat: ~5,000 → 3,435 (estaba sobrestimado)
4. pineal: 6 stubs (<30 LOC c/u), no 5. Export (23 LOC) también es
stub funcional. LOC reales por sub-crate documentados.
5. init/SDD.md: ente-soma es wrapper de 44 LOC, no ~30.
6. akasha/SDD.md: fastembed está detrás de feature `embeddings`,
ort es transitivo. Sin feature, akasha-nous-real es stub mínimo.
7. vista/barra: LOC ajustados (vista-core 177, barra-core 108).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>