Suche/Getestete, reviewfertige Änderungen in einer großen Codebasis machen

Getestete, reviewfertige Änderungen in einer großen Codebasis machen

Für den Einsatz, wenn ein KI-Agent eine große, mehrsprachige Codebasis ändert. Er baut über den Wrapper des Projekts, legt Tests neben den Code und prüft, dass sie ohne die Änderung fehlschlagen, hält sich an die Review-Regeln und meldet nur, was er selbst ausgeführt hat.

Diese KI-Regeln verwenden
## Nur über den Wrapper des Projekts bauen und Tests ausführen Große Projekte bündeln ihren Compiler und Test-Runner meist in einem einzigen Projektbefehl, der vor jeder Ausführung neu kompiliert und lokale Änderungen einbindet. Baue und führe Code immer über diesen Wrapper aus. Rufe niemals den rohen Test-Runner oder eine zuvor kompilierte Binärdatei direkt auf, denn dabei werden veraltete Artefakte ausgeführt, die die eigene Änderung nicht enthalten – ein erfolgreiches Ergebnis beweist dann gar nichts. Lerne, bei welchen Änderungen der native Neu-Build übersprungen werden kann. Änderungen, die nur nicht kompilierte Eingaben betreffen, etwa Typdeklarationen oder gebündelte Skripte, die sich selbst neu laden, brauchen keinen vollständigen Build – ihn trotzdem zu erzwingen, verschwendet nur Zeit. Führe stattdessen direkt die leichtere, gezielte Prüfung aus. Setze für einen vollständigen Build kein Zeitlimit. Ein regulärer Kaltstart-Build kann lange dauern, und ihn abzubrechen erzeugt verwirrende, irreführende Fehlermeldungen. Wenn der Wrapper nachgestellte Argumente an das gebaute Programm weiterreicht, platziere Build-Flags vor diesen Ausführungsargumenten, damit die Zuordnung eindeutig bleibt. ## Tests in die vorhandene Testdatei des geänderten Codes einfügen Füge einen neuen Test standardmäßig der bestehenden Testdatei für den geänderten Code hinzu. Ein Fehler im Verhalten eines Bereichs gehört in dessen bestehende Testdatei, nicht in eine brandneue Datei. Erst die Nähe zu verwandter Testabdeckung macht einen Test auffindbar und verhindert doppelten Einrichtungsaufwand. Orientiere dich an der etablierten Teststruktur des Repositorys: Unit-Tests gruppiert nach Subsystem, Kompatibilitätstests, Plattform- und Web-API-Tests, Kommandozeilentests sowie End-to-End-Integrationstests, jeweils in ihrem eigenen Bereich. Platziere deinen Test dort, wo bereits vergleichbare Abdeckung existiert. Reserviere Ordner für Spezialfälle exakt für den Zweck, für den sie gedacht sind. Ein nach Issue-Nummer benannter Regressionsordner ist ausschließlich für echte Regressionen bestimmt – also Verhalten, das in einer früheren Version funktionierte und dann kaputtging –, und diese Kennung muss real sein, niemals ein Platzhalter. War das Verhalten nie korrekt, handelt es sich nicht um eine Regression, und der Test gehört in die normale Datei des jeweiligen Moduls. ## Tests schreiben, die bei jedem Lauf dasselbe Ergebnis liefern Bevorzuge Snapshot-Assertions gegenüber spröden Gleichheitsprüfungen bei umfangreicher Ausgabe, und normalisiere den Snapshot so, dass zufällige Werte wie temporäre Pfade keine unnötigen Änderungen verursachen. Schreibe niemals einen Test, der nur die Abwesenheit eines Absturzes oder einer unbehandelten Ausnahme prüft; ein solcher Test kann in der Pipeline nie fehlschlagen und vermittelt eine trügerische Sicherheit. Beseitige jede Quelle von Nichtdeterminismus. Kodiere keinen Netzwerk-Port fest; binde stattdessen an einen ephemeren Port und lies den tatsächlich zugewiesenen aus. Verwende niemals Sleep oder einen Timer, um auf etwas zu warten, denn getestet wird der Zustand, nicht der Zeitablauf; warte stattdessen auf die tatsächliche Bedingung. Nutze den Temporärverzeichnis-Helfer des Test-Frameworks, statt Temporärverzeichnisse manuell anzulegen, und vermeide Shell-Werkzeuge wie Datei- oder Textsuche innerhalb eines Tests – verwende stattdessen die projekteigenen Datei-APIs. Wenn ein Test einen Prozess startet, prüfe zuerst dessen Ausgabe und erst dann den Exit-Code, damit ein Fehlschlag eine aussagekräftige Meldung liefert statt eines nackten Statuscodes ungleich null. ## Prüfen, dass neue Tests ohne die Änderung fehlschlagen, und nur selbst Ausgeführtes melden Eine Änderung ist erst fertig, wenn sie getestet ist. Wurden die Tests nicht ausgeführt, ist davon auszugehen, dass der Code nicht funktioniert; das Ausführen der Tests gehört zur Fertigstellung, nicht zu einem optionalen Nachgang. Weise nach, dass jeder neue Test die eigene Änderung tatsächlich prüft. Er muss gegen die unveränderte Ausgangsversion fehlschlagen und gegen den eigenen Build bestehen. Ein Test, der schon ohne die Änderung besteht, beweist gar nichts – bestätige also beide Richtungen, bevor du ihm vertraust. Sei in jeder Commit-Nachricht, jeder Review-Antwort und jedem Statusupdate bescheiden und ehrlich. Übertreibe niemals, was erreicht wurde oder was tatsächlich funktioniert. Berichte nur Ergebnisse, die aus dem eigenen Lauf beobachtet wurden, und benenne klar, was noch unbestätigt oder unfertig ist, statt den Eindruck zu erwecken, die Arbeit sei abgeschlossen. ## Vor dem Ändern verstehen, wie die Codebasis aufgebaut ist Verschaffe dir vor jeder Änderung einen Überblick über die Organisation der Codebasis: welche Schicht welche Verantwortung trägt, wo gemeinsam genutzte Hilfsfunktionen liegen und welche Dateien generiert sind statt von Hand geschrieben. Generierte Dateien entstehen aus Quelldefinitionen – bearbeite also die Quelle und lasse den Build sie neu erzeugen; bearbeite generierte Ausgaben niemals von Hand, denn der nächste Build überschreibt sie ohnehin. Identifiziere das Subsystem, dem das betroffene Verhalten gehört – sei es das Parsing, die Modulauflösung, die Laufzeit-APIs, Netzwerk, Speicher, der Bundler oder der Paketmanager –, damit sowohl die Änderung als auch ihr Test am richtigen Ort landen. Halte dich an den bestehenden Codestil. Prüfe benachbarte Dateien auf etablierte Muster und übernimm diese, statt Konventionen aus einem anderen Projekt zu importieren. Bevorzuge das sprachtypische Idiom für Ressourcenverwaltung, etwa scope-basierte automatische Bereinigung, gegenüber manuellem Aufräumen, und beachte dokumentierte Sonderfälle, etwa Werte, die in einem Bereich alloziert werden, der beim Zurücksetzen ihre Destruktoren überspringt und die deshalb zuerst explizit freigegeben werden müssen. ## Die Review-Regeln lesen und die Pflichtkonventionen des Projekts befolgen Ein ausgereiftes Projekt destilliert das, worüber seine Reviewer Merges blockieren, in ein schriftliches Regelwerk. Lies dieses, bevor du Code schreibst, der eine nicht offensichtliche Entscheidung trifft, und lies jeden situativen Leitfaden für den betroffenen Bereich – etwa Kompatibilitätsschichten, nutzerseitiges API-Design, performancekritische Hot Paths, plattformabhängigen Code, Änderungen an Abhängigkeiten und Vendoring oder Dokumentation und Typdeklarationen –, bevor du diese konkrete Arbeit beginnst. Halte die vom Projekt geforderten Konventionen exakt ein, denn die automatisierte Pipeline erzwingt sie. Verwende das vorgeschriebene Branch-Namenspräfix, halte Codekommentare kurz – tiefere Erklärungen gehören in die Dokumentation und werden nur geschrieben, wenn ausdrücklich verlangt –, und verwende bei Dateioperationen absolute Pfade. Kompiliere bei einer plattformspezifischen Änderung für jedes unterstützte Zielsystem, da bedingt kompilierter Code nur dann typgeprüft wird, wenn das passende Zielsystem tatsächlich gebaut wird. ## Bei fehlgeschlagenen Builds die Diagnosewerkzeuge des Projekts nutzen und sie bei falschen Angaben reparieren Wenn ein automatisierter Build fehlschlägt, nutze die dafür vorgesehenen Diagnosebefehle des Projekts – jene, die fehlgeschlagene Tests darstellen, den Job-Status zusammenfassen und vollständige Logs speichern –, statt sich dieses Bild manuell zu rekonstruieren. Sie trennen bereits neue Fehlschläge von solchen, die auch anderswo auftreten, und filtern routinemäßiges Rauschen heraus. Verwende beim Lesen von Feedback zu einer Änderung den Befehl, der das vollständige Bild liefert. Eine allgemeine Auflistung lässt Review-Zusammenfassungen und zeilenbezogene Kommentare oft stillschweigend aus – bevorzuge daher das Werkzeug, das übergeordnete Kommentare, Reviews und Inline-Kommentare gemeinsam in einer chronologischen, beschrifteten Ansicht liefert. Wirkt die Ausgabe eines Hilfswerkzeugs falsch, etwa eine fehlerhaft geparste Annotation oder ein Feld, dessen Ausgangsstruktur sich geändert hat, korrigiere den Presenter selbst, statt das Problem weiter unten zu umgehen. Das Hilfswerkzeug ist nur eine dünne Schicht über dem eigentlichen Tool, und es zu reparieren hält jeden späteren Lauf korrekt.