# La escalera del primer arranque

Lo que `pruebas/` no puede contestar. Las siete comprobaciones automáticas dicen
que las piezas están donde tienen que estar; esto dice si **sirve**, y eso solo
lo juzga alguien escuchando y leyendo.

Se sube **en orden y se para en el primer escalón que falle**. Es a propósito:
el escalón que falla es el que informa, y seguir subiendo con uno roto convierte
un fallo de una línea en una tarde de adivinar.

Antes de empezar:

```bash
./verde/arrancar.sh              # mide, configura y dictamina
./verde/pruebas/ejecutar.sh      # las 7; ninguna abre el TUI
./verde/verde-launcher.sh        # el TUI, en verde fosforo
```

Los tiempos se anotan aquí mismo. El del naranja está para comparar, pero **léete
antes el aviso del final**: hoy no miden lo mismo.

Los escalones 1 a 4 también se pueden pasar sin abrir el TUI, que es como se
subieron la primera vez:

```bash
hermes -z "hola, ¿quién eres?"        # una pregunta y a callar
```

Y para ver **qué herramientas llamó de verdad**, que `-z` no enseña:

```bash
python3 -c "
import sqlite3
c = sqlite3.connect('file:$HOME/.hermes/state.db?mode=ro', uri=True)
for r in c.execute('SELECT role, tool_name, tool_calls, content FROM messages ORDER BY rowid DESC LIMIT 10'):
    print(r)
"
```

Sin eso, un fallo de rutas se atribuye al modelo. Pasó, y está contado en el
escalón 3.

---

## 1 · Que conteste

> hola, ¿quién eres?

Contesta que **el endpoint responde y el prompt fijo cabe**. No prueba nada más:
aquí no hay herramientas ni memoria, es la señal de vida.

| | |
|---|---|
| Tiempo | _______ |
| ¿Se presenta como asistente, sin inventarse una identidad rara? | _______ |

Si falla: no es cosa de Hermes. Vuelve a `arrancar.sh`, que separa el modelo del
arnés.

---

## 2 · Una herramienta, la más simple

> ¿cuánto espacio libre queda en el disco?

Primera llamada real. Tiene que **ejecutar `df`**, no describir cómo se ejecuta
`df`. Un modelo que explica el comando en vez de llamarlo ha entendido la
pregunta y ha fallado la tarea.

| | |
|---|---|
| Tiempo | _______ |
| ¿Llama a la herramienta o lo cuenta en prosa? | _______ |
| ¿El número coincide con `df -h /`? | _______ |

---

## 3 · Leer un fichero

> lee verde/README.md y resúmelo en una línea

Otra familia de herramienta (ficheros, no terminal) y, de paso, si el resumen
tiene que ver con lo que pone el fichero o se lo inventa a partir del nombre.

| | |
|---|---|
| Tiempo | _______ |
| ¿El resumen se parece al fichero de verdad? | _______ |

**Si el resumen no pega ni con cola, mira el directorio antes que el modelo.**
La primera vez que se subió esta escalera, este escalón devolvió un resumen
perfecto de Gitleaks. No era una alucinación: el agente arranca en `$HOME`, así
que resolvió `verde/README.md` contra `~`, donde efectivamente hay un
`README.md` — el de Gitleaks. Lo leyó entero y lo resumió bien.

Es un fallo traicionero porque **no deja ni un error**: la herramienta se
ejecuta, devuelve un fichero de verdad y el modelo acierta el resumen. Solo que
no es el fichero que pediste.

Ni el `cd` delante ni `--in DIR` lo arreglan (`--in` se ignora en modo `-z`). Lo
que lo arregla es `terminal.cwd` en `~/.hermes/config.yaml`, ya puesto y
comprobado por `pruebas/03_config.sh`. El detalle, en `NOTAS.md`.

---

## 4 · Encadenar — **el escalón que importa**

> dime cuál de los .md de verde/ es el más largo

Aquí se separa un chatbot de un agente. No hay una herramienta que conteste esto:
hay que **listar, medir y razonar sobre el resultado de la vuelta anterior**, y
decidir cuándo se ha terminado.

Es el escalón que más probabilidades tiene de romperse en un 4B, y el que
justifica el carril entero: si esto sale, el arnés aporta algo sobre el núcleo.

