0.11.0: der Driver übernimmt, Installation mit npx und ein BC-Versprechen, nach dem im richtigen Moment gefragt wird

· Release · geschrieben für 0.11.0

Bei 0.11.0 geht es darum, dass die Suite kontinuierlich weitermacht, mit vorsichtigen Standards. /continuous-refactoring ist jetzt der Driver, die Suite installiert sich mit einem npx-Befehl, und nach dem BC-Versprechen wird gefragt, wenn es zu zählen beginnt, statt an der Tür. Es gibt eine inkompatible Änderung, und sie betrifft jeden Aufruf, der „ein Run“ meint: siehe Was sich für dein Projekt ändert.

Wie ein Run bisher funktionierte

Ein Aufruf von /continuous-refactoring war ein Run: Er glich ab, was aus früheren Merge Requests geworden war, wählte einen Track, scannte, legte Tickets an, plante das nächste bearbeitbare Ticket, setzte es test-first auf einem eigenen Branch um und öffnete einen Merge Request. An jedem Entscheidungspunkt legte er Befunde, Optionen und eine Empfehlung dar und fragte dich; mit „mach das selbst“ nahm er seine eigenen Empfehlungen. Danach hörte er auf. Was den nächsten Run aufruft, musstest du selbst einrichten: einen Cronjob, /schedule, /loop oder du selbst an der Tastatur.

Das Driver-Playbook in 0.10.0

0.10.0 brachte ein Playbook für den Schritt danach: ein Agent, der einen autonomen Run nach dem anderen aufruft, jeden in einem eigenen Subagenten, sodass jeder Run mit frischem Kontext beginnt, jeden Merge Request in einem zweiten Subagenten prüft und dich nur fragt, wo die Entscheidung bei dir liegt. Es war ein Prompt, den du in eine Sitzung kopiert hast.

Der Driver ist jetzt der Hauptbefehl

Seitdem ist ein Run so stabil und zuverlässig geworden, dass ich den Driver fest etablieren möchte: als den normalen Weg, die Suite zu nutzen, nicht als Prompt am Rand. Deshalb sind die Namen umgezogen, damit der Name continuous-refactoring passt:

  • /continuous-refactoring ist der Driver. Der Name sagt „continuous“, und ein einzelner Run hört auf. Was weitermacht, ist der Driver, also hat er den Namen bekommen. Er arbeitet von selbst Runde um Runde: ein Run in einem Subagenten, das Review seines Merge Requests in einem zweiten Subagenten und eventuell Nacharbeit.
  • Ein einzelner Run heißt jetzt /continuous-refactoring-run, sonst unverändert. Ein Agent, der Refactoring erledigt haben will, ruft diesen auf.
  • Die Suite hat jetzt drei Skills: den Driver, einen Run und /continuous-housekeeping.

Das Driver-Playbook ist um all das herum neu geschrieben, und die FAQ sagt, warum die Namen umgezogen sind.

Sicher, wo du nichts sagst

Auch hier beginne ich vorsichtig und lockere erst, wo es sich bewährt hat, wie bei allem in der Suite: Ein Driver, der ohne weitere Anweisungen aufgerufen wird, tut das Vorsichtige. Er startet, ohne zu fragen, sagt in einem Satz zurück, was er verstanden hat, und dann:

  • mergt er nichts. Er kommentiert jeden Merge Request, und du mergst. Sagst du mergen, mergt er, sobald die CI grün ist. Danach prüft er, dass der Merge den Inhalt des Branchs wirklich übernommen hat, und hält an, wenn nicht: Die Korrektur ist ein gewöhnlicher Merge Request, nie ein Umschreiben der Historie.
  • hört er nach fünf Runden auf, und auch, wenn mehr als drei seiner Merge Requests offen sind.
  • wartet er 30 Minuten zwischen den Runden. Das Tempo soll langsam und stetig sein, neben anderen Agenten und Menschen, und die Wartezeit ist eine Chance, einen Job zu bemerken, der noch den alten Befehl aufruft.
  • bleibt Nacharbeit in der Runde und begrenzt. Eine Bitte um Änderungen wird sofort beantwortet; nach zwei Nacharbeiten ohne mergebares Ergebnis geht der Merge Request an dich.
  • hält er an, wenn etwas nicht stimmt: ein fehlgeschlagener Run, ein danach nicht sauberes Arbeitsverzeichnis, ein Merge, der nicht gelandet ist, oder zwei Runs in Folge ohne Merge Request und ohne neues wartendes Ticket.
  • beantwortet er nie selbst eine offene Frage. Er macht mit dem nächsten Ticket weiter, während eine auf dich wartet.
  • ist er für dich oder einen Zeitplan gedacht, nicht für einen Agenten. Er arbeitet stundenlang und schreibt in deine Forge; ein Agent, der nur etwas aufräumen sollte, soll ihn also nicht auslösen. Seine Beschreibung sagt das und verweist einen Agenten stattdessen auf /continuous-refactoring-run. Technisch gesperrt ist er nicht: Eine Skill-Einstellung wie disable-model-invocation würde auch einen geplanten Task daran hindern, ihn aufzurufen. Nur in einem Subagenten bricht er ab, weil er eigene Subagenten braucht und ein Subagent keine starten kann.

