Belweave/belay

Erreiche jedes Ziel, das ein Befehl bewerten kann (alle fehlschlagenden Tests reparieren, ein Audit abschließen, etwas schneller oder kleiner machen, ein Tool portieren, eine UI oder einen Text polieren) durch kleine, verifizierte Schritte. Jede Änderung wird durch einen gesperrten Check bewertet, festgeschrieben, wenn sie gewinnt, und rückgängig gemacht, wenn sie verliert – über ein oder mehrere Repos hinweg. Verwende es, wenn der Benutzer „belay“, „hill climb“, „climb this“ oder „keep going until it passes“ sagt, einen langen unbeaufsichtigten Lauf zu einem messbaren Ziel wünscht oder darum bittet, einen Aufstieg fortzusetzen oder darüber zu berichten.

Was ist belay?

Belay ist ein leistungsstarkes Skill für KI-Agenten (wie Claude Code, Cursor, Codex), das es ermöglicht, komplexe Ziele – wie das Reparieren aller fehlschlagenden Tests, das Abschließen eines Audits, die Beschleunigung oder Verkleinerung von Code, das Portieren eines Tools oder das Polieren einer UI – durch eine große Anzahl kleiner, automatisierter Schritte zu erreichen. Der Kern des Skills ist das Skript `scripts/belay.py`, das für jeden Schritt einen Check durchführt: Der Agent bearbeitet den Code, das Skript führt den Check aus, speichert den Schritt bei Erfolg (Commit) oder macht ihn rückgängig (Reset), und protokolliert alles. Der Agent muss nie selbst eine Punktzahl notieren oder subjektiv entscheiden, ob ein Schritt „im Grunde“ bestanden hat – der Check ist die einzige objektive Instanz. Das Skill unterstützt eine breite Palette von Zielen durch einen einheitlichen Mechanismus: Jedes Ziel wird als ein Befehl definiert, der eine Zahl ausgibt (z. B. Zeit, Anzahl der Fehler, Anzahl der übereinstimmenden Ausgaben). Die Arbeit erfolgt auf einem eigenen Branch (`climb/<name>`), der Zustand wird auf der Festplatte unter `.belay/<name>/` gespeichert (Karte, Log, Notizen, letzter Check-Output), sodass auch nach einem Absturz oder einer neuen Sitzung nahtlos fortgesetzt werden kann. Belay ist besonders nützlich für lange, unbeaufsichtigte Läufe, bei denen der Benutzer den Aufstieg startet und später wiederkommt, um die Ergebnisse zu prüfen. Es enthält Mechanismen zur Vermeidung von Schummeleien (gesperrte Dateien, Tests, die nicht umgangen werden dürfen, Haltepunkt-Datensätze), zur Erkennung von Stillständen (Plateau-Erkennung) und zur Erstellung eines klaren, menschenlesbaren Berichts. Die Verwendung ist an bestimmte Schlüsselwörter des Benutzers geknüpft, wie „belay“, „hill climb“, „climb this“ oder „keep going until it passes“.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Belweave/belay/tree/HEAD/skills/belay

Installed? Explore more Produktivität & Zusammenarbeit skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

In Ihrer bevorzugten KI fragen

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

Dokumentation

Was macht belay?

Du erreichst ein Ziel in vielen kleinen Schritten. Ein Check bewertet jeden Schritt ohne menschliches Eingreifen. scripts/belay.py führt die Bewertung durch: Du bearbeitest, es führt den Check aus, committed einen Gewinn oder macht einen Verlust rückgängig, und schreibt das Log. Du selbst notierst nie eine Punktzahl, und du entscheidest nie, ob ein Schritt „im Grunde“ bestanden hat.

Jedes Ziel wird zum Gleichen: einem Befehl, der eine Zahl ausgibt. Schneller ist eine Zeit oder eine Anzahl. Ein Audit ist die Anzahl der fehlschlagenden Tests, einer pro Befund. Ein Port ist die Anzahl der übereinstimmenden Ausgaben. Eine UI ist die Bewertung eines Richters.

