# Runtime & Sandbox

Lebenszyklus der Sandbox, injizierte Umgebung, Token-Familien und das Image, von dem eine Sitzung gestartet wird.

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

Jede Sitzung läuft in ihrer eigenen isolierten Sandbox. Diese Seite ist die Referenz für den Lebenszyklus der Sandbox, die Umgebung, die Beeuni beim Start injiziert, die Token-Familien und das Sandbox-Image selbst. Das Sitzungskonzept wird unter [Sitzungen](/docs/de/work/sessions) erläutert.

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

## Lebenszyklus der Sandbox

Ein Sitzungseintrag enthält einen `status`. Die Enumeration definiert `queued`, `branching`, `provisioning`, `running`, `stopped`, `failed`, `completed`, aber Beeuni verwendet nur 4 davon.

| Status | Wird gesetzt, wenn |
| --- | --- |
| `provisioning` | Beim Erstellen der Sitzung. Beeuni erstellt den Sitzungsbranch und fordert die Sandbox an. |
| `running` | Sobald die Sandbox läuft und erreichbar ist. |
| `stopped` | Beim expliziten Beenden oder durch die Inaktivitätsprüfung, die inaktive Sandboxes in den Ruhezustand versetzt. |
| `failed` | Wenn die Bereitstellung fehlschlägt. |

`queued`, `branching` und `completed` sind in der Enumeration vorhanden, werden aber im Sitzungsablauf nicht verwendet. Betrachte sie nicht als aktive Zustände.

Die Sandbox selbst hat in ihrem eigenen Eintrag einen separaten `status` mit eigener Enumeration.

| Status | Wird gesetzt, wenn |
| --- | --- |
| `provisioning` | Der Anbieter die Sandbox startet. |
| `active` | Der Anbieter bestätigt, dass die Sandbox läuft. |
| `stopped` | Beim expliziten Beenden, automatischen Beenden wegen Inaktivität oder während eines Neustarts. |
| `error` | Der Anbieter einen Start- oder Laufzeitfehler meldet. |
| `archived` | Endgültig. Du hast die Sitzung gelöscht und der Anbieter hat die Sandbox zerstört, nicht pausiert. |

Beeuni begrenzt nicht, wie viele Sitzungen gleichzeitig pro Konto oder Projekt laufen. Für laufende Sitzungen wird Rechenleistung berechnet; bei einem Konto ohne Guthaben wird beim Erstellen `402` zurückgegeben.

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

### Branch-Modell

- Der Sitzungsbranch trägt die Sitzungs-ID (eine UUID) als Namen. `BEEUNI_SESSION_ID` und `BEEUNI_BRANCH_NAME` haben denselben Wert.
- Beeuni erstellt den Branch beim Erstellen der Sitzung aus `base_ref`, standardmäßig aus dem Standardbranch des Projekts.
- Trigger erstellen ihren Sitzungsbranch genauso wie eine interaktive Sitzung.
- Direkt in den Standardbranch wird nichts geschrieben. Das geschieht nur durch einen gemergten [Änderungsantrag](/docs/de/work/change-requests).

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

### Sitzungsbranch abgleichen

Verwende **Ask Agent: Sync Branch & Reload** in der Befehlspalette der Sitzung, wenn sich der Basisbranch geändert hat. Der Agent prüft den Sitzungsbranch, bewahrt lokale Änderungen, ruft den neuesten Stand von `base_ref` ab, löst Konflikte, führt die relevanten Tests aus und committet den Abgleich. Beeuni wählt bei Konflikten keine Seite aus und setzt den Arbeitsbaum nicht zurück.

Der Agent schließt mit `beeuni sessions reload "$BEEUNI_SESSION_ID" --project "$BEEUNI_PROJECT_ID" --no-repo --force --yes` ab. `--no-repo` ist erforderlich, weil der Agent den Branch bereits abgeglichen hat. Beim Neuladen wird die Standard-Harness-Laufzeit ersetzt, sobald die neue Laufzeit fehlerfrei ist. Dadurch endet der aktuelle Durchlauf; sende `continue`, sobald die Laufzeit wieder verfügbar ist.

Der Sitzungsheader zeigt jede vom Server bestätigte Phase des Neuladens in Echtzeit an. Beim Neuladen im Web wird die Sitzung geprüft, die Agentenkonfiguration kompiliert, der Laufzeitwechsel angewendet und validiert und anschließend die aktive Konfiguration bestätigt. Das Repository wird dabei nicht aktualisiert. Die CLI kann das Repository aktualisieren, außer du übergibst `--no-repo`.

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