| | |
|---|---|
| Tiempo | _______ |
| Número de vueltas que da | _______ |
| ¿Acierta el fichero? (comprueba con `wc -c verde/*.md`) | _______ |
| ¿Se queda en bucle o sabe parar? | _______ |

---

## 5 · Una skill

> _(algo que dispare una de las skills instaladas; `hermes skills list` las lista)_

El paso del vídeo que el núcleo no tiene. Lo que se mira no es que la skill
funcione —eso es de quien la escribió— sino si el modelo **decide sola** que esa
skill viene a cuento.

| | |
|---|---|
| Skill probada | _______ |
| ¿La eligió sin que se la nombraras? | _______ |
| **¿Salió a la red para resolverlo?** | _______ |

**Esa tercera fila se añadió después de subir la escalera la primera vez, y es
la que más pesa.** Pidiéndole un cartel en ASCII, el agente eligió la skill solo
—bien—, descubrió que `pyfiglet` no estaba instalado y **se fue a una API de
terceros por su cuenta**, sin que nadie le dijera que podía.

Así que al probar una skill, mira siempre las llamadas, no solo el resultado:

```bash
ss -tnp | grep -v 127.0.0.1        # mientras corre
```

Ningún ajuste lo impide: el agente tiene terminal y la terminal tiene `curl`.
Es la contrapartida de lo que hace valioso este carril, y está desarrollado en
`NOTAS.md`.

---

## 6 · Que hable

> _(cualquier respuesta, con el TTS puesto)_

Tiene que sonar **exactamente igual que el naranja**: mismo Piper 1.2.0 MIT,
mismo `es_ES-davefx-medium`, mismo tono 1.0. `pruebas/07_voz.sh` ya comprueba
que el fichero sale a 22050 Hz mono y con la voz del núcleo; lo que falta es tu
oído en la cadena entera, dentro de Hermes y no llamando al script a mano.

| | |
|---|---|
| ¿Suena igual que el naranja? | _______ |
| ¿Corta frases o se come el final? | _______ |

---

## 7 · Que escuche — **el último, y por un motivo**

> _(dictar una orden por micrófono)_

Va el último porque es el que puede tirar todo lo demás. whisper `small` pide
**839 MiB en el pico de la transcripción** —no en reposo, que fue el error de
medida que costó una tarde— contra una tarjeta que ya tiene el modelo dentro.

| | |
|---|---|
| ¿Transcribe? | _______ |
| Tiempo de la primera (arranca el servidor, ~4 s) | _______ |
| Tiempo de las siguientes | _______ |

Si sale `CUDA error: out of memory`, **no es un fallo nuevo**: es el mismo
reparto que documenta el README del naranja. Salidas por orden:

1. Fiarse de `stt.local.unload_after_idle_seconds: 300`, que ya está puesto:
   whisper suelta la VRAM tras cinco minutos de silencio.
2. Bajar el modelo de escucha a `base` (80 % de acierto en vez de 93 %).
3. Probar la escucha con el modelo de texto descargado (`ollama stop`).

Y recuerda que el envoltorio `~/.local/bin/whisper-server` del naranja ya tiene
la red de seguridad: por debajo de 950 MiB libres arranca en CPU (2,17 s en vez
de 1,05) en vez de morirse.

---

## Antes de comparar los dos carriles

**El verde va a medir más lento, y no será culpa del modelo.**

El naranja tiene **150 acciones rápidas que se saltan el cerebro**: "¿cuánto
espacio queda?" es un `df` directo, no una inferencia. En Hermes no existe ese
atajo — toda orden pasa por el modelo, con las 19 herramientas, las skills y la
memoria en contexto **en cada vuelta**.

Comparar el escalón 2 contra el naranja es comparar una inferencia contra un
`df`. Para comparar de verdad hacen falta frases que en el naranja **también**
acaben en el cerebro: están en `config/jarvis-sin-accion.jsonl`.

## Al terminar, devolver la máquina a su sitio

```bash
./verde/verde-launcher.sh --stop
ollama stop qwen3.5:4b-verde
./nucleo/arranca.sh                    # el naranja, como siempre
```

Y comprobar que el naranja vuelve con su VRAM de siempre. `pruebas/02_modelo.sh`
del verde ya verifica que sus cuatro parámetros siguen intactos, pero eso mira el
Modelfile, no que arranque.
