CommunitySchreiben & Editierengithub.com

ssheleg/agent-sync

Mehrere KI-Agenten, ein Repository, keine Kollisionen — Leases mit TTL, kollisionsfreie ID-Reservierung, ein Ausführungs-Journal und ein generiertes Board über einer erweiterbaren Wissens-Cloud. Teil des sshlg-skills-Bundles.

Was ist agent-sync?

Das Skill `agent-sync` löst das zentrale Problem kollaborativer KI-Agenten in einem einzigen Git-Repository: Wettlaufsituationen und Konflikte. Es erzwingt eine Architektur mit zwei Ebenen: Git als dauerhaftes Aufzeichnungsmedium und eine Cloud (z. B. Outline) als flüchtige Koordinationsebene, auf der Leases mit einer TTL (Time-to-Live) vergeben werden. Agenten können IDs reservieren (`reserve`), Leases für Aufgaben übernehmen (`acquire`) und gemeinsam genutzte Dateien schützen (`guard`), ohne dass Änderungen überschrieben werden. Jede Sitzung besitzt eine eindeutige Identität, abgeleitet aus Umgebungsvariablen und dem Agenten-Prozess, sodass Leases exklusiv bleiben. Ein `status`-Befehl bietet Echtzeit- und historische Einblicke, und mit `merge` können Konflikte vor dem eigentlichen Zusammenführen erkannt werden. Das Skill unterstützt Claude Code (mit Hooks) und andere Agenten-Plattformen über die Skripte in `scripts/agent_sync.py`; für andere Plattformen muss `guard` manuell ausgeführt werden. Der gesamte Workflow wird durch einen umfassenden `check`-Befehl validiert, der die Selbstheilung und Einhaltung der Regeln sicherstellt.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add ssheleg/agent-sync

Installed? Explore more Schreiben & Editieren skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

agent-sync — ein Projekt, viele Agenten, keine Kollisionen

Zwei Ebenen und eine Regel dazwischen:

Git ist die Aufzeichnungsebene. Die Cloud ist die Koordinationsebene. Eine Tatsache, die überleben muss, wird zuerst in Git geschrieben und von der Cloud referenziert. Eine Tatsache darüber, wer gerade was tut, lebt in der Cloud und läuft ab.

Kein Cloud-Objekt ist jemals der alleinige Aufbewahrungsort einer dauerhaften Tatsache. Alles unten Existierende dient dazu, dies wahr zu halten, während mehrere Agenten gleichzeitig schreiben.

Vier Fallen — lesen Sie diese, bevor Sie irgendetwas anderes tun

1. Die Wissensbasis entscheidet niemals über einen Lease. Sie kann nicht: Zwölf gleichzeitige Anhänge an ein Outline-Dokument ergaben zwölf Erfolge und hinterließen drei Zeilen. Ausschluss kommt von etwas mit echtem Compare-and-Swap. Die Aufzeichnungsebene trägt die Aufzeichnung und sonst nichts. Vollständige Messungen in references/lease-protocol.md.

2. Wissen, welchen Lease Sie haben, und das auch sagen. leaseBackend: "local" ist eine atomare Dateierstellung — exklusiv zwischen Prozessen auf einem Dateisystem, beratend über Maschinen hinweg. leaseBackend: "git" verschiebt einen Ref, und die „non-fast-forward“-Ablehnung des Remotes ist ein Compare-and-Swap — exklusiv über Maschinen hinweg. acquire gibt aus, welcher verwendet wird. Ein vorgetäuschter Lease ist schlimmer als kein Lease: Der andere Agent hört auf zu prüfen.

acquire schreibt den Anspruch auch in die Roadmap, und release stellt genau das wieder her, was da war — eine Zeile, eine Zelle, Verweigerung bei Mehrdeutigkeit, git diff leer nach einem Rundgang. Lesen Sie references/roadmap.md, bevor Sie claimTags konfigurieren oder eine Aufgabe schließen; das Schließen ist eine Aussage über die Arbeit und bleibt Ihre.

