---
title: "Mehrere Coding-Agenten, ein Repository: Claims statt Sperren"
description: "Wie Foxl Code verhindert, dass parallele Coding-Agenten dieselben Dateien bearbeiten: Claims ohne Sperre, Glob-Überschneidung, Freigabe nach dem Lauf, Kosten auf D1."
author: "Foxl Team"
date_published: "2026-10-23"
date_modified: "2026-10-27"
canonical_url: "https://foxl.ai/de/blog/parallel-coding-agents-file-claims"
markdown_url: "https://foxl.ai/de/blog/parallel-coding-agents-file-claims/index.md"
image: "https://foxl.ai/blog/parallel-coding-agents-file-claims-cover.png"
social_image: "https://foxl.ai/blog/social/parallel-coding-agents-file-claims.png"
content_type: "Deep dive"
topics: ["Coding agents","Multi-agent","Claude Code","Codex","Cloudflare D1"]
products: ["Foxl Code"]
---

<!-- Generated by scripts/blog-publishing.mjs; do not edit. -->

# Mehrere Coding-Agenten, ein Repository: Claims statt Sperren

> Parallele Coding-Agenten kollidieren beim Merge, weil keiner weiß, was die anderen bearbeiten. Die Cloud-Agenten von Foxl Code beanspruchen jetzt die Dateien, die sie ändern wollen, und erfahren, welche deiner anderen aktiven Agenten schon einen überlappenden Pfad beansprucht haben. Ein Claim wird in jedem Fall festgehalten und sperrt nichts; bei einem Konflikt wird der Agent angewiesen, dem Inhaber die Änderung zu schicken, zu warten oder dich zu fragen. Echte Ausgabe des ausgelieferten Befehls, die Glob-Regeln, die Datenbankkosten und die Frage, ob sich Agenten wirklich an die Regel halten. Die können wir noch nicht beantworten.