### Konfigurationsabgleich

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

Jede Sitzung verwendet die Konfiguration ihres Basis-Branches. Pushe Änderungen dorthin und lade die Sitzung neu. Updates warten bis zum Ende des aktiven Durchlaufs. Es gibt kein separates Config-Releases-Flag.

Nutze **Reload config** oder `beeuni sessions reload <session id>`. Bei Ladefehlern prüfe die Fehlerdetails der Sitzung und korrigiere die Projektkonfiguration.

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

#### `/workspace` ist der Ort zum Bearbeiten, der Basis-Branch bestimmt, was ausgeführt wird

Eine Sitzung führt IMMER die aktuelle Konfiguration des Basis-Branches aus. Es gibt keinen sitzungsspezifischen Konfigurationsmodus.

`/workspace` ist dein bearbeitbarer Checkout. Lies die Konfiguration dort und ändere sie dort — die Änderung erreicht die laufende Sitzung, sobald sie **in den Basis-Branch gepusht** wurde. Anschließend wird sie bei der normalen Konvergenz übernommen. Eine Änderung, die sich nur in `/workspace` befindet, ändert nichts am Verhalten der Sitzung; der laufende Agent wird darauf hingewiesen: In seinen Anweisungen steht, aus welchem Commit seine Konfiguration stammt, und dass `/workspace` möglicherweise hinterherhinkt.

Die Release-Kopie ist schreibgeschützt. Eine Änderung an der falschen Kopie schlägt daher mit einem Berechtigungsfehler fehl, statt stillschweigend wirkungslos zu bleiben.

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

#### Wenn die Konfiguration den Agent einer Sitzung nicht mehr deklariert

Eine Sitzung wird mit einem Agent erstellt. Entfernt ein späterer Commit diesen Agent oder benennt ihn um, wechselt die Sitzung zum Standard-Agent des Projekts — einmalig und nur dann, wenn der Besitzer der Sitzung diesen Agent verwenden darf. Beeuni hält den Wechsel im Audit-Log fest und erwähnt ihn in den Anweisungen des laufenden Agents, damit die Sitzung erklärt, was passiert ist.

Darf der Besitzer den Standard-Agent nicht verwenden oder deklariert das Projekt keinen Standard-Agent, hat die Sitzung keinen Agent und keinen Agent-Zugriff. Sie startet trotzdem und nennt den Grund. Deklariere den Agent erneut, lege einen Standard-Agent für das Projekt fest oder bitte einen Projektmanager um Zugriff auf den Standard-Agent.

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

#### Anzeige in der Sitzungsüberschrift

| Status | Bedingung | Überschrift |
| --- | --- | --- |
| Aktuell | Nicht veraltet, kein Fallback | Nichts |
| Update verfügbar | `stale: true` | Update-Symbol mit **Reload config** |
| Fallback | `fallback_reason` gesetzt | Rotes Symbol: **Config failed to load** |

Endet ein Neuladen mit einem Fallback, wird ein Fehler und kein Erfolg gemeldet.

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

#### Konfiguration neu laden

**Reload config** — und `beeuni sessions reload <session id>` — erledigt zwei Dinge in einem Schritt und nennt für jedes, was passiert ist:

1. Die laufende Sitzung wird auf die aktuellen Agents, Skills und Tools des Basis-Branches umgestellt.
2. Der Checkout `/workspace` wird per Fast-Forward aktualisiert, sodass die dort gelesenen Dateien mit der von der Sitzung ausgeführten Konfiguration übereinstimmen.

Das Abrufen des Checkouts erfolgt ausschließlich per Fast-Forward auf dem eigenen Branch der Sitzung und verwirft daher nichts. Übergib `--no-repo` über die CLI, um es zu überspringen. Um den CODE von `base_ref` in den Sitzungs-Branch zu übernehmen, verwende **Ask agent to sync**.

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

#### Deaktivieren

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

## Injizierte Umgebungsvariablen

Beeuni injiziert diese Variablen beim Start. Nur ein Projektschlüssel, der ausdrücklich für die Bereitstellung an `runtime` konfiguriert wurde, gelangt in die Sandbox. Zugangsdaten für Connectoren und Modellanbieter verbleiben auf dem Beeuni-Server.

