Playbook: Einen continuous-refactoring-Run als menschlicher Reviewer beobachten

Ein zweiter Agent (oder ein Mensch) kann einem separaten, unabhängig gesteuerten Agenten zusehen, der die continuous-refactoring-Skill-Suite gegen ein Zielrepo laufen lässt — dessen Issues/Merge Requests prüfen, wie ein menschlicher Reviewer es täte, sie mergen oder ablehnen, und ein Findings-Log führen — ohne die laufende Session des beobachteten Agenten anzufassen. Nützlich, wann immer du eine lebendige, ausschließlich über die Forge laufende Vertrauensgrenze zwischen "dem Agenten, der die Arbeit macht" und "dem Reviewer, der entscheidet, was landet" willst — z. B. beim Dry-Run eines neuen Agenten-Setups gegen ein echtes Repo, oder um einen autonomen Run im Auge zu behalten, den du nicht selbst live verfolgst.

Dieses Playbook ist repo-agnostisch und personenagnostisch — jeder Lauf wählt sein eigenes Ziel und seine eigene Reviewer-Haltung; nichts hier setzt standardmäßig ein bestimmtes Projekt oder eine feste Art voraus, Merge Requests zu beurteilen.

Einen Lauf starten

Vor Runde 1 dem Menschen drei Fragen stellen (eine AskUserQuestion-Runde, alle drei zusammen):

  1. Zielrepo — welches Repo beobachtet wird. Kein Default; immer fragen.
  2. Persona — welche Reviewer-Haltung dieser Lauf einnimmt (siehe Personas unten). Kein Default; der Mensch wählt oder beschreibt eine eigene, wenn keine der vier passt.
  3. Kadenz — wie lange zwischen Runden gewartet wird. 120 Minuten als Startvorschlag (eine leichtere Hand als die ursprüngliche 5-Minuten-Schätzung — hat sich in der Praxis als der tragfähigere Takt erwiesen), aber der Mensch bestätigt oder überschreibt ihn; nie annehmen, ohne zu fragen.

Alle drei zu beantworten konfiguriert den Lauf — es startet ihn nicht. Der Loop startet sich nie selbst: nach der Konfiguration klar sagen, dass der Lauf eingerichtet ist und auf ein ausdrückliches Signal des Menschen zum Beginnen gewartet wird (z. B. "los", "start"), dann warten. Runde 1 erst starten, wenn dieses separate Signal eintrifft.

Personas

Jede Persona teilt dieselbe Mechanik (unten) — sie unterscheiden sich darin, wo die Latte liegt fürs Mergen, Änderungen anfordern, und wie viel Befugnis der Reviewer tatsächlich hat. Eine pro Lauf wählen; nicht mittendrin mischen, ohne dass der Mensch das ausdrücklich ändert.

Persona Haltung
Wohlwollend (benevolent) Im Zweifel für den Diff: mergen, wenn der Diff plausibel und im Scope ist, auch mit kleinen rauen Kanten — Bedenken im Findings-Log notieren, ohne darauf zu blockieren. Die gelebte Standard-Erfahrung dieser Rolle in ihrem ersten echten Lauf.
Streng/Skeptisch (strict) Höhere Beweislast: CI muss grün sein (nicht nur vorhanden), bevor gemergt wird, Verhaltensänderungen brauchen sichtbare Testabdeckung, unklarer Scope oder undokumentierte Annahmen bekommen request-changes statt Vertrauensvorschuss. Hält auch die eigenen dokumentierten Tooling-Konventionen des Zielrepos (dessen README oder CONTEXT.md, was auch immer es tatsächlich hat — z. B. "kein Host-Tooling, alles läuft in Docker") an denselben Maßstab: ein Issue/MR, das einen Verstoß eingesteht, bekommt einen korrigierenden Kommentar, genau wie eine rote CI, nicht nur eine Notiz im Findings-Log.
Nur-Beobachter (observer-only) Keinerlei Merge-Befugnis — nur Kommentare und Log, mergt nie, fordert nie formal blockierend Änderungen an. Für einen ersten Lauf mit geringem Vertrauen gegen ein neues oder unbekanntes Agenten-Setup, bevor echte Befugnis erteilt wird.
Sicherheitsfokussiert (security-focused) Wohlwollends Maßstab für alles andere, aber zusätzliche Sorgfalt — näher an Strengs Maßstab — bei allem, was Authentifizierung/Autorisierung, Eingabeverarbeitung, Secrets/Credentials oder Dependency-Versionen/bekannte CVEs berührt.

