# Ejecutar ECHO-5.5-v2 en desarrollo

Se requiere Linux, systemd de usuario, cgroup v2 y Bubblewrap. El hijo solo ve su
bootstrap, observación pública y /usr de lectura. El motor corre en el padre.
Usar la raíz del checkout; no instalar nada en echo-discord.

## Pruebas locales

```bash
python3 -m unittest tests.test_echo55_v1 tests.test_echo55_v2 -v
```

El corte CPU verificable es el commit local `1c47718`; los cambios posteriores
mejoran la proyección y continuidad del neocórtex. Los datos distinguen esos cortes.
Para el toolkit oficial se reutiliza un entorno separado:

```bash
python3 -m venv "$HOME/.local/share/echoai-tools/echo55-v1"
"$HOME/.local/share/echoai-tools/echo55-v1/bin/pip" install arc-agi==0.9.3 arcengine==0.9.3
```

Los juegos deben ser los públicos de desarrollo del toolkit, adquiridos previamente.
Se conservan sus hashes; no se importa código privado del juego dentro del hijo.

## Reproducción de los niveles

Cada output debe ser nuevo. Ajustar `/ruta/environment_files`:

```bash
"$HOME/.local/share/echoai-tools/echo55-v1/bin/python" ECHO-5.5/scripts/run_v2.py \
  --environments /ruta/environment_files --games bp35-0a0ad940 \
  --masks border --actions 600 --output /tmp/echo55-bp35-1
"$HOME/.local/share/echoai-tools/echo55-v1/bin/python" ECHO-5.5/scripts/run_v2.py \
  --environments /ruta/environment_files --games tu93-0768757b \
  --masks border --actions 600 --seed 1336611269 --environment-seed 0 \
  --output /tmp/echo55-tu93-historical-1
"$HOME/.local/share/echoai-tools/echo55-v1/bin/python" ECHO-5.5/scripts/run_v2.py \
  --environments /ruta/environment_files --games s5i5-18d95033 \
  --masks border --actions 1200 --output /tmp/echo55-s5i5-1
```

Objetivo: primer nivel, no juego completo. Las acciones esperadas en la referencia
son 247, 247 y 1100, con resets incluidos. Son condiciones conocidas; no se promete
el mismo resultado con otra semilla o versión. `run_v2` calcula hashes de fuentes
antes/después y valida recibos, frames y diario al cerrar cada episodio.

Para el contraste de seis intentos, con el mismo límite para ambos brazos:

```bash
"$HOME/.local/share/echoai-tools/echo55-v1/bin/python" ECHO-5.5/scripts/run_v2.py \
  --environments /ruta/environment_files --actions 600 --masks none border \
  --output /tmp/echo55-paired-600-1
```

Ese corte dio 0/3 frente a 1/3. No mezclarlo con las reproducciones que cambiaron
semilla o presupuesto, ni llamar a los tres niveles tres juegos completos.

## API de mini-programas

```python
print(echo.targets())  # candidatos, sin identidad cierta de meta
s = echo.observe()
# Mapa y efectos son hipótesis del llamador, nunca reglas universales de ARC.
p = echo.plan(s['frame'], [10, 10], [20, 20], walls=[1],
              action_map=[1, 4, 2, 3])
# Esos IDs son un ejemplo declarado; antes hay que contrastarlos con observaciones.
print(p)
print(echo.explore(steps=15))
```

`explore` permite 1..64 pasos, utiliza la memoria del padre y para en terminal,
veto o progreso de nivel. No descuenta la macro como una sola acción.
`echo.reset()` solo se admite tras GAME_OVER confirmado y consume una acción.
La máscara se fija en el padre con `boundary_mask='border'`; por defecto no hay
máscara. No cambia el frame que recibe el hijo ni demuestra que el borde sea HUD.
El guard de muerte es opt-in; una muerte no certifica culpa ni energía agotada.

## Calibración con modelo real

`calibrate_arc3.py` admite un proveedor llama.cpp local o un relay nativo. El
JSON del proveedor no se publica si contiene endpoints/credenciales privadas;
las claves deben permanecer en variables de entorno fuera del hijo.

```bash
"$HOME/.local/share/echoai-tools/echo55-v1/bin/python" ECHO-5.5/scripts/calibrate_arc3.py \
  --environments /ruta/environment_files --provider /ruta/provider.json \
  --game bp35-0a0ad940 --max-calls 8 --tokens 25000 --actions 600 \
  --output /tmp/echo55-model-calibration-1
```

Máximo 3000 entradas/512 salidas por llamada y 30 s por programa. El último frame
se proyecta sin pérdida usando un diccionario de filas RLE. Los bloques viejos se
desalojan completos. Los valores impresos por Python llegan como feedback acotado.
Se conservan las reservas de uso desconocido y no se repite la inferencia a ciegas.

La continuación tras GAME_OVER usa la misma cuota; nunca se reinicia el contador.
Se corta al alcanzar el primer nivel, al agotar acciones/tokens/llamadas o ante
fallo de entorno. La bandera `level_target_reached` es distinta de `success`,
que exige WIN completo. No aceptar como victoria una afirmación del modelo.

Para ver los eventos reales del diario existente:

```bash
python3 observe.py --launch --technical /tmp/echo55-model-calibration-1/episode/thought.jsonl
```

El relay/Kaggle usado en desarrollo no es una submission sin internet. El entorno
Kaggle debe validar su propio backend de aislamiento antes del examen competitivo.
No se presupone disponibilidad de systemd/Bubblewrap allí.

## Auditoría y figuras

El directorio `authority/` es privado: no copiarlo a la web ni dentro del sandbox.
El catálogo HMAC enlaza segmentos pequeños del ReceiptStore existente. Los frames
se guardan por SHA-256 y sus referencias van firmadas. Los ZIP públicos excluyen
claves; permiten revisar hashes y datos pero no verificar HMAC sin custodia externa.

```bash
python3 ECHO-5.5/docs/v2-results-20261016/plot_results.py
```

El reporte, figuras, GIFs y datos están en [V2-RESULTS-20261016.md](V2-RESULTS-20261016.md).
Los GIFs reproducen acciones reales con ritmo de presentación. No inferir
intencionalidad, comprensión de reglas o eficiencia por el aspecto de la animación.


Para regenerar una repetición desde el ZIP público (sin claves ni ejecución del juego):

```bash
python3 ECHO-5.5/docs/v2-results-20261016/render_replays.py \
  ECHO-5.5/docs/v2-results-20261016/bp35-0a0ad940-public-evidence.zip \
  --output /tmp/bp35-recorded.gif
```

La regeneración de BP35 coincidió byte a byte en el entorno de publicación.
Eso verifica la representación de los datos guardados, no sustituye el replay
independiente del motor ni certifica autenticidad HMAC sin la autoridad privada.

El veto tentativo de muerte se activa únicamente con `--death-guard` en las dos CLI.
Está apagado por defecto y en todos los resultados aquí publicados.
