Zum Hauptinhalt springen

diagnosing-bugs: Diagnose-Loop für harte Bugs

On-Ramp🤖 Kann selbst gewählt werden🔧 Angepasst für unser SetupHerunterladen ↓

Eine Disziplin für harte Bugs: den flüchtigen Fehler, den intermittierenden Flake, die Regression, die sich zwischen zwei bekannt-guten Zuständen eingeschlichen hat.

Wann brauche ich das?​

Wenn etwas kaputt ist, sich aber nicht auf den ersten Blick erklärt.

Wie funktioniert das?​

Phase 1: Eine scharfe Rot/Grün-Schleife bauen, das ist der Kern​

Alles andere ist danach mechanisch. Testläufe sind bei uns möglich (bestätigt), also gilt: du stößt den Lauf an, wenn die KI ihn vorschlägt, und gibst das Ergebnis zurück. Wege, eine Schleife zu bauen, ungefähr in dieser Reihenfolge:

  1. Fehlschlagender Test an der Stelle, die den Bug erreicht (Unit, Integration, E2E).
  2. Curl/HTTP-Skript gegen einen laufenden Dev-Server.
  3. CLI-Aufruf mit einem Fixture-Input, Diff gegen einen bekannt-guten Snapshot.
  4. Headless-Browser-Skript (Playwright/Puppeteer), das die UI treibt und auf DOM/Konsole/Netzwerk prüft.
  5. Eine mitgeschnittene Anfrage wiederholen (echten Request/Payload speichern, isoliert erneut abspielen).
  6. Wegwerf-Testkabel: eine minimale Teilmenge des Systems (ein Service, gemockte Abhängigkeiten).

Was nicht autonom läuft: git bisect run über viele Commits unbeaufsichtigt, ein Property-/Fuzz-Loop mit 1000 automatischen Durchläufen, Debugger-Fernsteuerung. Diese Automatisierung setzt eine Verkettung vieler Schritte ohne Zwischenschau voraus, das fällt unter "keine Agenten". Stattdessen führst du die Iterationen einzeln aus, auf Vorschlag hin, und meldest das Ergebnis zurück. Bei Bisection heißt das: die KI schlägt vor, welchen Commit als Nächstes zu prüfen ist, du checkst ihn aus und lässt den Test laufen, ihr wiederholt das gemeinsam statt automatisiert.

Fertig ist Phase 1, wenn du einen einzigen Befehl nennen kannst, den du schon mindestens einmal ausgeführt hast (zeig den Aufruf und die Ausgabe, Secrets geschwärzt), und der:

  • rot-fähig ist: trifft den echten Bug-Pfad und prüft das genaue Symptom.
  • deterministisch ist: gleiches Ergebnis bei jedem Lauf.
  • schnell ist: Sekunden, nicht Minuten.

Phase 2: Reproduzieren und minimieren​

Lauf laufen lassen, bestätigen, dass er das vom Nutzer beschriebene Symptom zeigt (nicht ein ähnliches). Dann schrittweise verkleinern: Eingaben, Aufrufer, Konfiguration einzeln streichen, nach jedem Schritt erneut laufen lassen, bis alles Verbleibende tragend ist.

Phase 3: Hypothesen bilden​

3-5 rangierte Hypothesen, bevor irgendeine getestet wird. Eine einzelne Hypothese verankert zu früh auf der ersten plausiblen Idee. Jede muss falsifizierbar sein: "Wenn X die Ursache ist, dann macht das Ändern von Y den Bug verschwinden." Zeig die Rangfolge, bevor ihr testet, du kennst oft Kontext, der sofort umsortiert.

Phase 4: Instrumentieren​

Jede Sonde bildet genau eine Vorhersage aus Phase 3 ab, eine Variable pro Schritt. Bevorzugt: Debugger/REPL-Inspektion in der IDE (ein Breakpoint schlägt zehn Logs), sonst gezielte Logs mit eindeutigem Tag ([DEBUG-a4f2]), niemals "alles loggen und grep".

Phase 5: Fix und Regressionstest​

Regressionstest vor dem Fix schreiben, aber nur an einer korrekten Naht (die den echten Bug-Pfad trifft). Gibt es keine passende Naht, ist das selbst ein Befund: die Architektur verhindert, dass sich der Bug festschreiben lässt.

Phase 6: Aufräumen​

  • Ursprünglicher Repro reproduziert nicht mehr (Phase-1-Schleife erneut laufen lassen)
  • Regressionstest ist grün (oder das Fehlen einer Naht ist dokumentiert)
  • Alle [DEBUG-...]-Instrumentierung entfernt
  • Die bestätigte Hypothese steht in der Commit-/PR-Nachricht

Wo passt das rein?​

Standalone, jederzeit erreichbar, sobald etwas kaputt ist. Der Fix mündet zurück in implement; fehlt eine korrekte Naht für den Regressionstest, ist das ein Fall für improve-codebase-architecture. Gesamtüberblick: ask-simon.

Was sich gegenüber dem Original geändert hat​

  • Vollautomatisierte Loops (git bisect run, Fuzz-Loop mit 1000 Durchläufen) werden zu von dir einzeln ausgeführten Iterationen. Die Disziplin (erst Schleife, dann minimieren, dann hypothetisieren) bleibt vollständig erhalten.
  • Kein HITL-Bash-Skript für "ein Mensch muss klicken" nötig, da Testläufe direkt möglich sind.