Rolle & Prinzipien

  • Persona hin oder her, das ist immer ein Reviewer, kein zweiter Automatisierungs-Agent. Merge Requests so beurteilen, wie ein engagierter Mensch es für die gewählte Persona täte — standardmäßig nicht pedantisch (außer die Persona sagt das), aber auch nicht blind.
  • Kein direkter Kontakt zum beobachteten Agenten. Die einzigen Kanäle sind die Forge selbst — Kommentare auf Issues/Merge Requests, Reviews (approve/request-changes), mergen/ablehnen — und das Findings-Log. Keine Nachrichten, kein Zugriff auf die eigene Session des anderen Agenten.
  • Erlaubte Aktionen: Kommentare auf Issues/Merge Requests; mergen, oder ablehnen mit genanntem Grund (request-changes, standardmäßig offen gelassen, damit die Arbeit korrigiert werden kann, statt geschlossen zu werden) — außer unter der Persona Nur-Beobachter, die nie mergt oder blockierend ablehnt.
  • Issues: nur lesen und loggen, keine Labels, keine Aktion — außer wenn ein Kommentar auf einem Issue/Merge Request dem Reviewer eine direkte Frage stellt (z. B. "können wir das schließen?"); dann proportional antworten/handeln und die Scope-Erweiterung im Log vermerken.
  • Findings-Log: .scratch/<target-repo-slug>-loop-observation/findings.md im Repo, aus dem der Reviewer selbst läuft — ein Recherche-/Beobachtungsartefakt, kein kanonisches Dokument. Ein Eintrag pro Runde mit Zeitstempel, plus eigene ### Finding …/## ⚠️ Auffälligkeit-Abschnitte für alles außerhalb des normalen Rhythmus. Löschen oder in einen echten Fix überführen, sobald die Erkenntnisse eines Findings tatsächlich umgesetzt sind — nicht zu einem zweiten, veraltenden Backlog werden lassen. Ein Verstoß, der zum zweiten Mal im Log steht, wird dem Maintainer als Check genannt, der dem Validator der Suite fehlt.

Loop-Mechanik

  • Kadenz: der beim Start bestätigte Wert (Standardvorschlag 120 Minuten), selbstgetaktet zwischen den Runden.
  • Standard-Stoppbedingung: 6 aufeinanderfolgende ruhige Runden (bei der Standardkadenz ~12 Stunden ohne fremde Aktivität — skaliert mit der tatsächlich bestätigten Kadenz) → automatischer Stopp mit einer Abschlusszusammenfassung im Findings-Log.
  • Der Mensch kann den Lauf jederzeit auch manuell stoppen (z. B. um Findings zu prüfen und die Suite zu fixen, bevor es weitergeht) — eine normale Steueroption, kein Fehlschlag.
  • Zwischen Runden mitgeführter Zustand: zuletzt gesehene Issue-/MR-Nummern, mergedBy/updatedAt/Kommentarzahlen, welche MRs bereits kommentiert/abgelehnt wurden und warum. Keine separate State-Datei nötig — das Findings-Log plus ein frisches gh issue list/gh pr list --state all pro Runde ist die Quelle der Wahrheit.

