Lab Notes
Operations

Operations Runbook

Procedimientos paso a paso para las operaciones recurrentes. Cada procedimiento es una sección autocontenida que se puede seguir sin leer el resto de la documentación.

Propósito

Este runbook es la referencia del operator. Está escrito para el humano que necesita arreglar algo, reiniciar algo o verificar que algo está funcionando. Cada procedimiento es una sección autocontenida con los prerequisitos, los pasos, el output esperado y la recuperación si el procedimiento falla.

El cheatsheet companion está en Cheatsheet; los health checks están en Health Checks.

Convenciones

  • Todas las rutas usan el placeholder {workspace-root}. La ruta real es el workspace root del operator.
  • Todos los comandos asumen un shell POSIX. En macOS y Linux es el default.
  • Los comandos destructivos se marcan con [DESTRUCTIVE]. Requieren confirmación explícita.
  • Los procedimientos asumen que el operator tiene acceso por shell al host.

State review

Verificar el health de todos los gateways, sessions y herramientas.

Procedimiento

  1. Comprobar el gateway del Coordinator:

    curl -s http://localhost:{coordinator-port}/health

    Output esperado: un documento JSON con "status": "ok".

  2. Comprobar el gateway del Research Worker:

    curl -s http://localhost:{worker-port}/health

    Output esperado: un documento JSON con "status": "ok".

  3. Comprobar el gateway del Media Agent:

    curl -s http://localhost:{media-port}/health

    Output esperado: un documento JSON con "status": "ok".

  4. Listar las sesiones activas:

    {workspace-root}/ops/cheatsheets/list-sessions.sh

    Output esperado: una lista de session IDs y sus estados.

  5. Listar las misiones de research en curso:

    ls {workspace-root}/research/runs/

    Output esperado: una lista de carpetas de misiones. Cada carpeta tiene un phase.json con un estado no-terminal, o está archivada (estado terminal).

Recuperación

Si un gateway no responde, ver el procedimiento de recuperación del gateway específico más abajo.

Session resume

Continuar trabajo previo sin perder contexto.

Procedimiento

  1. Identificar la sesión a reanudar:

    {workspace-root}/ops/cheatsheets/list-sessions.sh
  2. Reanudar la sesión:

    {framework-cli} session resume {session-id}
  3. Verificar que la sesión está activa:

    {framework-cli} session status {session-id}

Recuperación

Si la sesión no se puede reanudar, la causa más común es que el proceso subyacente ha crasheado. Reiniciar el gateway y reintentar.

Worker recovery

Reiniciar el Research Worker tras un crash o tras un cambio de configuración.