- Author: Foxl Team
- Published: 2026-10-23
- Last reviewed: 2026-10-27
- Reading time: 10 minutes
- Canonical HTML: [https://foxl.ai/de/blog/parallel-coding-agents-file-claims](<https://foxl.ai/de/blog/parallel-coding-agents-file-claims>)

![Eine Datei, an deren Ecke die Anhänger zweier Agenten gebunden sind, einer blau, einer orange, und daneben liegt ein offenes Vorhängeschloss: Beide Claims auf die Datei sind festgehalten, und nichts ist gesperrt.](<https://foxl.ai/blog/parallel-coding-agents-file-claims-cover.png>)

Lass mehrere Coding-Agenten in einem Repository arbeiten, und sie kollidieren beim Merge, weil keiner weiß, was die anderen gerade bearbeiten. Foxl Code führt Coding-Agenten wie Claude Code und Codex in der Cloud aus, und seit v0.9.3-beta.5 wird jeder Agent angewiesen, die Pfade, die er ändern will, vor dem Bearbeiten mit `foxl-agents claim <paths>` zu beanspruchen. Hat ein anderer Agent desselben Nutzers, der noch läuft (ein aktiver Agent), schon einen überlappenden Pfad beansprucht, nennt die Antwort diesen Agenten und die Notiz, die er hinterlassen hat. Gesperrt wird nichts. Bei einem Konflikt wird der Agent angewiesen, dem Inhaber die Änderung zu schicken, die er braucht, zu warten, bis der Inhaber den Claim freigibt, oder den Nutzer zu fragen, und seine eigenen Claims verschwinden, wenn sein Lauf endet.

## Warum parallele Coding-Agenten kollidieren

Jeder Agent arbeitet in seinem eigenen Checkout auf seinem eigenen Branch, also hindert nichts zwei von ihnen daran, dieselbe Datei zu ändern. Git meldet einen Textkonflikt, wenn der zweite Pull Request gemergt wird, nachdem beide Agenten fertig sind und bezahlt wurden. Einen semantischen Konflikt, bei dem zwei Pull Requests jeweils ihre Checks bestehen, aber den Build brechen, sobald beide gemergt sind, meldet gar nichts, bis jemand beide merged. Claims fangen diese Art nur ab, wenn die beiden Agenten dieselben Pfade anfassen.

Unser eigenes Setup hat uns gezeigt, was hilft. Wir bauen Foxl mit 15 bis 20 Sitzungen von Claude Code, die parallel auf seinem Repository laufen, und in 14 Tagen haben sie einander 4.773 Nachrichten geschickt. Was sie davon abhielt, sich gegenseitig zu überschreiben, war eine gemeinsame Zuständigkeitsliste. Eine Koordinator-Sitzung hält fest, welcher Sitzung welche Dateien gehören (und bei einer Datei, die viele Sitzungen anfassen, welche Teile davon), und eine Sitzung, die eine Änderung in einer Datei braucht, die ihr nicht gehört, schickt die Änderung an die zuständige Sitzung, statt sie selbst zu machen. Vor der Liste bearbeiteten Sitzungen gleichzeitig dieselben Dateien und merkten es erst beim Merge. Die Liste hatte ihren eigenen Preis: Von den 123 Malen, die eine Sitzung in diesen 14 Tagen blockiert war, warteten 33 auf eine Antwort des Koordinators.

Den Nachrichtenteil hatte Foxl Code schon: einen Befehl `foxl-agents`, mit dem jeder Cloud-Agent die anderen aktiven Agenten des Nutzers auflisten und ihnen eine Nachricht schicken kann. Claims fügen die Zuständigkeitsliste ohne Koordinator hinzu: Jeder Agent sagt, was er anfassen wird, und die Datenbank antwortet in einer einzigen Anfrage.

## Warum Claims statt Sperren?

Eine Sperre funktioniert nur, wenn jeder Agent sie beachtet und jeder Agent sie wieder freigibt. Ein Coding-Agent, der abstürzt, sein Budget aufbraucht oder abgebrochen wird, gibt nichts frei, also braucht eine Sperre ein Timeout, und ein Timeout, das für einen echten Lauf lang genug ist (unsere können über sieben Stunden dauern), blockiert alle so lange. Zwei Agenten, die jeweils eine Zeile in der Datei des anderen brauchen, würden ewig aufeinander warten. Und einem Agenten, dessen Sperre abgelehnt wird, bleibt nichts anderes übrig, als aufzuhören.

Claims umgehen jedes dieser Probleme. Ein abgestürzter Inhaber zählt nicht mehr, sobald sein Lauf nicht mehr aktiv ist, es gibt also kein Timeout abzusitzen. Ein Claim, der sich mit einem anderen überschneidet, wird nicht abgelehnt; er wird festgehalten, und die Überschneidung geht an den Agenten zurück, der gefragt hat, mit Task-ID, Titel, beanspruchten Pfaden und Notiz des Inhabers. Und ein Agent, der auf einen Konflikt stößt, wird zuerst angewiesen, dem Inhaber die nötige Änderung zu schicken, sodass zwei Agenten, die gegenseitig ihre Dateien brauchen, etwas anderes zu tun haben als zu warten, auch wenn nichts sie davon abhält, trotzdem beide zu warten. Das sind die Anweisungen, die jeder Agent bekommt, Wort für Wort:

```
- Before you start editing, claim the files and directories you expect to
  change, in one command: `foxl-agents claim <path>... --note "<why>"`. A
  directory claims everything under it; `*`, `?` and `**` globs work. Claim
  what you will change, not the whole repository, and claim again if your
  plan grows.
- The answer names any other live agent that already claimed an overlapping
  path. On a CONFLICT, do not edit those files: send the holder the exact
  change you need with `foxl-agents send <task-id> "<the change>"`, wait until
  it releases them (check `foxl-agents claims` at a natural checkpoint, never
  in a loop or behind a `sleep`), or tell the user. A claim is information,
  not a lock.
- `foxl-agents release <path>...` drops a claim you no longer need. Every
  claim you hold is dropped when your run ends.
```

Diese Zeilen werden an die Anweisungsdatei auf Nutzerebene angehängt, die jede CLI liest: CLAUDE.md für Claude Code und AGENTS.md für Codex, Kiro, Cursor, Hermes und OpenCode. Derselbe Mechanismus muss sechs verschiedene CLIs erreichen, und deshalb ist `foxl-agents` ein Shell-Befehl und kein MCP-Server. Jede Coding-CLI kann einen Shell-Befehl ausführen, also funktioniert ein Skript in allen sechs, ohne dass man jede einzeln so konfigurieren muss, dass sie einen Server lädt.

## Was ein Agent ausführt und was er sieht

Unten steht die echte Ausgabe des ausgelieferten Befehls, ausgeführt von einem Skript statt von einem Agenten, für zwei Demo-Tasks in einem Demo-Repository. Task A ist ein Codex-Task, der Rate Limiting hinzufügt, und Task B ist ein Claude-Code-Task, der dem Users-Endpoint Paginierung hinzufügt. Server, Datenbank und Befehl sind dieselben, die auch die Cloud-Agenten bekommen.

![Terminalausgabe. Task A beansprucht src/api/middleware.ts und src/api/routes.ts mit der Notiz „adding a token bucket per API key“ und erfährt, dass kein anderer aktiver Agent einen überlappenden Pfad beansprucht hat. Task B beansprucht dann das Verzeichnis src/api/ und bekommt ein CONFLICT, das Task A, ihren Titel, die beiden Dateien und ihre Notiz nennt, gefolgt von der Anweisung, dem Inhaber die Änderung zu schicken, auf eine Freigabe zu warten oder dem Nutzer Bescheid zu geben. Eine Liste der aktiven Claims zeigt die Claims beider Tasks.](<https://foxl.ai/blog/parallel-coding-agents-file-claims-terminal.png>)

_Abbildung 1. Aufgezeichnete Ausgabe des ausgelieferten Befehls gegen den ausgelieferten Server, lokal in workerd (der Workers-Runtime von Cloudflare), 23. Oktober 2026. Auch der Claim von Task B ist festgehalten._

Task B hat `src/api/` mit einem abschließenden Schrägstrich beansprucht, der ein Verzeichnis kennzeichnet, und der Server hat das als `src/api/**` gespeichert. Ohne den Schrägstrich hätte der Befehl `/**` selbst angehängt: Er läuft im Checkout, dem einzigen Ort, der eine Datei von einem Verzeichnis unterscheiden kann. Der Befehl schreibt außerdem jeden Pfad relativ zur Wurzel des Repositorys um, egal in welchem Arbeitsverzeichnis, und lehnt einen Pfad außerhalb des Checkouts ab, bevor er irgendetwas sendet.

Der Konflikt nennt die beiden Dateien von Task A und ihre Notiz, und Task B entscheidet anhand der Notiz. Hier könnte sie die Middleware in Ruhe lassen und Task A die eine Änderung schicken, die sie dort braucht, oder mit dem eigenen Handler des Endpoints anfangen und wieder nachsehen, sobald Task A freigegeben hat.

## Wie erkennt man, ob sich zwei Globs überschneiden?

Zwei Claims überschneiden sich, wenn mindestens ein Pfad auf beide passt. Die Grammatik ist absichtlich klein gehalten:

- ein einfacher Pfad ist ein Glob ohne Platzhalter;
- `*` passt innerhalb eines Pfadsegments;
- `?` passt auf genau ein Zeichen;
- ein Segment, das genau `**` ist, passt auf beliebig viele ganze Segmente;
- jedes andere Zeichen ist wörtlich gemeint, `[id].tsx` ist also ein Dateiname und keine Zeichenklasse.

Das liefert der ausgelieferte Matcher für ein paar Paare:

| Claim A | Claim B | Überschneidung |
| --- | --- | --- |
| `src/api/**` | `src/api/users.ts` | ja |
| `src/*.ts` | `src/api/users.ts` | nein, `*` bleibt in einem Segment |
| `src/**/*.test.ts` | `src/api/*.ts` | ja, beide passen auf `src/api/x.test.ts` |
| `docs/**` | `src/**` | nein |
| `src/app/[id]/page.tsx` | `src/app/a/page.tsx` | nein, `[id]` ist wörtlich |
| `**/*.md` | `docs/guide.md` | ja |

Eine Überschneidung führt nie dazu, dass ein Claim abgelehnt wird, ein paar Formen aber schon:

- ein Glob nur aus Platzhaltern, der `**` enthält, etwa `**` oder `**/*`, weil er das ganze Repository beanspruchen würde;
- ein Pfadsegment `..`, ein Backslash oder ein Steuerzeichen;
- ein führendes `!`, weil es hier keine Negation ist und auch nicht wie eine aussehen soll.

Ein Task hält höchstens 50 Claims mit je höchstens 200 Zeichen, dazu Notizen mit bis zu 280 Zeichen.

Der Vergleich ist gedeckelt, damit eine ungewöhnliche Menge von Claims den Server nicht viel CPU kosten kann. Zwei Claims, deren führende wörtliche Segmente sich unterscheiden (`docs/**` und `src/**`), werden sofort ausgeschlossen. Andernfalls geht der Server memoisiert über Paare von Segmenten und, innerhalb eines Segments, über Paare von Zeichen. Alle Vergleiche in einer Anfrage teilen sich ein Budget von 50.000 Schritten, und ein Paar, das das Budget nie erreicht, wird als mögliche Überschneidung gemeldet, statt unter den Tisch zu fallen. So erfährt der Agent auch bei einer Anfrage, der das Budget ausgeht, davon.

## Wann ein Claim endet

Ein Claim gehört zu einem Lauf. Wenn der Lauf endet, verwirft der Task jeden Claim, den er angelegt hat, im selben Schritt, der den Lauf als beendet festhält. Zwei Prüfungen beim Lesen decken einen Lauf ab, der diesen Schritt nie erreicht hat: Ein Claim, dessen Inhaber nicht mehr aktiv ist, wird ignoriert, ebenso ein Claim, der älter ist als die längste mögliche Dauer eines Laufs, 7 Stunden 20 Minuten. Claims haben dieselbe Sichtbarkeit wie Nachrichten: Nur die aktiven Agenten eines einzigen Nutzers, die über dieselbe Installation der GitHub App auf demselben Repository arbeiten, sehen gegenseitig ihre Claims.

![Zwei Agenten und eine Claims-Tabelle. Agent A beansprucht zwei Dateien und erfährt, dass es keine Überschneidung gibt. Agent B beansprucht das Verzeichnis um sie herum, sein Claim wird geschrieben, und er bekommt einen Konflikt zurück, der Agent A nennt. Agent B hat dann drei Möglichkeiten: Agent A die Änderung schicken, auf die Freigabe von Agent A warten oder die Person fragen. Wenn ein Lauf endet, werden seine Claims entfernt.](<https://foxl.ai/blog/parallel-coding-agents-file-claims-flow.png>)

_Abbildung 2. Ein Konflikt geht an den Agenten zurück, der gefragt hat. Nichts wird wegen einer Überschneidung abgelehnt, und nichts wartet auf eine Sperre._

## Was es auf einem kostenlosen Datenbanktarif kostet

Claims liegen in einer Tabelle mit einem Index auf (Nutzer, Repository, Erstellungszeit), und nichts fragt sie per Polling ab. Jeder Lesezugriff fragt nur nach Claims, die in den letzten 7 Stunden 20 Minuten angelegt wurden, und die Erstellungszeit ist die letzte Spalte des Index, also fallen ältere Zeilen aus dem Bereich, den die Datenbank durchsucht. Veraltete Claims, die niemand freigegeben hat, fügen einem Lesezugriff eine Zeile hinzu, egal ob es 1.000 oder 2.000 davon gibt; wir haben beides gemessen.

Wir messen das, weil Foxl auf dem kostenlosen Tarif von Cloudflare läuft, bei dem sich alle D1-Datenbanken eines Kontos 5 Millionen gelesene und 100.000 geschriebene Zeilen pro Tag teilen und das Konto 100.000 Worker-Anfragen pro Tag bekommt. Die Zahlen unten stammen von D1, lokal in workerd ausgeführt, der Runtime von Cloudflare, und sind noch nicht mit den eigenen Metriken des D1 in Produktion abgeglichen:

| Aufruf | gelesene Zeilen | geschriebene Zeilen |
| --- | --- | --- |
| N Pfade beanspruchen | etwa 2 pro aktivem Claim auf dem Repository, plus etwa 1 pro Pfad und ein paar feste Lesezugriffe | 2 pro Pfad |
| Claims auflisten | 1 + 2 pro aktivem Claim | 0 |
| freigeben | etwa 1 pro Pfad | 1 pro freigegebener Zeile |
| ein Lauf endet, der nie etwas beansprucht hat | 0 | 0 |

Bei etwa 50 Cloud-Tasks am Tag über alle Nutzer und je zwei Claim-Aufrufen sind das 100 Aufrufe am Tag. Jeder Aufruf sind zwei Worker-Anfragen, eine bei code.foxl.ai und eine über einen internen Hop zum Server, also etwa 200 Anfragen oder 0,2 % der 100.000 des kostenlosen Tarifs. Selbst wenn jeder dieser Aufrufe so viel kosten würde wie der eines vielbeschäftigten Nutzers im schlimmsten Fall (zehn Agenten mit je fünf Claims auf einem Repository), würde der Tag etwa 11.000 Zeilen lesen (0,2 % der 5 Millionen) und etwa 830 schreiben (0,8 % der 100.000).

## Halten sich die Agenten wirklich an die Regel?

Das wissen wir noch nicht, und diese Phase ist dafür gebaut, es herauszufinden. Unsere eigenen lokalen Sitzungen brauchten einen Koordinator, um dieselbe Regel durchzusetzen, also gehen wir nicht davon aus, dass sechs verschiedene CLIs vor dem Bearbeiten beanspruchen und bei einem Konflikt zurückstecken, nur weil es in ihren Anweisungen steht. Jeder Konflikt schreibt einen Audit-Eintrag (jede Serverinstanz überspringt eine Wiederholung für denselben Task und dieselben Inhaber innerhalb von zehn Minuten), und das tut auch jede Nachricht, die ein Agent einem anderen schickt. Ob ein Agent dem Inhaber geschrieben hat, zeigt das Audit-Log, ob er seinen Claim freigegeben hat, zeigt die Claims-Tabelle, und ob er die Datei trotzdem bearbeitet hat, zeigt der Diff des Pull Requests.

Die nächste Phase hängt davon ab, was das zeigt. Wenn Agenten Claims respektieren, soll der Teil von Foxl Code, der eine Anfrage auf mehrere Agenten aufteilt, jedem Teil-Task eine Dateiliste geben und Teil-Tasks, die sich überschneiden, nacheinander statt gleichzeitig ausführen. Stand 23. Oktober 2026 ist die Produktionstabelle leer, weil seit dem Deployment der Funktion kein Cloud-Task gestartet wurde.

Wer etwas Ähnliches baut: Die drei Eigenschaften, die wir behalten würden, sind, dass ein Claim immer festgehalten wird, dass eine Überschneidung mit Inhaber und Notiz zurückkommt und dass ein Claim nur so lange gilt wie sein Lauf. Unser Beitrag zum Start von Foxl Code beschreibt die Agentenschleife selbst, die [auf ein Ziel hin abgleicht, statt jedem Schritt zu vertrauen](<https://foxl.ai/blog/foxl-code-autonomous-agents>) (auf Englisch).

## Quellen und weiterführende Lektüre

1. [Cloudflare D1: Preise und Limits des Free-Tarifs](<https://developers.cloudflare.com/d1/platform/pricing/>) - Documentation
2. [Release Foxl v0.9.3-beta.5](<https://github.com/foxl-ai/foxl/releases/tag/v0.9.3-beta.5>) - Release