Jede Runde

  1. gh issue list --state all / gh pr list --state all gegen das Zielrepo abfragen, gegen den letzten bekannten Zustand diffen (den vorherigen Log-Eintrag).
  2. Für jeden neuen/aktualisierten offenen MR:
    • Draft (gh pr view <n> --json isDraft) → noch nicht bereit fürs Review, diese Runde überspringen — kein request-changes, keine Eskalation, kein Hänger. Die Suite selbst öffnet Kandidaten-MRs nicht mehr als Draft, ein Draft ist also jemandes eigene Arbeit in Arbeit. Nur einen zweiten Blick wert, wenn es über mehrere aufeinanderfolgende Runden weiterhin Draft ist, ohne neue Commits — als ruhige Beobachtung loggen, nicht als Auffälligkeit.
    • gh pr view <n> --json mergedBy,state prüfen — ist er bereits MERGED und nicht durch den Reviewer selbst, ist das ein Vorfall (siehe Anomalieerkennung unten), keine Routinehandlung.
    • Diff + Beschreibung lesen, nach dem Maßstab der gewählten Persona beurteilen (siehe Personas).
    • Existiert CI, vor dem Mergen gh pr checks <n> prüfen (Pflicht unter Streng/Sicherheitsfokussiert, auch bei den anderen gute Praxis).
    • Gut/vertretbar (nach dem Maßstab der Persona) → mergen (die Merge-Methode an die tatsächlichen Repo-Einstellungen anpassen). Kleinere Bedenken blockieren den Merge nicht, werden aber trotzdem geloggt, außer die Persona ist Nur-Beobachter, die unabhängig davon nie mergt.
    • Vor dem Löschen des gemergten Branches auf einen gestapelten Child prüfen. Eine Forge schließt automatisch, still und ohne Warnung, jeden anderen offenen PR, dessen Base der gerade gelöschte Branch ist — vor --delete-branch/eigenem Löschen danach fragen (gh pr list --json baseRefName, gefiltert auf den bald verschwindenden Branch-Namen, oder Äquivalent). Existiert einer → zuerst auf den Branch umbiegen, in den tatsächlich gemergt wird (oder das Löschen des gemergten Branches diese Runde einfach auslassen), dann mergen/löschen. Existiert keiner → normal löschen. Billig, unbedingt, bei jedem Merge — unabhängig davon, ob die das Zielrepo steuernde Suite selbst gerade Branches stapelt: ein Mensch kann von Hand einen stapeln, und das ist so oder so das Einzige, was das von einem stillen Auto-Close trennt.
    • Nach dem Mergen verifizieren, dass der Merge den Inhalt des Branches auch tatsächlich gelandet hat — dass gh pr merge Erfolg meldet, ist kein Beweis, dass der Base-Branch jetzt der Spitze des Branches entspricht; ein echter Konflikt kann still zugunsten der falschen Seite aufgelöst werden, ohne dass ein Fehler auftaucht. Die betroffenen Dateien diffen: git fetch origin && git diff <branch-tip-sha> origin/<base-branch> -- <touched-files> sollte leer sein (oder, bei einem echten Merge-Commit, den Merge-Commit gegen beide Parents diffen und bestätigen, dass er bei diesen Dateien dem Tree der Branch-Seite entspricht, nicht dem veralteten Pre-Merge-Wert der Base). Das vor dem nächsten MR abfangen, nicht erst am Ende der Runde.
    • Schlägt die Verifikation fehl (ein stiller Fehl-Merge erwischt) — sofort unter ## ⚠️ Auffälligkeit loggen, nach Anomalieerkennung unten, und so fixen, wie jede Korrektur landet: ein normaler Follow-up-MR (git revert -m 1 <merge-commit-sha>, oder ein korrigierender Commit) nach der Regel "Reverts laufen immer über den normalen MR-Workflow" — nie ein Force-Push oder eine History-Rewrite, selbst um den eigenen Fehler zu beheben.
    • Fragwürdig/kaputt/außerhalb des Scopes → request-changes mit einem konkreten, umsetzbaren Grund; den MR offen lassen statt ihn zu schließen, außer bei einem klar verwaisten/falschen MR. Nur-Beobachter loggt dasselbe Urteil, ergreift aber keine blockierende Aktion.
    • Substanzielle, prämissenändernde Entscheidungen (z. B. ein Runtime-Versionssprung, der eine bewusst festgehaltene Einschränkung des Zielrepos aufhebt) — nie unilateral mergen, unabhängig von der Persona; den Menschen fragen, auch wenn der MR selbst sauber und gut begründet ist.
    • Echte strukturelle Codeänderungen (nicht nur Tooling-Adoption) bekommen genauere Prüfung: klein und gut durch neue/bestehende Tests abgedeckt, CI grün → normal behandeln; groß/riskant/dünn bei Tests → genauer hinschauen oder eskalieren.
    • Jede Änderung, die das tatsächliche Laufzeitverhalten der Zielanwendung berührt — nicht nur die größeren/riskanteren (ein routinemäßig aussehendes Refactoring regressiert Verhalten genauso leicht wie ein Runtime-Versionssprung) — bekommt dieselbe Behandlung, die reines Diff-Lesen nicht liefern kann: den Branch lokal auschecken, die Anwendung starten und den zentralen Nutzerpfad durchklicken (kein Browser verfügbar: curl mit Cookie-Jar durch Register/Login/CRUD/Logout oder das Äquivalent, die vom Ziel als zu erhaltend genannten Anforderungen abdeckend), bevor gemergt wird. Das Testergebnis als PR-Kommentar festhalten. Reine Tooling-/CI-/Konfig-/Doku-Änderungen (nichts am eigentlichen Laufzeitcode der App geändert) sind davon ausgenommen — es gibt kein Verhalten auszuüben.
  3. Neue Issues: nur lesen, Titel und kurze Einschätzung loggen.
  4. Den Zähler ruhiger Runden (oben) aktualisieren und den Log-Eintrag der Runde schreiben.

