# Entorno de ejecución y sandbox

Ciclo de vida del sandbox, entorno inyectado, familias de tokens e imagen desde la que se inicia una sesión.

Canonical page: https://beeuni.ai/docs/es/work/runtime

Cada sesión se ejecuta en su propio entorno aislado. Esta página es la referencia para el ciclo de vida del sandbox, el entorno que Beeuni inyecta al iniciar, las familias de tokens y la propia imagen del sandbox. Para conocer el concepto de sesión, consulta [Sessions](/docs/es/work/sessions).

<a id="sandbox-lifecycle"></a>

## Ciclo de vida del sandbox

Una fila de sesión tiene un `status`. La enumeración define `queued`, `branching`, `provisioning`, `running`, `stopped`, `failed`, `completed`, pero Beeuni solo escribe 4 de ellos.

| Estado | Se establece cuando |
| --- | --- |
| `provisioning` | Al crear la sesión. Beeuni crea la rama de la sesión y solicita el sandbox. |
| `running` | Cuando el sandbox está activo y accesible. |
| `stopped` | Al detenerlo explícitamente o mediante el proceso de inactividad que hiberna los sandboxes inactivos. |
| `failed` | Si falla el aprovisionamiento. |

`queued`, `branching` y `completed` existen en la enumeración, pero no se usan en el flujo de sesión. No los consideres estados activos.

El propio sandbox tiene un `status` independiente en su propia fila, con su propia enumeración.

| Estado | Se establece cuando |
| --- | --- |
| `provisioning` | El proveedor inicia el sandbox. |
| `active` | El proveedor confirma que el sandbox está activo. |
| `stopped` | Al detenerlo explícitamente, detenerlo automáticamente por inactividad o durante un reinicio. |
| `error` | El proveedor informa de un error de inicio o de ejecución. |
| `archived` | Terminal. Eliminaste la sesión y el proveedor destruyó el sandbox en vez de pausarlo. |

Beeuni no limita cuántas sesiones se ejecutan a la vez, ni por cuenta ni por proyecto. Las sesiones en ejecución consumen recursos de cómputo; si una cuenta se queda sin crédito, al crear una sesión se obtiene `402`.

<a id="branch-model"></a>

### Modelo de ramas

- La rama de la sesión lleva el nombre del ID de sesión (un UUID). `BEEUNI_SESSION_ID` y `BEEUNI_BRANCH_NAME` tienen el mismo valor.
- Beeuni crea la rama a partir de `base_ref`, que de forma predeterminada es la rama predeterminada del proyecto, al crear la sesión.
- Los activadores crean la rama de la sesión igual que una sesión interactiva.
- Nada escribe directamente en la rama predeterminada. Solo lo hace una [solicitud de cambio](/docs/es/work/change-requests) combinada.

<a id="reconcile-a-session-branch"></a>

### Sincronizar una rama de sesión

Usa **Ask Agent: Sync Branch & Reload** en la paleta de comandos de la sesión cuando cambie la rama base. El agente inspecciona la rama de la sesión, conserva el trabajo local, obtiene la última versión de `base_ref`, resuelve los conflictos, ejecuta las pruebas pertinentes y confirma la sincronización. Beeuni no elige un lado de un conflicto ni restablece el árbol de trabajo.

El agente termina con `beeuni sessions reload "$BEEUNI_SESSION_ID" --project "$BEEUNI_PROJECT_ID" --no-repo --force --yes`. Se requiere `--no-repo` porque el agente ya sincronizó la rama. La recarga reemplaza el entorno de ejecución de harness estándar una vez que el reemplazo está en buen estado. Finaliza el turno actual, así que envía `continue` cuando vuelva el entorno de ejecución.

El encabezado de la sesión informa en tiempo real de cada fase de recarga confirmada por el servidor. Una recarga web comprueba la sesión, compila la configuración del agente, aplica y valida el reemplazo del entorno de ejecución y, luego, confirma la configuración activa. No actualiza el repositorio. La CLI puede actualizar el repositorio, a menos que pases `--no-repo`.

<a id="config-convergence"></a>