Jedes davon änderst du in eigenen Worten: eine andere Zahl Runden, ein Ende wie eine Uhrzeit oder „bis nichts mehr bearbeitbar ist“, einen anderen Rhythmus oder „keine Pause“, einen Track oder eine Einschränkung („Guardrails“, „nur die Rector-Tools“), eine Logdatei, die dein Repository ignoriert.

Zwei Haken stehen in den bekannten Einschränkungen: Eine Sitzung hält nur einen kurzen Rhythmus (in Claude Code reicht ein Warten eine Stunde), und der Driver weiß nicht, wann er zuletzt lief. Für einen täglichen Rhythmus richtest du deinen eigenen Scheduler auf /continuous-refactoring, und lass pro Projekt einen Driver laufen.

Installation mit npx skills

Die Suite wird jetzt mit dem skills-Installer installiert (Node.js 22.20 oder neuer), für OpenCode, Claude Code, Codex und andere Agenten:

npx skills@latest add https://github.com/Art4/continuous-refactoring/tree/0.11.0/skills --skill '*' -a <agent>

Er kopiert genau die drei Skills dieser Version ins Ziel, sonst nichts aus dem Repository, und hält die Version in skills-lock.json fest. Installiere immer alle drei: Der Driver und Housekeeping lesen Dateien des Run-Skills. Ein Upgrade führt denselben Befehl mit der neuen Version in der URL aus; --skill '*' bringt auch einen Skill mit, den die neue Version hinzufügt. Ein Git-Checkout mit Symlinks funktioniert weiter, ohne Node.js oder um an der Suite selbst zu arbeiten: Checke ein Release-Tag aus, statt main zu folgen.

Das BC-Versprechen, im richtigen Moment gefragt

Ob die Suite eine alte API löschen darf, hängt von deinem BC-Versprechen ab, dem Dokument, das sagt, was für Code außerhalb deines Projekts stabil bleibt. Bis 0.10 fragte das Onboarding danach, und ein früher eingerichtetes Projekt wurde zu Beginn seines nächsten Runs gefragt. Das war früh und ohne Zusammenhang. Jetzt fragt vorab nichts mehr. Solange die Suite dein Versprechen nicht kennt, behandelt sie Code, der von außen erreichbar ist, als abgedeckt; das ist sicher, behält aber alte APIs, die außerhalb womöglich niemand nutzt.

Das BC-Versprechen ist jetzt ein eigenes Tool auf Anfrage, und das bringt einen neuen Mechanismus mit: den Opener. Ein Tool auf Anfrage wird weiterhin nie ungefragt eingerichtet, darf aber jetzt von selbst zur Sprache kommen, einmal, als Frage, in dem Moment, in dem es sich ausgezahlt hätte. Ein Plan, der diesen Moment trifft, vermerkt ihn, und der nächste Scan legt ein Ticket an, das fragt, ob das Tool eingerichtet werden soll. Das Ticket wartet auf dein Ja, auch in einem autonomen Run, und hält bis dahin keinen Track zurück. Ein Nein sorgt dafür, dass das Tool nicht erneut angeboten wird.