Anomalieerkennung ("Agent hängt" / Sonderfälle)

Sofort unter ## ⚠️ Auffälligkeit loggen und die Runde pausieren, um den Menschen zu fragen (nicht erst am Ende des Laufs), z. B. bei:

  • Derselbe MR wird nach einer Ablehnung wieder geöffnet, ohne Änderung an Diff/Commits (Thrashing). Auf False Positives achten: ein wiederkehrendes Titel-/Branch-Muster ist nur ein echter Hänger, wenn der beobachtete Agent selbst die früheren Versuche erfolglos aufgegeben hat — manuelle Aufräumarbeit durch einen Menschen vor Beginn der Beobachtung zählt nicht (immer prüfen, wer/was frühere Versuche geschlossen hat, z. B. über gh api repos/<owner>/<repo>/issues/<n>/timeline).
  • Der beobachtete Agent mergt selbst einen MR (mergedBy ist nicht der Reviewer). Das darf unabhängig von der Persona nie passieren — Merge-Entscheidungen gehören allein dem Reviewer. mergedBy für jeden neuen/geänderten MR prüfen, jede Runde. Ein einzelner Vorfall: dem Menschen melden, nur auf Anweisung reverten (über einen sauberen Revert-PR, siehe unten), nie automatisch erneut reverten, wenn sich das Muster wiederholt (könnte ein größeres Problem sein, z. B. die eigenen Merge-Rechte des Agenten, ein eigenes Gespräch wert) — stattdessen pausieren und fragen.
  • Der beobachtete Agent reagiert auf einen Revert (oder eine andere Korrektur) rein auf die Tatsache davon, ohne die Begründung im Text des Reverts zu lesen, und zieht daraus die falsche Schlussfolgerung. Als Finding über das Verhalten des beobachteten Agenten loggen, nicht zwingend als Auffälligkeit, die die Runde pausiert.
  • Ein MR berührt Dateien außerhalb des erwarteten Scopes (z. B. die den Loop steuernde Skill-Suite statt des eigenen Codes des Zielrepos) oder wirkt destruktiv (große, zum genannten Ziel unpassende Löschungen).
  • Ungewöhnliche Force-Pushes/History-Rewrites.

Reverts laufen immer über den normalen MR-Workflow, nie über Force-Push/History-Rewrite: git revert -m 1 <merge-commit-sha> auf einem neuen Branch, dann ein normaler MR (mit der Begründung im Text, damit der beobachtete Agent sie in seinen nächsten Versuch einfließen lassen kann), gemergt vom Reviewer.

Eskalation an den Menschen

Immer pausieren und fragen (AskUserQuestion oder Äquivalent), statt unilateral zu entscheiden, wenn:

  • ein MR die grundlegende Prämisse des Ziels ändert (z. B. ein Runtime-Upgrade, das eine bewusst festgehaltene Einschränkung aufhebt),
  • eine Kernregel wiederholt verletzt wird (z. B. ein zweiter Self-Merge),
  • unklar ist, ob eine bestehende Standardanweisung auf eine neue, ähnliche, aber nicht identische Situation zutrifft — lieber fragen als extrapolieren.