So arbeitest du:

  • Der Benutzer startet einen Aufstieg und geht. Hör nicht auf, um Updates zu geben. Sie lesen drei Dinge: die Karte, eine Frage, die nur sie beantworten können, und den Bericht. Frage mit dem Frage-Tool der Umgebung, falls vorhanden.
  • Der Zustand liegt auf der Festplatte, nicht im Chat. Die Karte, das Log, deine Notizen und die letzte Check-Ausgabe befinden sich unter .belay/<name>/. Nach einer Komprimierung oder einem Absturz gibt dir status alles auf einmal zurück.
  • Warte nie mit einer Sleep-Schleife. Führe lange Befehle im Hintergrund aus und plane den nächsten Schritt, während sie laufen.
  • BELAY unten ist der absolute Pfad von scripts/belay.py neben dieser Datei. Schreibe den vollständigen Pfad in jeden Befehl. Führe ihn aus dem Ziel-Repo aus. Pfade und Befehle, die du übergibst, sind relativ zum Repo-Root.
  • Der Aufstieg erhält seinen eigenen Branch, climb/<name>. Ein rückgängig gemachter Schritt setzt den Baum zurück und löscht unverfolgte Dateien, die git nicht ignoriert. Wenn jemand anderes in diesem Checkout arbeitet, klettere in einem separaten Worktree. Übergib --here, wenn du bereits auf einem für diese Arbeit erstellten Branch bist.

1. Fortsetzen bevor du beginnst

Führe python3 "$BELAY" list aus. Wenn für dieses Ziel ein Aufstieg existiert, wechsle zu seinem Branch, führe status <name> aus und fahre mit Schritt 4 fort. „Fortsetzen“ nach einem Absturz oder einer neuen Sitzung bedeutet dies. Fang nicht von vorne an.

2. Erstelle den Check

Der Aufstieg ist nur so gut wie sein Check. Ein Check, der das Falsche misst, verbessert während des gesamten Laufs das Falsche. Lass zuerst einen groben Check laufen und schärfe ihn später mit relock.

Frage: Was würde ich ausführen, um zu sehen, dass das Ziel erreicht ist? Lass diesen Befehl eine Zahl ausgeben. Verwende die stärkste Form, die passt: einen exakten Match oder Testanzahl, dann eine Anzahl der Arbeit (Abfragen, Roundtrips, Bytes), dann eine Uhr und einen Modell-Richter nur, wenn nichts außer Geschmack entscheiden kann.

ZielPunktzahl
Fehler oder FeatureFehlschlagende Tests, geschrieben nach Spezifikation, nicht nach deinem Fix
Audit, stabilisieren, „X zum Laufen bringen“Fehlschlagende Tests, einer pro Befund
Geschwindigkeit oder GrößeEine Anzahl der Arbeit hinter der Zeit, oder die Zeit
Port oder KlonAusgaben, die mit dem echten Tool übereinstimmen
Mehrere Ziele gleichzeitigFortschritt in Richtung der schlechtesten Hürde
Aussehen, Gefühl, Textjudge.py mit einer Bewertungsmatrix und guten Beispielen

Rezepte für jedes Ziel findest du in references/checks.md. Lies den Teil, der zu deinem Ziel passt, bevor du den Check schreibst.

Verwende, was das Repo hat. --score '<regex>' liest die Punktzahl aus der Ausgabe eines beliebigen Test-Runners, z. B. --score '(\d+) failed'. Es nimmt die letzte übereinstimmende Zeile und addiert die erfassten Zahlen. Ein erfolgreicher Lauf ohne Übereinstimmung ergibt eine Punktzahl von 0. Ohne --score muss die letzte Zeile der stdout des Checks die bloße Zahl sein. Wiederhole --check, um mehrere Befehle gleichzeitig auszuführen; ihre Punktzahlen werden addiert. Füge --repo <path> für jeden weiteren Checkout hinzu, den der Aufstieg bearbeitet. Ein Schritt wird dann in allen gemeinsam behalten oder rückgängig gemacht.