### Convergencia de la configuración

<a id="where-a-box-gets-the-release"></a>

Cada sesión usa la configuración de su rama base. Envía los cambios a esa rama y recarga la sesión. Las actualizaciones esperan al final del turno activo. Config Releases no tiene un indicador separado.

Usa **Reload config** o `beeuni sessions reload <session id>`. Si falla la carga, consulta los detalles del error y corrige la configuración del proyecto.

<a id="workspace-is-where-you-edit-the-base-branch-is-what-runs"></a>

#### `/workspace` es donde editas; la rama base es lo que se ejecuta

Una sesión SIEMPRE ejecuta la configuración actual de la rama base. No existe un modo de configuración por sesión.

`/workspace` es tu copia de trabajo editable. Lee ahí la configuración y cámbiala ahí; el cambio llega a la sesión en ejecución cuando se **envía a la rama base**, y la convergencia normal lo aplica. Una edición que solo esté en `/workspace` no cambia el comportamiento de la sesión, y se le informa de ello al agente en ejecución: sus instrucciones indican de qué commit proviene su configuración y señalan que `/workspace` puede estar desactualizado.

La copia de la versión es de solo lectura, así que editar la copia equivocada produce un error de permisos en lugar de no hacer nada en silencio.

<a id="when-the-configuration-no-longer-declares-a-sessions-agent"></a>

#### Si la configuración deja de declarar el agente de una sesión

Una sesión se crea con un agente. Si un commit posterior elimina o cambia el nombre de ese agente, la sesión pasa al agente predeterminado del proyecto, una sola vez y solo si el propietario de la sesión puede usarlo. Beeuni registra el cambio en el registro de auditoría y lo indica en las instrucciones del agente en ejecución, para que la sesión explique lo ocurrido.

Si el propietario no puede usar el agente predeterminado, o el proyecto no declara ninguno, la sesión se queda sin agente ni acceso a uno. Aun así, arranca e informa del motivo. Vuelve a declarar el agente, establece un agente predeterminado para el proyecto o pide acceso al agente predeterminado a un responsable del proyecto.

<a id="what-the-session-header-shows"></a>

#### Qué muestra el encabezado de la sesión

| Estado | Condición | Encabezado |
| --- | --- | --- |
| Actual | No está desactualizada, sin alternativa | Nada |
| Actualización disponible | `stale: true` | El indicador de actualización, con **Reload config** |
| Alternativa | `fallback_reason` definido | Una etiqueta roja: **Config failed to load** |

Si la recarga termina usando una alternativa, informa de un error, no de un éxito.

#### Reload config

**Reload config** —y `beeuni sessions reload <session id>`— hace dos cosas en un solo paso e indica qué ocurrió con cada una:

1. Cambia la sesión en ejecución a los agentes, habilidades y herramientas actuales de la rama base.
2. Actualiza mediante avance rápido la copia de trabajo de `/workspace`, para que los archivos que lees ahí coincidan con la configuración que ejecuta la sesión.

La actualización de la copia de trabajo solo permite avances rápidos y se hace en la rama de la propia sesión, así que no descarta nada. Pasa `--no-repo` en la CLI para omitirla. Para incorporar el CÓDIGO de `base_ref` a la rama de la sesión, usa **Ask agent to sync**.

<a id="turning-it-off"></a>

#### Desactivarlo

<a id="injected-environment"></a>

## Entorno inyectado

Beeuni inyecta estas variables al arrancar. Solo un secreto del proyecto configurado explícitamente para la entrega `runtime` entra en el sandbox. Las credenciales de conectores y proveedores de modelos permanecen en el servidor de Beeuni.