Beim BC-Versprechen ist dieser Moment das erste Mal, dass ein Plan eine alte API nur deshalb behält, weil das Versprechen offen ist. Das Ticket trägt, was die Suite gefunden hat: dein Dokument oder einen Entwurf, der die üblichen Fragen eines solchen Versprechens aus deinem Code beantwortet und offen lässt, was nur du sagen kannst, etwa wie lange eine Deprecation gilt. Deine Antwort auf dem Ticket entscheidet, und ein autonomer Run beantwortet es nie für dich.

Auch der Punkt BC promise kann mehr:

  • Er darf eine Seite deiner Website nennen statt einer Datei. Eine Seite, die der Run nicht öffnen kann, lässt diesen Teil für den Run ungeklärt, mit einem Befund.
  • Er darf mehrere Versprechen auflisten, jedes mit seinem Umfang: ein Ordner wie packages/client/ oder eine Oberfläche wie die PHP-API, eine HTTP-API oder die Kommandozeile. Wo zwei denselben Code abdecken, gilt das strengere; Code, den keines abdeckt, bleibt abgedeckt.
  • Roaves Backward-Compatibility-Check gilt pro Teil. Folgen nur manche Teile Semantic Versioning, werden die Klassen der anderen ignoriert, jeder Eintrag mit seinem Umfang kommentiert.
  • Rectors Type Coverage sagt, warum sie vorsichtig war. Nimmt sie ihren BC-sicheren Weg nur, weil kein Versprechen festgehalten ist, vermerkt der Plan das, und der nächste Scan bittet dich, das Versprechen einzurichten.

Auch andere Tools nutzen den Opener. Semgrep und die Taint-Analyse von Psalm kommen zur Sprache, wenn ein Plan ein Sicherheitsproblem behebt, das durch Lesen des Codes gefunden wurde: Eine Injection geht an die Taint-Analyse, sobald PHPStan Level 4 oder Psalm erreicht ist, alles andere an Semgrep. Infection kommt zur Sprache, wenn ein Plan Tests findet, die den Code, den er ändert, zwar ausführen, aber wenig davon prüfen. Secret Detection bleibt nur auf Anfrage, weil Housekeepings Scan der Git-Historie ein committetes Secret ohnehin findet.

Die FAQ hat die Begründung.

Außerdem in 0.11.0

  • Ein eigenes Pack, für dich gebaut. /continuous-refactoring-run ein eigenes Pack für Deptrac überspringt die Arbeitsliste und die Track-Wahl, schlägt das Tool, seine Rolle und seine Stufen vor, prüft das Pack mit dem Parser und endet mit einem Merge Request. Das Playbook beginnt jetzt damit und behält den Weg von Hand darunter. Der --own-pack des Parsers nimmt einen relativen Pfad gegen das Ziel, wie dokumentiert, nicht gegen das Arbeitsverzeichnis.
  • Die Tracker-Datei darf woanders liegen. Nenne sie in deiner AGENTS.md (oder CLAUDE.md), in eigenen Worten, und die Suite liest und schreibt den Abschnitt ## Refactoring operations dort. Ohne eine solche Zeile ändert sich nichts; eine Datei außerhalb des Repositorys beendet den Run. Siehe die FAQ.
  • Ein Playbook weniger. Das Reviewer-Loop-Playbook ist weg: Es war ein Werkzeug, um die Suite zu entwickeln, nicht für ein Projekt, das sie nutzt. Das Reviewen innerhalb eines Projekts ist die Aufgabe des Drivers.

Was sich für dein Projekt ändert

Zu tun, wegen der inkompatiblen Änderung:

  • Stelle sicher, dass alle drei Skills installiert sind: Bei npx skills führst du den Befehl oben aus (--skill '*' bringt den neuen mit); bei Symlinks legst du den dritten an, skills/continuous-refactoring-run, neben den anderen beiden.
  • Stelle jeden Aufruf, der einen Run meint, auf /continuous-refactoring-run um, vor allem einen geplanten Job. Bliebe er auf /continuous-refactoring, würde er jetzt einen Driver starten.
  • In einem eigenen Pack änderst du die $schema-Zeile auf den neuen Pfad unter continuous-refactoring-run.

Die Zeile „Used by /continuous-refactoring“ in einer bereits geschriebenen Tracker-Datei ist harmlos und darf bleiben.