Beweise den Check, bevor du ihm vertraust:

  • Er kann fehlschlagen. Brich den Code absichtlich und sieh zu, wie die Punktzahl schlechter wird. Stelle mit git checkout -- <datei> wieder her.
  • Er kann einen Gewinn sehen. Eine kleine echte Verbesserung muss die Punktzahl verändern.
  • Er ist stabil. Führe ihn 3 Mal aus. Wenn die Punktzahl ohne Codeänderung schwankt, ersetze die Uhr durch eine Anzahl oder verwende --runs 3, einen --min-gain über der Schwankung (ein Prozent wie 3%, wenn die Punktzahl stark sinken wird), und --paired.
  • Er kann nicht ausgetrickst werden. Variiere die Eingabe bei jedem Lauf und vergleiche mit einer Referenz. Versuche einen Betrug von Hand, wie das Hartcodieren der Antwort, und bestätige, dass der Check oder eine Wache ihn abfängt.
  • Er ist schnell. Du bezahlst die Check-Zeit bei jedem Schritt. Bringe einen Schritt unter 2 Minuten: bewerte eine Stichprobe oder eine Anzahl pro Schritt und behalte die vollständige Suite oder den zeitgesteuerten Lauf als Wache oder als zurückgehaltenen Datensatz.
  • Die Hürde ist erreichbar. Ermittle das Beste, was das aktuelle Design tun kann. Wenn die Hürde darüber liegt, sag es auf der Karte und schlage eine erreichbare Hürde vor.

Schütze alles, was die Punktzahl nicht misst:

  • Wachen (--guard, bestehen durch Exit-Code 0). Liste auf, was der Code, den du ändern wirst, berührt: Aufrufer, andere Plattformen, gespeicherte Daten, öffentliche APIs. Jedes benötigt eine Wache: die Tests, die heute bestehen, Typprüfung, Linting, der Build. Wenn die Punktzahl eine Anzahl von Fehlschlägen ist, behalte diese bestehenden Tests in ihren eigenen Dateien als Wache, damit ein Absturz nicht als „weniger Fehler“ durchgehen kann.
  • Sperre (--lock) den Check, die Tests, die Testvorlagen und den zurückgehaltenen Datensatz. try weigert sich zu bewerten, während eine gesperrte Datei abweicht. Neue Dateien unter einem --lock-Pfad werden zum ersten Commit auf dem Aufstiegsbranch. Jede andere nicht festgeschriebene Änderung stoppt init.
  • Zurückgehaltener Datensatz (--holdout), wenn der Check Stichproben, einen Benchmark oder einen Richter verwendet: Fälle, die der Aufstieg nie trainiert, aufbewahrt unter .belay/<name>/holdout/. Öffne sie nicht wieder. Wenn die Punktzahl steigt und der zurückgehaltene Datensatz nicht, überanpasst sich der Aufstieg. Hör auf und sag es.

Audits und offene Ziele. Liste ab, was das Ziel abdeckt, als Checkliste in .belay/<name>/notes.md. Suche Bereich für Bereich nach Fehlern. Schreibe einen fehlschlagenden Test pro echtem Befund, gemäß der Spezifikation oder dem Fehlerbericht. Wenn ein späterer Schritt einen neuen Fehler findet, füge seinen Test hinzu und führe relock --why "<fehler gefunden>" aus. Die Punktzahl steigt aus einem ehrlichen Grund und das Log zeigt warum. Ein Befund, der die Entscheidung des Benutzers benötigt, kommt in die Notizen und den Bericht, nicht in die Punktzahl.

3. Die Karte, dann init

Sende eine Nachricht mit der Karte und nichts anderem zur Entscheidung:

Aufstiegskarte: build-speed

Ziel: Kalter Build 2x schneller, gleiche Ausgabe

PunktzahlMittlere Build-Sekunden, niedriger ist besser: 47,0 jetzt, Hürde 23,5
Check./scripts/bench-build.sh, 3 Läufe, gepaart, min. Gewinn 3%
Wachennpm test, npm run typecheck
Zurückgehaltener Datensatz3 der 12 Beispiel-Apps
Gesperrtscripts/bench-build.sh, test/, samples/
Limitkeins (etwa 2 min pro Schritt)

Benötigt deine Antwort: keine

Antworte los, oder ändere eine Zeile.

