Vibecoding Pro Review anfragen

Alle Artikel

Parallele Subagents ohne Sandbox: Ein Test startet Prozesse

Ein Incident mit sieben Claude Code Subagents im Auto Mode: Ein Testbug startet echte Prozesse gegen Production. Was die Ursache war und welches Setup hilft.

Auf einen BlickSetup-Check für autonome und parallele Agenten
  • Writes auf den eigenen Worktree begrenzen, nicht nur auf das Repo
  • Netzwerk nur per Allowlist, kein Default auf Production-Endpoints
  • Keine Live-Credentials in Prompts oder Agent-Instruktionen, nur kurzlebige, eng gescopte Tokens
  • Tests schlagen fehl, sobald der echte Launcher statt des Fakes aufgerufen wird
  • Keine echten Befehle wie say als Testbeispiele
  • Hand-back-Report verlangt unerwartete Side Effects, nicht nur grüne Tests
  • blockWritesOutsideWorkingDirectories setzen, aber wissen, dass es Bash nicht abdeckt

Grafik: Vibecoding Pro · Grundlage: die Quellen unten

Sieben Subagents, Auto Mode, jeder in seinem eigenen Git Worktree, jeder schließt ein Issue und öffnet einen PR. Ein Setup, das mit Background-Subagents naheliegt. Ein Incident-Report auf marutpandya.com zeigt, was passiert, wenn dabei nichts zwischen Agent und Maschine steht: Ein Testbug startete echte Prozesse, zwei davon mit Production als Default-Endpoint.

Nichts ging kaputt. Laut Autor war das Glück, kein Design. Hier die Kette und die Konfiguration, die du daraus ableiten solltest.

Das Setup und der Ablauf

Claude Code 2.1.286 im Auto Mode, eine Session startet sieben Background-Subagents parallel, macOS, keine Sandbox. Alle Agenten liefen unter dem User-Account des Entwicklers, mit dessen Rechten.

Ein Agent implementierte Live Capture: einen Hook, den Claude Code oder Codex nach jedem Turn aufruft und der einen Background-Worker startet, um das Session-Transcript hochzuladen. Der Agent schrieb Tests, die den macOS-Befehl say als Beispiel für das Notification-Programm eines Users nutzten. Beim zweiten Testlauf sprachen plötzlich zwei synthetische Stimmen JSON vor.

Die Zeitachse ist der eigentliche Punkt: Der Bug wurde in 23 Sekunden geschrieben, ausgeführt und gefixt. Der Mensch bemerkte es knapp vier Minuten später.

Die Ursache: eine Zeile Python

Die Tests übergaben einen Fake-Launcher, eine Liste, die Befehle nur aufzeichnet. Der Code wählte den Launcher so:

spawn = spawn or _spawn   # Fake wenn übergeben, sonst der echte

Eine leere Liste ist in Python falsy. spawn or _spawn warf den Fake weg und nahm den echten Launcher, und der startet Prozesse detached in einer eigenen Session, sodass sie den Test überleben. Der Fix:

spawn = _spawn if spawn is None else spawn

Ein gewöhnlicher Bug, den auch ein Mensch schreibt. Interessant ist, was danach kam.

Vier Befunde, die dein Setup betreffen

Es liefen vier Prozesse, nicht zwei. Drei Tests riefen den echten Launcher auf: zwei say-Prozesse und zwei Upload-Worker, einer für Codex, einer für Claude Code.

Die Worker zeigten auf Production. Im Test setzte niemand den Endpoint, also griff der Default: die Production-Ingest-URL. Gesendet wurde nichts, aber aus Gründen, die keine Sicherheitskontrolle waren. Ein Fixture bog zufällig alle Config-Verzeichnisse auf einen Temp-Ordner um, der API-Key war ein Fake, und es gab keine Daten. Ohne das Fixture hätten die Worker echte Transcripts gelesen, inklusive eines GitHub-Tokens, das den Agenten im Klartext mitgegeben worden war.

Der Agent sah es und meldete es nicht. Die Assertions schlugen mit [] == [...] fehl, der Fake hatte also nichts aufgezeichnet. Der Agent fixte den Bug als normalen Testfehler und berichtete der Parent-Session nur von PR und grünen Tests. Der Autor wertet das nicht als Verschleierung, sondern als fehlende Unterscheidung im Loop zwischen „Testbug“ und „Testbug mit Side Effects auf der Maschine“.

Die Transcripts führten in die Irre. Die Suche nach „voice“ fand nur Fehltreffer. Erst das macOS Unified Log, gefiltert auf coreaudiod, corespeechd und say, zeigte die Prozesse mit Zeitstempel.

Was v2.1.314 dazu liefert und was nicht

Passend kam mit Claude Code v2.1.314 eine neue Einstellung: permissions.blockWritesOutsideWorkingDirectories. Damit verweigern Write, Edit und NotebookEdit Pfade außerhalb der Working Directories, und zwar in jedem Permission Mode, also auch im Auto Mode.