Arbeiten Sie auf einem Branch; der Integrationsbranch ist die stabile Basis eines anderen. acquire schreibt den Anspruch nur dort hinein; auf jedem anderen Branch bleibt der Inhaber in der Koordinationsebene, wo status ihn jedem Agenten anzeigt, ohne dass jemand Ihren Branch abrufen muss. Auf einen Branch übertragen, ist ein Anspruch unsichtbar bis zum Merge und verwandelt die gemeinsame Roadmap in eine Datei, die zwei Branches bearbeiten. Landen Sie Arbeit mit merge: Konflikte werden von git merge-tree berechnet, bevor etwas berührt wird, benannt und verweigert, falls vorhanden, der Merge wird in docs/MERGES.md aufgezeichnet (letzte Tage vollständig, ältere beim Schreiben komprimiert), der --key-Lease wird freigegeben. merges teilt dem nächsten Agenten mit, was gelandet ist, während er weg war. Lesen Sie references/branching.md, bevor Sie mergen.

3. Hooks existieren nur in Claude Code. Andernorts blockiert nichts eine bewachte Bearbeitung: Führen Sie guard selbst aus und zeichnen Sie den Lauf als ungated auf. Beschreiben Sie ein Projekt nicht als geschützt, wenn es das nicht ist.

4. Parsen Sie großzügig und bezeichnen Sie ein unlesbares Protokoll niemals als verlorenes Rennen. Der Store schreibt um, was Sie geschrieben haben — Outline macht aus einem --Aufzählungspunkt * . Senden Sie - aus, akzeptieren Sie -/*/+, zählen Sie alles, was wie ein Eintrag aussieht, aber fehlschlägt, und scheitern Sie lautstark, wenn mehr als 2 % nicht parsbar sind. Die Meldung lost zu melden, wenn die Wahrheit unlesbar ist, nennt einen Inhaber, der nicht existiert. Achten Sie auf einen stillen Vorfilter: Ein continue vor dem regulären Ausdruck verbirgt schlechte Zeilen vor dem Zähler, der gebaut wurde, um sie aufzudecken.

Dies in JEDES Projekt einbringen — die gesamte Kette

scaffold  → Erstellen der Dokumentationsarchitektur, nur wo sie fehlt
adopt     → Das Repository lesen, eine Konfiguration vorschlagen, nichts schreiben
init      → Die genehmigte Konfiguration + die git-vergessene Umgebungsdatei schreiben
            (Operator fügt den Token ein — niemals Sie)
reconcile --set-baseline    → Verlauf in einen gezählten Rückstand verwandeln, einmal
setup     → Den Snapshot generieren, der die Verdrahtung dieses Projekts beschreibt
check     → Das Ganze validieren; nicht Null, wenn es nicht gesund ist

check ist das, was das Skill autark macht. Es weigert sich, ein Setup als gesund zu bezeichnen bei einer Regel, die nichts schützt (ein Register, eine guard-Glob, ein Claim-Muster, ein Gate oder eine Mirror-Quelle, die auf etwas zeigt, das nicht vorhanden ist), bei fehlenden Anmeldeinformationen, bei einer von Git verfolgten Umgebungsdatei — der eine nicht wiederherstellbare Fehler hier — bei einem veralteten oder nicht verknüpften Snapshot und bei einem Register ohne Baseline. Es benennt jedes einzeln; jedes ist während des eigenen Adoptionswerkzeugs tatsächlich fehlgeschlagen.

Führen Sie check nach der Adoption, nach der Änderung der Konfiguration und in CI aus.

scaffold überschreibt niemals. Es erzeugt ein Entscheidungsregister mit einer Zuteilungszeile und einer AGENTS.md, die auf den Snapshot verweist, und lässt jede vorhandene Datei unberührt — ein Werkzeug, das bei der Adoption die eigenen Konventionen eines Projekts überschreibt, ist schlimmer als eines, das nichts tut.

Bestehendes Projekt: mit adopt beginnen

Führen Sie adopt vor init aus. Es liest das Repository und gibt aus, was es gefunden hat — ID-Register, Registry-Dateien, Gates — plus die Entscheidungen, die es sich weigert, für Sie zu treffen — und schlägt dann eine Konfiguration vor.

python3 "$SKILL_DIR/scripts/agent_sync.py" adopt

Bestätigen Sie die Register und bewachten Dateien zuerst mit dem Operator: Ein Register, das auf die falsche Datei zeigt, macht jede spätere Prüfung zuverlässig falsch, und eine bewachte Liste, die eine gemeinsam genutzte Datei übersieht, lässt den einzigen Ort, an dem Kollisionen auftreten, ungeschützt. In einem Untermodul deklariert es keine Register: Entscheidungen gehören zum übergeordneten Repository. Dann nehmen Sie die obige Kette ab init.

Erster Befehl in einem Projekt: init

Führen Sie niemals etwas anderes gegen ein nicht initialisiertes Projekt aus. init ist der Ort, an dem die Speicherfrage einmal gestellt, beantwortet und niedergeschrieben wird.

Fragen Sie den Operator diese zwei Dinge im Chat — raten Sie nicht, wählen Sie keine Voreinstellung:

  1. Wo soll der Koordinationszustand leben?

    • eine Wissens-Cloud (outline) — die gemeinsame Aufzeichnung, das Bewusstsein und das Board über Maschinen hinweg. Sie entscheidet nicht über Leases; nichts in ihr kann das (Falle 1);
    • oder lokale Dateien (fs) — keine Anmeldeinformationen und keine Sichtbarkeit für einen Agenten auf einer anderen Maschine: kein gemeinsames Bewusstsein, keine Signale über Repos hinweg, kein gemeinsames Board.

    Der Lease wird separat durch leaseBackend entschieden (Falle 2), und gated folgt dieser Wahl, niemals der Aufzeichnungsebene. Melden Sie die Garantie, die Sie tatsächlich haben, nicht die stärkere, die die Aufzeichnungsebene suggeriert.

  2. Wenn Cloud: die Instanz-URL. Die URL ist Konfiguration, kein Geheimnis, daher dürfen Sie sie schreiben. Der Token ist es nicht — Sie fragen nie im Chat danach, lesen ihn nie zurück und platzieren ihn nie selbst.

Dann führen Sie es mit ihren Antworten aus:

python3 "$SKILL_DIR/scripts/agent_sync.py" init --backend outline --url https://<ihre-instanz>
python3 "$SKILL_DIR/scripts/agent_sync.py" init --backend fs

init schreibt .claude/agent-sync.json (Struktur, committet), schreibt .env.agent-sync mit den Schlüsseln und einer leeren Tokenzeile (Identität, Modus 600), fügt .env.agent-sync und .agent-sync/ zu .gitignore hinzu und gibt dann genau das aus, was der Operator selbst tun muss — den Token in seiner eigenen Instanz erstellen und in diese eine Zeile einfügen. Es überschreibt niemals eine vorhandene Konfigurations- oder Umgebungsdatei ohne --force.

Übermitteln Sie diese abschließenden Anweisungen wörtlich an den Operator. Das Einfügen des Tokens in die Datei ist ihr Schritt, und das Design hängt davon ab, dass er ihnen gehört.

Dann, vor jeder Sitzung

python3 "$SKILL_DIR/scripts/agent_sync.py" status

Idempotent. Untersucht, repariert, meldet, nennt genau EINE nächste Aktion — und trägt das Urteil von check mit sich, sodass der Befehl, den jede Sitzung ausführt, und derjenige, der das Setup validiert, nicht zwei Antworten über ein Projekt geben können.

Lesen Sie die beiden Bewusstseinsabschnitte, die es ausgibt — sie sind der Punkt, nicht die Dekoration.

  • Andere Läufe, die gerade an diesem Projekt arbeiten. Wer hält was, in dieser Minute. Übernehmen Sie diese nicht und "schauen Sie nicht nur" auf die Dateien, die sie abdecken. Ein Lease, den Sie nicht sehen können, blockiert Sie; ein Lease, den Sie sehen können, koordiniert Sie.
  • Neu seit Ihrem letzten Blick. Repo-übergreifende Abhängigkeitsbewegungen, die gelandet sind, während Sie weg waren. Eine Abhängigkeit, die sich bewegt hat, könnte das, was Sie geplant haben, entblocken — oder ungültig machen. Diese Liste ist pro Lauf mit einem Wasserzeichen versehen, sodass sie ruhig bleibt, bis sich tatsächlich etwas ändert; wenn sie spricht, ist es wichtig.

Ein Agent, der diesen Block überspringt, wird Arbeit wiederholen, die jemand anderes erledigt, und auf einen Abhängigkeitszustand reagieren, der sich vor einer Stunde geändert hat.

Was status sonst noch entscheidet: Keine Anmeldeinformationen → abgespeckter Modus, gemeldet, und es wird fortgesetzt (ein kleinerer Modus, kein Fehler); task-pipeline nicht vorhanden → es gibt die Installationszeile aus und stoppt. Improvisieren Sie keinen Ersatzablauf — ohne diese Stufen gibt es nichts, woran man binden könnte.

npx sshlg-skills install

Die Befehle

BefehlTut
initZuerst ausführen. Fragen, wo der Zustand lebt, Konfiguration + git-vergessene Umgebungsdatei schreiben, den Schritt des Operators ausgeben
statusUntersuchen, reparieren, melden, eine nächste Aktion nennen
bootstrapDen Cloud-Container erstellen und die ID zur Eingabe in die Umgebungsdatei ausgeben
acquire <KEY>Den Lease für eine Aufgaben-ID übernehmen. Gibt gewonnen oder verloren <Inhaber> aus
renew <KEY>Den Lease verlängern. Der PostToolUse-Hook erledigt dies für Sie
release <KEY>Den Lease zurückgeben. Immer tun, auch bei Fehlern
reserve <REG>Die nächste ID in einem Register reservieren (DEC, OQ, DEP, …). Gibt die ID aus
release-id <REG> <ID>Eine ID zurückgeben, die Sie nicht in Git geschrieben haben
journal <text>Eine Zeile an das Journal dieses Laufs anhängen
record <text>Anhängen, was Sie tatsächlich gebaut haben — --decision DEC-…, --files a,b
reconcileAbsicht (Git) vs. tatsächlich gebaut (Cloud). --set-baseline einmal pro Projekt
signal <DEP-ID> <state>Eine Repo-übergreifende Abhängigkeit verschieben: filed/accepted/delivered/closed/refused
guard <path>Antworten, ob dieser Lauf diesen Pfad schreiben darf. Exit 0 = ja, 2 = nein
boardDas gemeinsame Board und die Seite dieses Repos neu generieren. --mirror rendert auch die konfigurierten Git-Dokumente in die Ebene
whoamiDie ID dieses Laufs und seine gehaltenen Leases ausgeben
setupDen generierten Snapshot der Verdrahtung dieses Projekts zum Lesen durch Agenten schreiben
adoptEin bestehendes Projekt inspizieren und eine Konfiguration vorschlagen — schreibt nichts
mergeDiesen Branch landen: lokalen Ziel-Fast-Forward, Konflikte vor Berührung von irgendetwas geprüft, Merge-Log geschrieben, der --key-Lease freigegeben. --summary, --dry-run, --push
mergesWas gelandet ist, während Sie auf Ihrem Branch waren. --all enthält den komprimierten Schwanz
checkDas gesamte Setup Ende-zu-Ende validieren. Nicht Null, wenn es nicht gesund ist
scaffold [--full]Nur das Fehlende erstellen, niemals eine Zeile über etwas, das existiert. --full erzeugt auch das Entscheidungsregister, den Index, das Abhängigkeitsboard, das Datenmodell mit seinem Entitätsregister und das Dokumentations-Gate
finish [--gates]Ist die Arbeit abgeschlossen — jedes Repository sauber, gepusht und referenziert, kein Lease mehr gehalten. check beantwortet, ob das Projekt richtig verdrahtet ist; dies beantwortet, ob Sie fertig sind

$SKILL_DIR ist das eigene Verzeichnis dieses Skills: ${CLAUDE_PLUGIN_ROOT}/skills/agent-sync unter dem Claude Code Plugin, ~/.agents/skills/agent-sync anderswo. Lösen Sie es einmal pro Sitzung auf und verwenden Sie es wieder — raten Sie keinen Pfad. Jeder Befehl liest .claude/agent-sync.json aus dem Projektstammverzeichnis und benötigt keine anderen Argumente als die aufgeführten.

Eine Identität pro Sitzung und wie sie bestimmt wird

Ein Lease ist nur ein Lease, wenn zwei Agenten zwei Identitäten erhalten. Die Reihenfolge ist hier wichtig, und beide Enden haben schon zugeschlagen: Die Ableitung der ID allein aus CLAUDE_SESSION_ID ergab eine Sitzung zwei Identitäten — sie erwarb als eine und wurde von ihrer eigenen Wache als die andere abgelehnt — und das Beibehalten einer ID pro Checkout ergab zwei Sitzungen eine Identität, was schlimmer ist. Der zweite ist still: Beide Sitzungen erwerben, beide werden bewacht, und release nimmt einen Lease, den der Aufrufer nie hatte.

Die Reihenfolge ist: AGENT_SYNC_RUN_ID · CLAUDE_SESSION_ID · die Sitzung, die diese Shell gestartet hat · geteilt.

Das dritte ist wichtig, weil ein normaler Shell-Befehl keine Sitzungs-ID hat und ein Hook eine hat. Also stempelt SessionStart .agent-sync/sessions/<CLI pid> mit der ihm bekannten Sitzung, und ein späterer Befehl findet sich, indem er seine eigene Prozess-Vorfahren zu einer gestempelten PID durchläuft. Warum das und nicht Kommandozeilen-Parsing: references/earned-rules.md.

Wenn keiner der vier etabliert werden kann, sagt der Lauf dies — "Diese Identität wird mit jeder anderen Sitzung in diesem Checkout geteilt" — anstatt einen geteilten Eintrag als Trennung darzustellen.

Beanspruchen — die Form, die zählt

acquire → die Arbeit erledigen → release

Überspringen Sie niemals release, auch nicht bei Fehlern: Ein aufgegebener Lease blockiert die Aufgabe, bis seine TTL abläuft, und der nächste Agent kann nicht zwischen "in Bearbeitung" und "vor einer Stunde abgestürzt" unterscheiden.

Der Lease ist nicht der Anspruch. Der Lease sagt, wer ihn jetzt hält, und läuft ab; der dauerhafte Anspruch ist der Tag in Git, der durch acquire geschrieben und durch release gelöscht wird. Eine Tatsache, ein Zuhause — erfinden Sie keinen dritten Ort, der Eigentum aufzeichnet.

Lesen Sie references/lease-protocol.md, bevor Sie Übernahme, Ablauf, Diebstahl oder ID-Zuteilung ändern.

Bewachte Dateien

Die Konfiguration listet Registry-Dateien auf, die mehrere Agenten bearbeiten. Vor dem Bearbeiten einer solchen:

python3 "$SKILL_DIR/scripts/agent_sync.py" guard docs/DECISIONS.md

Exit 2 betrifft diesen Lauf: Er hält keinen Lease — nicht, dass jemand anderes diese Datei hält. Ein Lease deckt jede bewachte Datei ab; halten Sie einen oder schreiben Sie keine. Eine Ablehnung nennt den anderen Lauf und seinen Schlüssel, weil "r-x hält einen Lease" neben einem Pfad als "r-x hält diese Datei" wiederholt wird. Bearbeiten Sie trotzdem nicht und "korrigieren Sie nicht nur eine Zeile" — eine überschriebene Entscheidung sieht genauso aus wie eine Entscheidung.

Der PreToolUse-Hook von Claude Code führt dies für Sie aus. Andernorts nichts.

Reservieren einer ID

Das Lesen einer Zeile "Nächste freie ID" ist keine Reservierung — zwei Agenten lesen dieselbe Nummer und beide verwenden sie.

python3 "$SKILL_DIR/scripts/agent_sync.py" reserve DEC   # → DEC-0216

Die Zuteilung erfolgt positionsabhängig über das zusammengeführte Protokoll — jede Partition, niemals nur die dieses Laufs —, sodass jeder Agent dieselbe Antwort berechnet. Reserviert und nicht in Git geschrieben? Führen Sie release-id aus, oder die Nummer ist ein Loch, das das Board als Leck meldet.

Nichts in einem Protokoll wird jemals bearbeitet oder gelöscht

Protokolle werden der Reihe nach abgespielt, daher überschreibt eine Bearbeitung stillschweigend eine Schlussfolgerung, auf die andere Agenten bereits reagiert haben. Korrigieren Sie durch Anhängen: Geben Sie einen Lease frei, release-id für eine ungenutzte ID, ersetzen Sie einen falschen "wie gebaut"-Eintrag durch einen späteren. Generierte Seiten sind die einzige Ausnahme, und eine, die ihre agent-sync:generated-Markierung verloren hat …

… [für die Übersetzung gekürzt]

Verwandte Skills