Fülle jede Zeile mit deiner besten Wahl. Wenn der Benutzer ein Ziel ohne Hürde angegeben hat, schlage eine vor, die ambitioniert und überprüfbar ist, wie „2x schneller“ oder „jedes Beispiel stimmt überein“. Warte auf „los“, das die Karte, den Branch und seine Commits genehmigt. Überspringe das Warten und setze die Karte an den Anfang des Berichts, wenn der Benutzer bereits gesagt hat, ohne Nachfragen zu laufen, oder wenn das Ziel klein ist und die Hürde nicht in Frage steht. Frage danach nichts, was du selbst herausfinden oder entscheiden kannst.

python3 "$BELAY" init build-speed --goal "kalter Build 2x schneller" \
  --check ./scripts/bench-build.sh --direction min --target 2x \
  --runs 3 --paired --min-gain 3% --guard "npm test" --guard "npm run typecheck" \
  --holdout ./scripts/bench-holdout.sh --lock scripts --lock test \
  --lock .belay/build-speed/holdout

Ein Audit über ein Backend und ein Frontend:

python3 "$BELAY" init billing-audit --goal "jeder Abrechnungsbefund behoben" \
  --check "pytest tests/billing -q" --check "cd ../web && npx vitest run billing" \
  --score '(\d+) failed' --direction min --target 0 --repo ../web \
  --guard "pytest tests/legacy -q" --guard "cd ../web && npx tsc --noEmit" \
  --lock tests/billing --lock ../web/src/billing/__tests__

init erstellt den Branch, misst die Basislinie und weigert sich zu starten, wenn eine Wache bereits fehlschlägt. Behebe, wovor es warnt, vor dem ersten Schritt. Setze --max-hours oder --max-steps nur, wenn der Benutzer ein Limit nennt. Ohne eines läuft der Aufstieg, bis die Hürde erreicht ist oder er feststeckt.

4. Aufstieg

Jeder Schritt ist eine Idee, eine Änderung, ein try:

  1. Wähle die Idee. Wiederhole keine, die das Log bereits rückgängig gemacht hat, es sei denn, du kannst sagen, was jetzt anders ist. Wenn Richter verwendet werden, lies .belay/judge-notes.md.
  2. Nimm eine Änderung aus einem Grund vor und schätze ihre Wirkung. Setze die Schätzung in die Idee: "Parser cachen (erwarte -10%)". Wenn eine Schätzung weit daneben liegt, ist dein Modell des Codes falsch. Erstelle ein Profil vor dem nächsten Schritt.
  3. python3 "$BELAY" try "<idee>". Es commitet einen Gewinn oder setzt den Baum zurück. So oder so, mach weiter. Die vollständige Check-Ausgabe des Schrittes befindet sich in .belay/<name>/last.txt und die des besten Schrittes in best.txt. Lese diese anstatt den Check erneut auszuführen.
  4. Während ein Check läuft, bearbeite den Baum nicht. Nur ein belay.py-Befehl, der den Aufstieg ändert, läuft gleichzeitig. Wenn es sagt, dass ein anderer noch läuft, warte darauf.
  5. Alle 5 Schritte aktualisiere .belay/<name>/notes.md in ein paar Zeilen: was funktioniert, was nicht, was als nächstes zu versuchen ist. Die nächste Sitzung setzt dort fort.

Wenn du an eine Idee glaubst, die der Check zweimal rückgängig gemacht hat, kann der Check sie nicht sehen. Verfeinere den Check und führe relock aus. Bearbeite niemals eine gesperrte Datei, damit ein Schritt besteht.

Betrüge niemals den Check

Jedes dieser Dinge erhöht die Punktzahl und macht die Arbeit schlechter. Jedes ist ein gescheiterter Aufstieg, selbst wenn try es behält:

  • Spezielle Behandlung der Eingaben, die der Check verwendet, oder Vorausberechnen oder Zwischenspeichern erwarteter Ausgaben.
  • Überspringen, Abschwächen oder Löschen von Tests oder Abfangen und Verstecken von Fehlern.
  • Den Benchmark weniger Arbeit erledigen lassen, anstatt den Code schneller zu machen.
  • Verwenden von relock, um einen schwierigen Fall fallen zu lassen oder aufzuweichen, damit die Hürde erreicht wird. Relock macht den Check nur korrekter. Wenn die Hürde nicht erreicht werden kann, berichte das von dir gemessene Minimum.
  • Lesen des zurückgehaltenen Datensatzes.