| Variable | Descripción |
| --- | --- |
| `BEEUNI_PROJECT_ID` | UUID de este proyecto. |
| `BEEUNI_SESSION_ID` | UUID de esta sesión. También es el nombre de la rama. |
| `BEEUNI_BRANCH_NAME` | Mismo valor que `BEEUNI_SESSION_ID`. |
| `BEEUNI_REPO_URL` | URL de clonación del repositorio del proyecto. |
| `BEEUNI_DEFAULT_BRANCH` | Rama predeterminada del proyecto. |
| `BEEUNI_BASE_REF` | La referencia desde la que se creó la rama de esta sesión. |
| `BEEUNI_API_URL` | URL base de la API de la plataforma (`.../v1`). |
| `BEEUNI_AGENT_NAME` | El agente con el que se creó la sesión. |
| `BEEUNI_MODEL` | El modelo que se ejecutará, si está definido. `BEEUNI_OPENCODE_MODEL` tiene el mismo valor en los daemons creados antes de que existiera este nombre. |
| `BEEUNI_LLM_BASE_URL` | URL base de la puerta de enlace LLM de Beeuni. La puerta de enlace resuelve las credenciales del proveedor en el servidor. |
| `BEEUNI_TOKEN` | La credencial de Beeuni asociada a la sesión. Consulta la sección siguiente. |