| Variable | Beschreibung |
| --- | --- |
| `BEEUNI_PROJECT_ID` | UUID dieses Projekts. |
| `BEEUNI_SESSION_ID` | UUID dieser Sitzung. Zugleich der Branch-Name. |
| `BEEUNI_BRANCH_NAME` | Derselbe Wert wie `BEEUNI_SESSION_ID`. |
| `BEEUNI_REPO_URL` | Klon-URL des Projekt-Repos. |
| `BEEUNI_DEFAULT_BRANCH` | Der Standard-Branch des Projekts. |
| `BEEUNI_BASE_REF` | Der Ref, von dem dieser Sitzungs-Branch abzweigt. |
| `BEEUNI_API_URL` | Die Basis-URL der Plattform-API (`.../v1`). |
| `BEEUNI_AGENT_NAME` | Der Agent, mit dem die Sitzung erstellt wurde. |
| `BEEUNI_MODEL` | Das auszuführende Modell, sofern festgelegt. `BEEUNI_OPENCODE_MODEL` enthält denselben Wert für Daemons, die erstellt wurden, bevor es diesen Namen gab. |
| `BEEUNI_LLM_BASE_URL` | Basis-URL des Beeuni-LLM-Gateways. Das Gateway löst die Anmeldedaten des Anbieters serverseitig auf. |
| `BEEUNI_TOKEN` | Die an die Sitzung gebundene Beeuni-Anmeldedaten. Siehe unten. |