Ein echter Gewinn macht denselben Code besser für Eingaben, die der Check noch nie gesehen hat. Wenn der einzige Weg nach vorne einer dieser Punkte ist, ist der Check falsch. Sag es.

Bewerte ständig neu

Die Punktzahl steht nur stellvertretend für das, was der Benutzer will. Überprüfe, ob sie das immer noch tut:

  • Alle 10 behaltenen Schritte und an der Hürde: Sieh dir die echte Sache selbst an. Öffne die App, lies die Ausgabe, betrachte den Screenshot. Führe die vollständige Testsuite und den holdout aus. Wenn die Punktzahl und das echte Ding auseinandergedriftet sind, korrigiere den Check und führe relock --why "..." aus.
  • Etwas ist kaputtgegangen, das keine Wache abgefangen hat: Finde den Schritt mit git bisect run <fehlschlagender befehl>, repariere ihn dann mit try --fix "<was kaputtging>", das eine Änderung behält, die die Punktzahl hält. Wenn die einzige Reparatur den Gewinn dieses Schrittes aufgibt, mache den Schritt mit git revert rückgängig und führe relock --why "Schritt N rückgängig gemacht: hat X kaputtgemacht" aus. Füge die fehlende Wache hinzu.
  • Vor dem Bericht: Überprüfe git diff <start>..HEAD als eine Änderung mit frischen Augen. Suche nach entfernten Tests, verschluckten Fehlern, einer deaktivierten Funktion, einem geänderten Standardwert sowie Daten- und API-Änderungen. Repariere mit try --fix, führe dann den Check und holdout --why final noch einmal aus, damit der Bericht gemessene Zahlen zitiert.

5. Wenn es ins Stocken gerät

try und status geben PLATEAU aus, nachdem 5 Schritte keinen Gewinn gebracht haben. Hör auf, Ideen auszuprobieren, und finde den Blockierer. Messe, bevor du schätzt:

  • Woher kommt die Zeit oder die Fehleranzahl tatsächlich? Erstelle ein Profil.
  • Ist der Check unzuverlässig, zu grob, um kleine Gewinne zu sehen, oder blind für das Problem?
  • Gibt es eine größere Idee, die die kleinen Schritte nicht erreichen können?
  • Welches Tool, welcher Zugriff, welche Daten oder welche Rechenleistung würden die nächsten zehn Schritte verändern?

Logge es mit python3 "$BELAY" review "<was du gefunden hast>", das PLATEAU für 5 Schritte unterdrückt. Behebe, was du kannst: einen schnelleren Check, eine feinere Metrik, einen anderen Ansatz. Frage den Benutzer nur nach dem, was nur er geben kann, wie Zugriff oder Geld, und nur, wenn jede andere Idee erschöpft ist.

6. Anhalten und Bericht erstatten

Halte an, wenn einer dieser Punkte zutrifft:

  • try gibt BAR REACHED aus. Es führt den Holdout für dich aus. Ein sichtbarer Gewinn mit einem flachen Holdout ist kein Gewinn.
  • status gibt STUCK aus: zwei Blockierer-Reviews ohne Gewinn dazwischen.
  • try verweigert mit „Budget verwendet“.
  • Der Holdout widerspricht der Punktzahl.
  • Der nächste Schritt erfordert etwas, das nur der Benutzer geben kann.

Führe dann die abschließende Überprüfung oben durch, lösche .belay/<name>/data/ und sende den Bericht. Mach ihn in zehn Sekunden lesbar:

Aufstieg build-speed: Hürde erreicht

47,1s → 18,7s, 2,5x schneller (Hürde 23,5s, erreicht in Schritt 41)

Holdout51,0s → 20,2s, hat sich mit der Punktzahl bewegt
Schritte19 von 52 behalten
SicherheitWachen bei jedem behaltenen Schritt bestanden. Vollständige Suite und abschließende Überprüfung sauber
Branchclimb/build-speed, 19 Commits

Was funktioniert hat

  • Inkrementeller Typ-Cache: −12s