Procedimiento

  1. Identificar el supervisor:

    • En macOS: launchd con el LaunchAgent ~/Library/LaunchAgents/{worker-launchagent-label}.plist.
    • En Linux: systemd con la unit {worker-systemd-unit}.service.
  2. En macOS:

    launchctl kickstart -k gui/$(id -u)/{worker-launchagent-label}

    El flag -k mata el proceso actual (si lo hay) y lo reinicia. KeepAlive=true asegura que el supervisor reinicia el proceso si crashea.

  3. En Linux:

    sudo systemctl restart {worker-systemd-unit}.service
  4. Verificar que el worker está up:

    curl -s http://localhost:{worker-port}/health

    Output esperado: un documento JSON con "status": "ok".

  5. Verificar que no hay misiones stuck:

    for mission in {workspace-root}/research/runs/*/; do
      phase=$(jq -r .current_phase "$mission/phase.json")
      if [ "$phase" != "done" ]; then
        echo "In-flight: $mission ($phase)"
      fi
    done

    Output esperado: una lista de misiones en curso. Si la lista está vacía, todas las misiones están en estado terminal.

Recuperación

Si el worker no arranca:

  • Comprobar el fichero de log:
    • macOS: tail -f /Users/{user}/.openclaw-scout/logs/gateway.log
    • Linux: sudo journalctl -u {worker-systemd-unit}.service -n 100
  • Problemas comunes:
    • Puerto ya en uso. Identificar y matar el proceso en conflicto.
    • Error de configuración. Validar el fichero de configuración.
    • Dependencias faltantes. Instalarlas.

Si una misión está stuck en un estado no-terminal, ver Research Mission Lifecycle → Recovery.

Media Agent recovery

Reiniciar el Media Agent tras un crash o tras un cambio de configuración.

Procedimiento

  1. Identificar el supervisor (igual que el worker).
  2. Reiniciar el proceso:
    • En macOS:
      launchctl kickstart -k gui/$(id -u)/{media-launchagent-label}
    • En Linux:
      sudo systemctl restart {media-systemd-unit}.service
  3. Verificar que el agent está up:
    curl -s http://localhost:{media-port}/health

Coding Assistant invocation

Correr el Coding Assistant no interactivamente para delegar una implementación específica o un análisis.

Procedimiento

El Coding Assistant se invoca mediante un scoped prompt. La invocación exacta es específica del framework; los requisitos documentados son:

  1. El prompt describe el objetivo y las boundaries, no la implementación.
  2. El prompt referencia los ficheros relevantes AGENTS.md, SKILL.md y TOOL.md.
  3. La invocación tiene el trust level requerido para la tarea:
    • read-only para inspección read-only.
    • workspace-write para cambios de código dentro del workspace.
    • Full trust para tareas que requieren acceso de producción (raro; solo con autorización explícita del usuario).

Ejemplo de invocación (ilustrativo):

{framework-cli} coding-assistant run \
  --prompt-file {workspace-root}/ops/prompts/{task-name}.md \
  --workspace {workspace-root}/{project-name} \
  --trust-level workspace-write

El prompt file es el implementation prompt descrito en Coding Assistant → Workflow.

Test suite

Correr la suite de tests de un proyecto.

Procedimiento

  1. Cambiar al directorio del proyecto:

    cd {workspace-root}/{project-name}
  2. Instalar dependencias (si no están instaladas):

    npm install   # para proyectos Node
    # o
    pip install -r requirements.txt   # para proyectos Python
  3. Correr los tests:

    npm test      # para Vitest
    # o
    pytest        # para pytest
  4. Verificar el output de los tests:

    • Todos los tests pasan.
    • El report de cobertura está en o por encima del mínimo del proyecto (típicamente 70%).

Audit review

Revisar el audit log del periodo pasado.

Procedimiento

  1. Listar los audit reports del periodo:

    ls -lt {workspace-root}/security/audits/ | head -20
  2. Abrir el report más reciente:

    cat {workspace-root}/security/audits/{latest-report}.md
  3. Para cada hallazgo, comprobar:

    • ¿El hallazgo sigue siendo válido?
    • ¿Se ha resuelto?
    • ¿La severidad sigue siendo precisa?
  4. Actualizar el report con el estado actual.

  5. Si se identifican nuevos hallazgos, añadirlos al Catálogo de fallos.

Backup

Respaldar el workspace.

Procedimiento

  1. Verificar que el destino del backup está disponible:

    ls {backup-destination}
  2. Correr el script de backup:

    {workspace-root}/ops/cheatsheets/backup.sh
  3. Verificar el backup:

    ls -lt {backup-destination}/ | head -5

    La entrada más reciente debería ser el backup recién creado.

  4. Verificar la integridad del backup:

    {workspace-root}/ops/cheatsheets/verify-backup.sh {backup-name}

Recuperación

Si el backup falla:

  • Comprobar el espacio en disco en el destino del backup.
  • Comprobar los permisos en el destino del backup.
  • Comprobar el log del script para el error específico.

Si el backup está corrupto, restaurar del backup previo y documentar el incidente en el audit log.

Browser recovery

Recuperar la instancia del browser cuando crashea o deja de responder.

Procedimiento

  1. Cerrar todas las instancias del browser:

    {framework-cli} browser close --all
  2. Arrancar una instancia nueva del browser:

    {framework-cli} browser start
  3. Verificar que el browser responde:

    {framework-cli} browser status

Retention

Archivar misiones de research antiguas a cold storage.

Procedimiento

  1. Identificar misiones más antiguas que el periodo de retención (default 90 días):

    find {workspace-root}/research/runs/ -maxdepth 1 -mindepth 1 \
      -mtime +{retention-days}
  2. Verificar que el cold storage está disponible:

    ls {cold-storage-destination}
  3. Archivar las misiones:

    {workspace-root}/ops/cheatsheets/archive-missions.sh {retention-days}
  4. Verificar el archive:

    ls {cold-storage-destination}/research/{year}/{month}/
  5. Eliminar las misiones archivadas del workspace:

    [DESTRUCTIVE] rm -rf {archived-missions}

    Confirmar con el usuario antes de correr este comando.

Coding Assistant killed by timeout

El proceso del Coding Assistant lo mata el OS (SIGKILL) cuando su task o prompt es demasiado grande. El síntoma típico es una línea de log que contiene killed y un return code de 137.

Síntomas

  • El Coding Assistant sale con código 137.
  • El log muestra Killed cerca del final de la run.
  • No hay artefactos ni output parcial en el workspace.

Procedimiento

  1. No escribas el código a mano. La regla de recuperación del Coding Assistant es absoluta. Para y recupera el assistant antes de hacer cualquier otra cosa.
  2. Identificar la task que mató al assistant. Normalmente es el fichero más grande o la fase más compleja.
  3. Dividir la task en prompts más pequeños. La regla recomendada: un fichero por prompt. Los prompts más pequeños tienen menos memoria y menos latencia.
  4. Re-correr con un timeout más largo (recomendado: 120-180s para tasks pequeñas).
  5. Si el assistant sigue muriendo, considera un split más agresivo: primero el fichero header-only, luego la implementación, luego los tests.

Recuperación

Si el Coding Assistant no se puede recuperar tras tres intentos con prompts progresivamente más pequeños, para y pide ayuda al operator. El operator puede necesitar ajustar el entorno (memoria, swap) o usar un execution path distinto.

Model quota exhausted

La quota de texto del modelo está agotada. El síntoma es un 429 o un quota_exceeded del provider del modelo. La quota de texto está en una rolling window de 5 horas; las quotas de voz, imagen y música son diarias.

Síntomas

  • El modelo devuelve un 429 o un quota_exceeded.
  • El health probe del Coordinator reporta quota_exhausted: true.
  • El fichero de tracking de quota muestra un porcentaje de uso no cero.

Procedimiento

  1. Identificar qué quota está agotada (texto, voz, imagen, música) leyendo la respuesta del provider del modelo.
  2. Para la quota de texto, esperar a que la rolling window de 5 horas se resetee. El reset time lo reporta el provider. Durante la espera:
    • El Coordinator no debería iniciar nuevas text requests.
    • Las background tasks deberían pausarse.
    • Se puede informar al usuario de que el assistant está en estado "quota cooldown".
  3. Para la quota de voz, imagen o música, esperar al reset diario.
  4. Si hay una task crítica en curso, considera cambiar a un modelo alternativo (si está configurado) o a un execution path de fallback (p. ej., correr una herramienta CLI directamente).

Recuperación

Cuando se resetea la quota:

  1. Verificar el reset corriendo una text request mínima.
  2. Reanudar las tasks en curso.
  3. Actualizar el fichero de tracking de quota con el uso nuevo.
  4. Si el reset time de la quota no se respeta, loguear el incidente y considerar rotar la API key.

Token pool: all tokens exhausted

Todos los tokens en el token pool de Perplexity del research framework están marcados quota_exhausted. El síntoma es un failed_terminal en la fase P3 con el error no_tokens_available.

Procedimiento

  1. Leer el fichero de estado del token pool:
    cat {framework-root}/runtime/token_pool_state.json
  2. Identificar qué tokens están exhausted y cuáles (si los hay) siguen activos.
  3. Esperar a que los tokens exhausted se reseteen. Las quotas de Perplexity se resetean diario.
  4. Si la espera no es aceptable, añadir un token nuevo al pool:
    • Editar {framework-root}/config/token_pool_config.json.
    • Añadir la entrada del token nuevo.
    • Recargar el pool (el framework recarga en cada request; no necesita restart).
  5. Verificar que el token nuevo está en uso leyendo el journal y buscando el campo name del token nuevo.

Recuperación

Si el operator no puede añadir un token nuevo, deshabilitar P3 para las misiones afectadas. El DAG maneja que P3 esté ausente (las fases que necesitan synthesis.json se marcarán blocked_missing_input).

Browser CDP target detached

La automatización del browser pierde su conexión con el Chromium DevTools Protocol. El síntoma es un error que contiene Target.detached o connection refused en el puerto CDP (default 18800).

Síntomas

  • Las acciones del browser devuelven connection refused o Target.detached.
  • El Coordinator no puede tomar un snapshot.
  • La pestaña del browser sigue abierta pero inalcanzable.

Procedimiento

  1. Comprobar si el proceso del browser sigue corriendo:
    lsof -nP -iTCP:18800 -sTCP:LISTEN
  2. Si el proceso no está corriendo, reiniciar el browser:
    {framework-cli} browser start
  3. Si el proceso está corriendo pero no responde, matarlo y reiniciar:
    kill -9 $(lsof -nP -iTCP:18800 -sTCP:LISTEN -t)
    {framework-cli} browser start
  4. Verificar que el browser nuevo responde tomando un snapshot de una URL conocida.

Recuperación

Si el browser se detacha repetidamente:

  • Comprobar los recursos del host (memoria, CPU).
  • Comprobar si hay instancias del browser en conflicto.
  • Considerar cambiar a un perfil nuevo.
  • Documentar el incidente en el audit log.

Media Lab Server not responding

El Media Lab Server (generación de imágenes y música) no responde en 127.0.0.1:8765. El síntoma es un connection refused o un timeout en la API.

Procedimiento

  1. Comprobar si el proceso del server está corriendo:
    lsof -nP -iTCP:8765 -sTCP:LISTEN
  2. Si no está corriendo, arrancarlo:
    cd {workspace-root}/devclaw-tools/audio-server
    python3 server.py &
  3. Verificar que el server está up:
    curl -s http://127.0.0.1:8765/api/status
  4. Si el server está corriendo pero no responde, comprobar el log para el error más reciente.
  5. Si el server falla repetidamente, comprobar el espacio en disco y los permisos del output directory.

Ver también