Beeuni injiziert `BEEUNI_WORKSPACE` nicht. Das Image enthält `/workspace`, und kein sitzungsspezifischer Schritt setzt es. Beeuni injiziert auch kein Git-Token – der Daemon ruft bei Bedarf kurzlebige Klon-Anmeldedaten ab; siehe [Aus einer Sitzung pushen](#pushing-from-a-session) unten. Beeuni lehnt ein Benutzergeheimnis mit dem Präfix `BEEUNI_*` ab, da dieses Präfix Plattformvariablen vorbehalten ist.

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

## Sitzungsanmeldedaten

Beeuni bietet externe Tokens, die du selbst erstellst, und eine Anmeldedaten innerhalb jeder Sandbox.

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

### Externe Tokens

Ein persönliches Zugriffstoken (PAT, mit dem Präfix `beeuni_pat_`) oder ein Dienstkonto (mit dem Präfix `beeuni_sa_`) authentifiziert Aufrufe der Beeuni-API, des SDK und der CLI von außerhalb einer Sandbox. Unter „Authentifizierung“ erfährst du mehr über PAT-Berechtigungen, die Einrichtung von Dienstkonten und die Wahl zwischen beiden.

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

### Token in der Sandbox

`BEEUNI_TOKEN` wird ausgestellt, wenn Beeuni die Sitzungsumgebung startet. Es ist an den startenden Benutzer, das Projekt, die Sitzung und die Agent-Berechtigung gebunden. Jede API-Route prüft weiterhin ihre eigenen Berechtigungen.

Die ursprünglichen Prompt- und Turn-Ledger-Kennungen sind keine Umgebungsvariablen. Nach dem Start ruft der Daemon sie mit `BEEUNI_TOKEN` über die API ab.

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

## Aus einer Sitzung pushen

Kein Upstream-Git-Token gelangt in die Sandbox. `git push origin HEAD` sendet Commits an den Sitzungs-Branch. Um Änderungen in den Standard-Branch zu übernehmen, ist ein gemergter [Änderungsantrag](/docs/de/work/change-requests) erforderlich.

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

## Das Sandbox-Image

Deine Dockerfile definiert die Basisumgebung. Beeuni stellt die Sitzungstools und die Verbindung zum Dashboard bereit.

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

### Vorlage deklarieren

Verweise unter `sandbox.templates` in `beeuni.yaml` auf deine Dockerfile als benannte Vorlage.

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

Legen Sie für jeden Eintrag genau eines von `dockerfile` oder `image` fest. Dockerfile-Pfade müssen innerhalb des Repositorys bleiben. Setzen Sie `default` auf den Template-Slug, den Ihre Sitzungen verwenden sollen; lassen Sie das Feld weg, um das Standard-Image der Plattform zu verwenden. Ältere Projekte auf `beeuni.toml` verwenden dieselben Felder – siehe [Legacy-`beeuni.toml`](/docs/de/project/legacy-toml). Vollständige Feldliste: [Manifest-Referenz](/docs/de/project/manifest).

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

### Einschränkungen

| Regel | Grund |
| --- | --- |
| Setzen Sie weder `ENTRYPOINT` noch `CMD`. | Beeuni überschreibt beide, um den Daemon zu starten. |
| Belegen Sie nicht Port `8000`. | Dieser ist für den Reverse-Proxy des Daemons reserviert. Führen Sie Entwicklungsserver auf anderen Ports aus. |
| Verwenden Sie `FROM` ein Debian- oder Ubuntu-Basis-Image. | Die Laufzeitebene führt `apt-get` aus. Alpine, Fedora und Arch führen zu einem fehlgeschlagenen Build. |
| Führen Sie `apt-get clean` nicht ohne `rm -rf /var/lib/apt/lists/*` aus. | Die Laufzeitebene führt `apt-get update` erneut aus; ein fehlerhafter Cache lässt den Build scheitern. |
| Betten Sie keine Zugangsdaten in das Image ein. | Deklarieren Sie den Namen in `env:` und legen Sie den Wert als Projektgeheimnis fest. Beeuni fügt ihn beim Start der Sitzung ein. |

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

### Hardwarespezifikation

`cpu`, `memory` und `disk` legen in einem Template-Eintrag die Größe der Sandbox fest. Alle drei Felder sind optional; fehlt ein Feld, gilt der Plattformstandard: 2 vCPU, 4 GiB Arbeitsspeicher, 20 GiB Festplattenspeicher.

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

`cpu` akzeptiert 1–32 Kerne, `memory` 1–128 GiB und `disk` 1–500 GiB. Beeuni begrenzt alle Werte oberhalb dieser Grenzwerte auf den jeweiligen Höchstwert. Beeuni unterstützt keine GPUs; ein Schlüssel `gpu` in einem Template führt zu einer Warnung, nicht zu einem Fehler.

Die Spezifikation ist Teil des Template-Snapshots und keine Einstellung pro Sitzung. Wird sie geändert, wird der Snapshot neu erstellt und die Änderung gilt für die nächste Sitzung. Die aktuelle Sitzung behält ihre bereits gestartete Spezifikation bei.

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

### Docker in der Sandbox

Setzen Sie `container_runtime: true` in einem Template, um Docker in dessen Sandboxes auszuführen: Bridge- und benutzerdefinierte Netzwerke, den Speichertreiber `overlayfs` und NAT-Egress. Lokale Stacks wie `supabase start` und `docker compose` funktionieren wie auf einem Laptop.

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

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

### Ports und Vorschau-URLs

Der Daemon lauscht auf Port `8000` und leitet alle anderen Ports weiter, die Ihre App innerhalb der Sandbox verwendet. Nur Port `8000` selbst ist vom Proxy ausgeschlossen.

Das Dashboard erreicht einen Sandbox-Port auf zwei Arten:

- **Pfadbasiert**: `https://<api-host>/v1/p/<sandbox-id>/<port>/...`. Dies ist das Standardformat und das einzige, das WebSocket-Upgrades unterstützt.
- **Subdomainbasiert**: `https://p<port>-<sandbox-id>.<api-host>/...`. Verwenden Sie dieses Format für Apps, die root-relative Pfade oder Cookies benötigen, etwa einen Next.js- oder Vite-Entwicklungsserver. WebSocket-Upgrades funktionieren in diesem Format noch nicht.

Der Vorschau-Proxy entfernt `X-Frame-Options` und alle Richtlinien für `frame-ancestors`. Eine Sitzung kann die App-Vorschau ohne Konfiguration Ihrerseits in einem Iframe einbetten.

Die Vorschau einer Sitzung kann auch über einen öffentlichen Link im Nur-Lese- oder interaktiven Modus geteilt werden. Öffentliche Freigabelinks sperren die Ports `22`, `4096`, `8000` und den Port für die statische Dateifreigabe.

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

### Snapshot-Neuaufbau

Änderungen am Image oder an den Umgebungseinstellungen erstellen die Umgebung für spätere Sitzungen neu. Bei unveränderten Einstellungen wird das vorhandene Image wiederverwendet. Die erste Sitzung, die einen Neuaufbau benötigt, zeigt „Image wird vorbereitet“; spätere Sitzungen verwenden diesen Build wieder.

Änderungen am Dockerfile innerhalb einer Sitzung werden erst in der nächsten Sitzung wirksam, nicht in der aktuellen. Die Änderung gelangt erst zu `main`, wenn der [Änderungsantrag](/docs/de/work/change-requests) zusammengeführt wird.