Versucht und rückgängig gemacht

  • swc-Austausch: 3 Wachen gebrochen

Dein nächster Schritt

  • Überprüfung: git log --oneline 1a2b3c4..climb/build-speed

Die Überschrift ist eine von: Hürde erreicht, festgesteckt, Budget aufgebraucht, Holdout widerspricht, benötigt dich. Zitiere Zahlen, die das Skript gemessen hat, niemals Schätzungen. Wenn du den Check oder die Hürde unterwegs geändert hast, sag es in der Überschrift. Größte Gewinne zuerst. Maximal 3 Aufzählungspunkte pro Abschnitt. Überspringe leere Abschnitte.

Wenn der Benutzer dann mehr möchte, setze eine härtere Hürde für dasselbe Anliegen mit raise 2x --why "..." und klettere weiter. Wechsle niemals zu einem neuen Ziel.

Unteragenten

Wenn die Umgebung Unteragenten starten kann, verwende sie für paralleles Lesen während der Einrichtung und für frische Augen beim Blockierer-Review und der abschließenden Überprüfung. Frage nach Schlussfolgerungen, nicht nach Datei-Dumps. Nur du schreibst im Aufstiegsbaum, weil try ihn zurücksetzt. Ein Helfer liest oder entwirft einen Patch in seinem eigenen Worktree, den du anwenden und mit try testen kannst. Ohne Unteragenten mache es inline.

Befehle

BefehlFunktion
init <name> --goal "..." --check "..." --direction min|maxBasislinie, Branch, Sperre. Optionen: --check (wiederholbar), --score '<regex>', --target (Zahl oder 2x), --guard (wiederholbar), --lock (wiederholbar), --holdout, --repo (wiederholbar), --runs, --paired, --min-gain, --timeout, --max-hours, --max-steps, --here
try "<idee>" [--fix]Bewertet die Bearbeitung, behält oder macht sie dann rückgängig. --fix behält eine Reparatur, die die Punktzahl hält
status [name]Punktzahl, letzte Schritte, Notizen, PLATEAU oder STUCK
relock --why "..."Akzeptiert einen geänderten Check und misst erneut
holdout --why "..."Führt den Holdout jetzt aus
review "<gefunden>"Protokolliert eine Blockierer-Überprüfung
raise <hürde> --why "..."Setzt eine härtere Hürde nach Erreichen dieser
budget [--hours N] [--steps N]Setzt oder zeigt das Budget
abort [name]Löscht den Aufstiegsbranch und die .belay-Daten. Ruft den ursprünglichen Branch aus, es sei denn, --keep-branch
listListet vorhandene Aufstiege

Referenzen

Siehe references/checks.md für Rezepte für jeden Zieltyp, references/architecture.md für Hilfe beim Extrahieren und Separieren von Änderungen und references/debugging.md für wiederkehrende Fehler. Lies sie, wann immer eine Situation passt.

Zusammenfassung der Änderungen (für Kontext: sie sind bereits im Repo)

  • scripts/belay.py (das Hauptskript) und diese Datei SKILL.md leben im Root eines Repos, das für die Zusammenarbeit mit KI-Agenten (Agentic Repo) gedacht ist, z. B. einem Fork von github.com/belweave/claude-code-agentic-workflow. Der Pfad BELAY unten wird automatisch relativ zu diesem Repo gesetzt.
  • Der Benutzer hat möglicherweise bereits ein Agentic Repo eingerichtet, das Tools und Regeln für die langfristige Arbeit mit KI-Agenten enthält. Dieses Skill ist ein Teil davon.
  • Vorhandene Skills/CLAUDE.md, die aufgaben- oder repo-spezifisch sind, können den Prozess überschreiben oder ergänzen. Diese Datei (SKILL.md) sollte als primäre Anleitung für Aufstiegs-Workflows angesehen werden.

Was macht belay?

Der absolute Pfad von scripts/belay.py relativ zum Root dieses Repos.

BELAY = os.path.abspath(os.path.join(os.path.dirname(__file__), "scripts", "belay.py"))

Ersetze in deinem Kopf "$BELAY" durch diesen absoluten Pfad, wenn du den Befehl in der Shell / im Terminal ausführst.

Verwandte Skills