{
  "permissions": {
    "blockWritesOutsideWorkingDirectories": true
  }
}

Setz das. Aber lies die Release Notes genau: Die Einstellung betrifft die Datei-Tools. Der Incident lief über einen Testlauf, also über Bash. Den hätte diese Einstellung nicht gestoppt. Für Shell-Befehle brauchst du die Sandbox, die Dateisystem und Netzwerk auf OS-Ebene begrenzt; wie du sie konfigurierst und was sie nicht abdeckt, steht im Beitrag zur Claude Code Sandbox. Beides zusammen ergibt erst eine Grenze, und die Datei-Tools brauchst du trotzdem weiterhin sauber über Permission-Regeln geschnitten.

Was das für deinen Workflow bedeutet

Der Autor zieht selbst klare Konsequenzen: jede autonome Session sandboxen, Writes auf den eigenen Worktree begrenzen, Netzwerk per Allowlist, kein Zugriff auf Config im Home-Verzeichnis. Keine Live-Credentials in Agent-Instruktionen, sondern kurzlebige, eng gescopte Tokens. Tests, die gegen einen toten lokalen Endpoint laufen und fehlschlagen, sobald der echte Launcher aufgerufen wird. Und ein Hand-back-Format, das unerwartete Side Effects abfragt, nicht nur Testergebnisse.

Der letzte Punkt ist reines Prompt- und Subagent-Design. Wenn deine Subagents mit einem festen Report-Schema zurückmelden, gehört dort ein Feld für Prozesse, Netzwerkzugriffe und Dateien außerhalb des Worktrees hinein. Wie du Subagents grundsätzlich schneidest, steht in Claude Code Subagents: Kontext-Isolation.

Der Autor betont auch die Grenzen: ein Incident, ein Agent, ein Bug, keine Messung, wie oft so etwas passiert. Und kein böswilliges Verhalten, keine Prompt Injection. Genau das macht den Fall relevant: Ein normaler Bug reichte.

Fazit

Wer Agenten parallel und autonom laufen lässt, sollte annehmen, dass jede Zeile, die sie schreiben, Sekunden später auf der eigenen Maschine läuft, bevor jemand sie gelesen hat. Die Frage ist dann nur, was dieser Code erreichen kann.

Du willst wissen, ob dein Setup aus Permissions, Sandbox, Hooks und Subagent-Reports diesen Fall abfangen würde? Fordere ein Agent-Setup-Review an.

Häufige Fragen

Was macht permissions.blockWritesOutsideWorkingDirectories in Claude Code?

Die Einstellung kam mit Claude Code v2.1.314. Sie sorgt dafür, dass die Tools Write, Edit und NotebookEdit in jedem Permission Mode Pfade außerhalb der Working Directories verweigern.

Schützt blockWritesOutsideWorkingDirectories auch vor Bash-Befehlen?

Laut Release Notes gilt die Einstellung für Write, Edit und NotebookEdit. Ein Testlauf, den der Agent per Bash startet, ist damit nicht abgedeckt. Dafür brauchst du zusätzlich eine Sandbox für Shell-Befehle.

Warum hat das Fake-Objekt im Test den echten Launcher nicht ersetzt?

Der Fake war eine leere Liste, und eine leere Liste ist in Python falsy. Der Ausdruck spawn or _spawn verwarf deshalb den Fake und nahm den echten Launcher. Die Korrektur prüft explizit auf None.

Woran erkennt man, welche Prozesse ein Agent wirklich gestartet hat?

Im beschriebenen Incident führten die Transcripts in die Irre. Erst das macOS Unified Log zeigte, welche Prozesse wann liefen. Transcripts zeigen, was der Agent sagt, das OS-Log zeigt, was tatsächlich lief.

Beitrag teilen

Weiterlesen

Weitere Artikel

  1. hooks Claude Code Kontext: Stack Traces und Test-Output filtern
  2. hooks Claude Code Sandbox: Bash per settings.json einsperren
  3. hooks Claude Code Hooks: deterministische Regeln für Agenten
Kontakt · Warteliste

Setup-Review anfragen

Das Agent-Setup-Review startet gerade. Sag kurz, wo dein Setup steht und was du lösen willst. Wir melden uns, sobald es losgeht, und vorher nur, wenn wir Rückfragen haben.

  1. Anfrage mit Rolle, Tool und größter Baustelle
  2. Rückfrage nur, wenn etwas unklar ist
  3. Nachricht, sobald das Review startet

Du willst ein ganzes Team schulen? Dann ist vibecodingtraining.de die richtige Adresse.

Kein Newsletter, nur eine Nachricht, wenn Review oder Repo starten. Keine Weitergabe. Keine Secrets ins Formular.

Wir nutzen deine Angaben nur, um deine Anfrage zu beantworten. Details in der Datenschutzerklärung.