Beeuni no inyecta `BEEUNI_WORKSPACE`. La imagen incluye `/workspace` y ningún paso por sesión lo establece. Beeuni tampoco inyecta un token de Git: el daemon obtiene una credencial de clonación de corta duración cuando la necesita; consulta [Enviar cambios desde una sesión](#pushing-from-a-session) más abajo. Beeuni rechaza los secretos de usuario cuyo nombre empieza por el prefijo `BEEUNI_*`, porque reserva ese prefijo para las variables de la plataforma.

<a id="session-credential"></a>

## Credencial de sesión

Beeuni tiene tokens externos que creas tú y una credencial dentro de cada entorno aislado.

<a id="external-tokens"></a>

### Tokens externos

Un token de acceso personal (PAT, con el prefijo `beeuni_pat_`) o una cuenta de servicio (con el prefijo `beeuni_sa_`) autentica las llamadas a la API de Beeuni, el SDK y la CLI desde fuera de un entorno aislado. Consulta Autenticación para conocer los ámbitos de PAT, cómo configurar una cuenta de servicio y cómo elegir entre ambos.

<a id="in-sandbox-token"></a>

### Token dentro del entorno aislado

`BEEUNI_TOKEN` se genera cuando Beeuni inicia el entorno de la sesión. Está asociado al usuario que la inició, el proyecto, la sesión y los permisos del agente. Cada ruta de la API sigue aplicando su propia comprobación de capacidades.

Los identificadores del prompt inicial y del registro de turnos no son variables de entorno. Tras el arranque, el daemon los obtiene de la API mediante `BEEUNI_TOKEN`.

<a id="pushing-from-a-session"></a>

## Enviar cambios desde una sesión

Ningún token de Git del repositorio remoto entra en el entorno aislado. `git push origin HEAD` envía los commits a la rama de la sesión. Para integrar cambios en la rama predeterminada, se necesita una [solicitud de cambio](/docs/es/work/change-requests) combinada.

<a id="the-sandbox-image"></a>

## Imagen del entorno aislado

Tu Dockerfile define el entorno base. Beeuni proporciona las herramientas de sesión y la conexión con el panel.

<a id="declare-a-template"></a>

### Declarar una plantilla

Haz referencia a tu Dockerfile como una plantilla con nombre en `sandbox.templates` dentro de `beeuni.yaml`.

```yaml
sandbox:
  templates:
    - slug: dev
      name: Dev box
      dockerfile: Dockerfile.dev
  default: dev
```

Establece exactamente uno de `dockerfile` o `image` en cada entrada. Las rutas de Dockerfile deben permanecer dentro del repositorio. Establece `default` en el slug de la plantilla que deben usar tus sesiones; omítelo para usar la imagen predeterminada de la plataforma. Los proyectos antiguos en `beeuni.toml` usan los mismos campos; consulta [la referencia heredada de `beeuni.toml`](/docs/es/project/legacy-toml). Lista completa de campos: [referencia del manifiesto](/docs/es/project/manifest).

<a id="constraints"></a>

### Restricciones

| Regla | Motivo |
| --- | --- |
| No establezcas `ENTRYPOINT` ni `CMD`. | Beeuni sustituye ambos para iniciar el daemon. |
| No ocupes el puerto `8000`. | Está reservado para el proxy inverso del daemon. Ejecuta los servidores de desarrollo en otros puertos. |
| Usa una imagen base de Debian o Ubuntu: `FROM`. | La capa de ejecución ejecuta `apt-get`. Alpine, Fedora y Arch provocan un fallo en la compilación. |
| No ejecutes `apt-get clean` sin `rm -rf /var/lib/apt/lists/*`. | La capa de ejecución vuelve a ejecutar `apt-get update`; una caché defectuosa provoca un fallo en la compilación. |
| No incluyas credenciales en la imagen. | Declara el nombre en `env:` y establece el valor como secreto del proyecto. Beeuni lo inyecta al iniciar la sesión. |

<a id="hardware-spec"></a>

### Especificaciones de hardware

`cpu`, `memory` y `disk` en una entrada de plantilla determinan el tamaño del entorno aislado. Los tres campos son opcionales; si se omite uno, se usa el valor predeterminado de la plataforma: 2 vCPU, 4 GiB de memoria y 20 GiB de disco.

```yaml
sandbox:
  templates:
    - slug: big
      image: ubuntu:24.04
      cpu: 4
      memory: 8
      disk: 50
```

`cpu` admite de 1 a 32 núcleos, `memory` admite de 1 a 128 GiB y `disk` admite de 1 a 500 GiB. Beeuni reduce al límite cualquier valor que lo supere. Beeuni no admite GPU; una clave `gpu` en una plantilla genera una advertencia, no un error.

La especificación forma parte de la instantánea de la plantilla, no es una configuración por sesión. Al cambiarla, se vuelve a crear la instantánea y el cambio se aplica a la siguiente sesión. La sesión actual conserva las especificaciones con las que ya se inició.

<a id="docker-in-the-sandbox"></a>

### Docker en el entorno aislado

Establece `container_runtime: true` en una plantilla para ejecutar Docker dentro de sus entornos aislados: redes bridge y definidas por el usuario, el controlador de almacenamiento `overlayfs` y salida NAT. Las pilas locales, como `supabase start` y `docker compose`, funcionan igual que en un portátil.

```yaml
sandbox:
  templates:
    - slug: dev
      dockerfile: .beeuni/Dockerfile.dev
      container_runtime: true
```

<a id="ports-and-preview-urls"></a>

### Puertos y URL de vista previa

El daemon escucha en el puerto `8000` y redirige cualquier otro puerto que use tu aplicación dentro del entorno aislado. El proxy solo bloquea el propio puerto `8000`.

El panel puede acceder a un puerto del entorno aislado de dos maneras:

- **Por ruta**: `https://<api-host>/v1/p/<sandbox-id>/<port>/...`. Es el formato predeterminado y el único que admite actualizaciones de WebSocket.
- **Por subdominio**: `https://p<port>-<sandbox-id>.<api-host>/...`. Usa este formato para aplicaciones que necesitan rutas relativas a la raíz o cookies, como un servidor de desarrollo de Next.js o Vite. Este formato aún no admite actualizaciones de WebSocket.

El proxy de vista previa elimina `X-Frame-Options` y cualquier política `frame-ancestors`. Una sesión puede insertar una vista previa de tu aplicación en un iframe sin que tengas que configurarlo.

También se puede compartir la vista previa de una sesión mediante un enlace público, en modo de solo lectura o interactivo. Los enlaces públicos para compartir bloquean los puertos `22`, `4096`, `8000` y el puerto para compartir archivos estáticos.

<a id="snapshot-rebuilds"></a>

### Reconstrucciones de instantáneas

Los cambios en la imagen o en los ajustes del entorno reconstruyen el entorno para las sesiones posteriores. Si los ajustes no cambian, se reutiliza la imagen existente. La primera sesión que necesita una reconstrucción muestra «preparing image»; las siguientes reutilizan esa compilación.

Editar el Dockerfile dentro de una sesión surte efecto en la siguiente sesión, no en la actual. El cambio llega a `main` solo cuando se fusiona su [solicitud de cambio](/docs/es/work/change-requests).