Was dir auffallen wird:

  • Das Onboarding fragt nicht mehr nach dem BC-Versprechen, und ein Run fragt zu Beginn nicht mehr danach. Wird eine alte API nur aus diesem Grund behalten, fragt dich später ein Ticket.
  • Der nächste Scan bietet vielleicht ein Tool auf Anfrage als Ticket an, wenn einer der Opener oben getroffen wurde. Es wartet auf dich und blockiert nichts.
  • Ein Roave-Check unter einem gemischten Versprechen wird auf die Teile eingegrenzt, die SemVer folgen.

Wenn du den Driver auf eines deiner Projekte loslässt, lese ich gern, wie es lief, in den GitHub Discussions (Show and tell).

Changelog 0.11.0

Die Einträge aus dem Upstream-Changelog zu 0.11.0, unverändert auf Englisch. Auch auf GitHub: Release 0.11.0.

Changelog-Einträge anzeigen
  • Breaking: /continuous-refactoring is now the Driver: it works round after round by itself, each a run, its review and any rework, 30 minutes apart, and stops after five rounds or at more than three open merge requests. It merges nothing unless the call says merge. One run is now /continuous-refactoring-run, unchanged otherwise, and the references moved with it. To upgrade: add the third symlink, skills/continuous-refactoring-run, beside the other two; move any call that means one run, a scheduled job above all, to /continuous-refactoring-run; in a Pack of your own change the $schema line to the new path. The line "Used by /continuous-refactoring" in a tracker file already written is harmless and can stay.
  • Onboarding no longer asks for the BC promise, and a run no longer asks for it at its start. The BC promise is now a tool on request of its own: the first time a plan keeps an old API only because the promise is open, the next scan files a ticket with what it found, or a draft that answers the usual questions of such a promise from the project's code and leaves open what only the human can say. The human's answer on that ticket decides; an autonomous run never answers it.
  • The BC promise bullet may now name a page on the project's website, and it may list several promises, each with its scope: a folder of the code or a surface such as the PHP API, an HTTP API or the command line. Where two cover the same code, the stricter one applies; code none covers stays covered. A page that cannot be read leaves its part unsettled for that run, with a finding.
  • A tool on request can now come up by itself, once, as a question: its Opener is the situation in which it would have paid off. A plan that meets it notes the Opener under its decisions, and the next scan files a ticket asking whether to set the tool up. The ticket waits for a human's yes, in an autonomous run too, and until then holds no Track back. A rejection keeps the tool from being offered again.
  • Semgrep, Psalm's taint analysis and Infection can now come up by themselves, once, as a question. Semgrep and the taint analysis come when a plan fixes a security problem found by reading the code: an injection goes to the taint analysis where PHPStan Level 4 or Psalm is reached, anything else to Semgrep. Infection comes when a plan finds tests that run the code it changes but check little of it. Secret Detection stays on request only.
  • Roave's backward-compatibility check now applies per part of the BC promise: when only some parts follow semantic versioning, the classes of the others are ignored, each entry commented with its scope. When Rector's type coverage takes its BC-safe path only because no promise is recorded, the plan notes that, and the next scan asks the human to set the promise up.
  • A call can now build a Pack of your own: /continuous-refactoring-run a Pack of its own for Deptrac skips the worklist and the Track choice, proposes the Tool, its Role and its Stages, checks the Pack with the parser, and ends with one merge request. The parser's --own-pack now takes a relative path against the target, as documented, not against the working directory.
  • The tracker file may live elsewhere: name it in your AGENTS.md (or CLAUDE.md), in your own words, and the suite reads and writes the ## Refactoring operations section there. Without such a line nothing changes. A file named outside the repository ends the run.
  • The reviewer-loop playbook is gone: it was a tool for developing the suite, not for a project using it. Reviewing inside a project is the Driver's job.
  • The suite now installs with the skills installer: npx skills@latest add https://github.com/Art4/continuous-refactoring/tree/0.11.0/skills --skill '*' -a <agent> copies exactly the three skills of that version into the target, for OpenCode, Claude Code, Codex and other agents, and an upgrade runs the same command with the new version. A Git checkout with symlinks still works; check out a release tag instead of following main.

Fragen oder Anmerkungen zu diesem Beitrag? Gern in den GitHub Discussions (Q&A).