


Code einer Hochleistungsdatenbank ändern, ohne Tempo oder Kompatibilität zu verlieren
Für Änderungen durch eine KI an einer auf Tempo ausgelegten Datenbank mit Java, SQL, Rust, nativem Code und CI. Legt Regeln für Codestil, NULL, Speicherfreigabe, Abfragetests, Fehlersuche, Pull Requests und Builds fest und endet mit einer Prüfung vor der Fertigmeldung.
Diese KI-Regeln verwenden
## Datenbankmodule getrennt halten und Datenpfade ohne Allokationen schützen
- Bewahre klare Modulgrenzen für Speicher-Engine, SQL-Engine, Netzwerkprotokolle, Hilfsprogramme, Worker-Warteschlangen, Protokollierung, Hintergrundaufgaben, Benchmarks, Kompatibilitätstests und Beispiele.
- Halte Produktivcode von Benchmarks, Build-Hilfsprogrammen, Beispielen und Plattform-Wrappern getrennt.
- Behandle ein verschachteltes Client-Repository oder Submodul als eigenständiges Repository mit eigenen Commits und einem eigenen Kompatibilitätsziel.
- Ermittle den richtigen Einstiegspunkt, bevor du Verhalten änderst: Serverstart, Speicher-Engine, SQL-Compiler, Tabellenleser oder Tabellenschreiber.
- Schütze Datenpfade ohne Allokationen während der Abfrageausführung und Datenaufnahme.
- Bevorzuge Objektpools, wiederverwendbare Puffer, spaltenorientierte Speicherung, vektorisierte Ausführung und native Beschleunigung, wenn die Architektur sie erfordert.
- Führe keine Laufzeitabhängigkeiten von Drittanbietern ein, wenn das Projekt leistungskritische Algorithmen bewusst selbst implementiert.
- Beschränke nativen Code auf Vorgänge, die seine Risiken für Speicher, Plattformen und Fehler rechtfertigen.
## Java-Klassenmember ordnen und ältere Java-Clients kompatibel halten
- Gruppiere Klassenmitglieder nach statischer oder Instanzzugehörigkeit und Sichtbarkeit und ordne die Mitglieder innerhalb jeder Gruppe alphabetisch.
- Füge neue Felder und Methoden an ihrer richtigen sortierten Position ein, statt dekorative Abschnittsgruppen zu erstellen.
- Verwende niemals Bannerkommentare als künstliche Java-Abschnittsüberschriften.
- Nutze die vom Hauptmodul unterstützten modernen Sprachmerkmale, darunter erweiterte `switch`-Ausdrücke, mehrzeilige Zeichenketten und Mustervariablen.
- Beachte ältere Sprachziele in Kompatibilitätsmodulen; Syntax des Hauptmoduls darf nicht in einen Client gelangen, der auf eine frühere Java-Version zielt.
- Stelle booleschen Variablen, Feldern und Methoden je nach Bedeutung `is` oder `has` voran.
- Verwende in Protokollmeldungen ausschließlich ASCII, wenn die Protokollierung Unicode-Satzzeichen oder -Symbole nicht zuverlässig darstellen kann.
- Nutze die ressourcenbewussten Sammlungstypen des Projekts statt generischer Objekt-Arrays, wenn sie in die vorhandenen Bereinigungshilfen eingebunden sind.
- Halte dich an bestehende Muster für Benennung, Besitz und Allokation, bevor du eine neue Abstraktion einführst.
## NULL-Verhalten festlegen und Speicher auf jedem Fehlerpfad freigeben
- Lege das NULL-Verhalten für Spaltendaten, Ausdrucksergebnisse, SQL-Anweisungen und Zwischenzustände ausdrücklich fest.
- Unterscheide einen NULL-Sentinel mit der Bedeutung „noch nicht initialisiert“ von einem echten Daten-NULL.
- Verfolge jede Allokation und jede schließbare Ressource durch Erfolgs-, Fehler-, Abbruch- und vorzeitige Rückgabepfade.
- Verwende die Bereinigungshilfen des Repositories durchgängig für Listen und schließbare Elemente.
- Behandle die Vermeidung von Lecks als Entwurfsanforderung und nicht nur als Testanliegen.
- Ergänze Tests, die nativen Speicher allozieren, um Zusicherungen gegen Speicherlecks.
- Eng begrenzte Unit-Tests, die nachweislich keinen nativen Speicher allozieren, dürfen auf die Leck-Prüfumgebung verzichten.
- Prüfe die Bereinigung auf jedem relevanten Fehlerpfad, nicht nur auf dem erfolgreichen Pfad.
- Verberge Unklarheiten über den Besitz niemals hinter einem bequemen Container oder Hilfsprogramm.
## Abfragen mit strengen Zusicherungen testen, die Ergebnisse erneut lesen
- Bevorzuge das maßgebliche Fluent-Framework für Abfragezusicherungen gegenüber älteren Hilfen, die nur einmal ausgeben und vergleichen.
- Verlange bei deterministischen Abfragen einen zweiten Cursor-Durchlauf, Größenabgleiche, Prüfungen variabler Spalten und einschlägige Zusicherungen zu Factory-Eigenschaften.
- Verwende eine Zusicherung mit nur einem Durchlauf ausschließlich dann, wenn die Projektion bei erneutem Lesen tatsächlich instabil ist, und nenne den Grund.
- Gültige Beispiele für Instabilität sind Zufallsfunktionen ohne gesetzten Startwert und zeitabhängige Funktionen.
- Führe DDL und andere Anweisungen, die keine Abfragen sind, über den Ausführungspfad für Nicht-Abfragen aus.
- Prüfe Ausführungspläne mit den Planhilfen des Frameworks, wenn das Verhalten des Optimierers Teil des Vertrags ist.
- Verwende eine einzige `INSERT`-Anweisung für mehrere Testzeilen, wenn der Dialekt dies unterstützt.
- Nutze mehrzeilige Zeichenketten für langes SQL und mehrzeilige erwartete Ergebnisse.
- Schreibe SQL-Schlüsselwörter einheitlich, vorzugsweise in Großbuchstaben.
- Trenne Tausender in Literalen mit mindestens fünf Ziffern durch Unterstriche, wenn diese Syntax unterstützt wird.
## Den SQL-Dialekt einhalten und Fehler auf das genaue Zeichen zeigen lassen
- Behandle mehrdimensionale Array-Typen als eigenständige Typen, wenn die Anzahl der Dimensionen im Spaltentyp codiert ist.
- Verwende durchgängig die bevorzugte Typumwandlungssyntax des Dialekts, statt gleichwertige Formen zu mischen.
- Halte die Unterstützung numerischer Trennzeichen zwischen Parser, Implementierungscode und Tests konsistent.
- Setze nicht voraus, dass Standard-SQL-Funktionen vorhanden sind; dokumentiere und teste nicht unterstützte Operationen.
- Wenn das Löschen von Zeilen nicht unterstützt wird, bilde logisches Löschen ausdrücklich in der Anwendungslogik ab.
- Halte Löschoperationen auf Partitionsebene vom Löschen einzelner Zeilen getrennt, da sich ihr Umfang und ihre Sicherheit unterscheiden.
- Lass eine gemeldete SQL-Fehlerposition auf das genaue fehlerverursachende Zeichen zeigen, nicht nur auf den Anfang des Ausdrucks.
- Prüfe Parserfehler sowohl hinsichtlich der Meldung als auch der genauen Position.
- Bewahre den Unterschied zwischen Syntax-, Semantik-, Typ- und Ausführungsfehlern.
## Jeden fehlgeschlagenen Test als echten Fehler behandeln, bis Belege anderes zeigen
- Behandle jeden roten Test, jeden fehlgeschlagenen CI-Auftrag und jeden überraschenden Protokolleintrag als aktuellen Defekt, bis Nachweise das Gegenteil belegen.
- „Bereits vorhanden“, „unzuverlässig“, „nicht zusammenhängend“ und „bekanntes Problem“ sind Hypothesen, keine Schlussfolgerungen.
- Reproduziere den Fehler auf der maßgeblichen Ausgangsbasis, prüfe den Versionsverlauf, miss zeitliche Randbedingungen und kontrolliere maßgebliche Berichte des Ursprungsprojekts.
- Lege einen Fehler erst beiseite, wenn die Nachweise diese Schlussfolgerung erzwingen.
- Berichte die Nachweise, die die Einordnung begründet haben, damit eine andere prüfende Person sie verifizieren kann.
- Betrachte einen erfolgreichen erneuten Lauf nicht als alleinigen Beweis dafür, dass ein Fehler harmlos war.
- Untersuche Wechselwirkungsfehler, wenn mehrere Änderungen zur selben CI-Abfolge gehören.
- Bewahre Protokolle, fehlschlagende Eingaben und die kleinste zuverlässige Reproduktion auf, die für die Diagnose erforderlich ist.
- Beschränke die Korrektur auf die nachgewiesene Ursache und ergänze einen Regressionstest, der ohne sie fehlschlägt.
## Branches und Pull Requests an Merge-Verfahren und CI-Aufwand anpassen
- Richte die Strategie für Branches und Pull Requests am Zusammenführungsmodell des Repositories und an den CI-Kosten aus.
- Verwende in einem Arbeitsablauf mit Squash-Merges keine Mühe darauf, eine später verworfene Branch-Historie zu glätten.
- Ergänze einen klaren Korrektur-Commit, statt frühere Commits umzuschreiben oder nur für eine kosmetische Historie einen Force-Push auszuführen.
- Bündele zusammengehörige Korrekturen, wenn eine Aufteilung lange CI-Läufe, das Risiko unzuverlässiger Tests und den Aufwand der Zusammenführung vervielfachen würde.
- Teile Änderungen nur auf, wenn der Benutzer dies verlangt oder wenn sie unabhängig zusammengeführt oder zurückgenommen werden müssen.
- Synchronisiere beim Aktualisieren eines vorhandenen Pull Requests mit dessen entferntem Head, füge die Änderungen diesem Branch hinzu und aktualisiere seine Metadaten.
- Eröffne nicht bloß einen zweiten Pull Request, um die Validierung derselben Änderungslinie erneut auszuführen.
- Erstelle keine Prüf-Worktrees und checke keine Branches aus, wenn die Repository-Richtlinie einen anderen Branch als maßgeblichen Prüfzustand festlegt.
- Rufe einen Pull-Request-Diff ab, ohne den Branch zu wechseln, wenn nur der Diff benötigt wird.
- Committe ein verschachteltes Repository intern, bevor du seinen Submodulzeiger im übergeordneten Repository festschreibst.
## In Pull Requests und Commits Vor- und Nachteile gleich deutlich nennen
- Verwende die vorgeschriebene Titelkonvention des Repositories für Pull Requests und gestalte die Beschreibung für Endbenutzer aussagekräftig.
- Beschreibe positive Auswirkungen, negative Auswirkungen, Regressionen und Abwägungen mit gleichem Gewicht.
- Vermeide Werbesprache, Superlative, selektiv ausgewählte Kennzahlen und dekorative Hervorhebungen.
- Verweise am Anfang des Pull-Request-Texts in der vorgeschriebenen Abschlussform auf ein behobenes Issue.
- Halte Commit-Titel kurz, beschreibend und im vorgeschriebenen Stil des Repositories.
- Füge einen gehaltvollen Commit-Text hinzu, der die Änderung erklärt, statt den Titel zu wiederholen.
- Verwende in Testplänen einfache Aufzählungspunkte, wenn Kontrollkästchen oder Häkchen untersagt sind.
- Weise Labels zu, die zum Änderungsbereich und Titel passen.
- Formuliere Commits, Pull Requests und Codekommentare im Aktiv.
- Benenne die handelnde Klasse, Methode, aufrufende Stelle oder Komponente, statt sie in Passivkonstruktionen zu verbergen.
## Erst die Umgebung prüfen, dann im kleinsten Umfang bauen und testen
- Prüfe vor dem Build die erforderliche Sprachlaufzeit, das Build-Werkzeug, die Architektur und die Umgebungsvariablen.
- Wähle das kleinste Build-Profil, das die aktuelle Änderung belegt, und verwende umfassendere Profile, wenn Web- oder native Artefakte betroffen sind.
- Erstelle abhängige Module erneut, wenn ein lokaler Artefakt-Cache einen veralteten Client oder eine veraltete Bibliothek enthalten könnte.
- Führe aufwendige Testaufrufe nacheinander aus, wenn parallele Builds einander stören.
- Beginne mit der engsten einschlägigen Testklasse oder -methode und erweitere die Prüfung anschließend entsprechend dem Risiko und der Repository-Richtlinie.
- Betrachte die Kompilierung allein nicht als Nachweis des Laufzeitverhaltens.
- Validiere den Server über den unterstützten Startpfad und prüfe den direkt betroffenen Endpunkt oder die direkt betroffene Schnittstelle.
- Bewahre Build-Artefakte an den dafür vorgesehenen, dem jeweiligen Modul zugeordneten Orten auf.
- Halte bei einem Build-Abbruch den genauen fehlgeschlagenen Befehl und den ersten verwertbaren Fehler fest.
## Alle Rust-Warnungen beseitigen und verhindern, dass ein Panic über JNI die JVM abstürzen lässt
- Führe vor Abschluss von Rust-Arbeiten im Crate-Stammverzeichnis Formatierung, Kompilierung aller Ziele, Lint-Prüfung und Bibliothekstests aus.
- Verlange in allen obligatorischen Prüfungen null Fehler und null Warnungen.
- Miss die Abdeckung nach dem Hinzufügen oder Ändern von Tests.
- Ergänze für jede nicht abgedeckte Zeile einen Test oder beweise, dass sie nicht erreichbar ist, und kennzeichne diese Invariante ausdrücklich.
- Rufe `unwrap()` oder `expect()` niemals für aus Dateien stammende oder extern bereitgestellte Daten auf.
- Gib behebbare Fehler mit `Result`, `Option` und der üblichen Fehlerweitergabe der Sprache weiter.
- Bedenke, dass eine Rust-Panik, die JNI überschreitet, die gesamte JVM ohne Wiederherstellungsmöglichkeit abbrechen kann.
- Baue native C- und C++-Bibliotheken mit der Release-Konfiguration des Repositories und überprüfe die erwarteten Artefakte.
- Behandle Besitz, Lebensdauer, Ausrichtung und Fehlerumwandlung an FFI-Grenzen als ausdrückliche Verträge.
- Teste Grenzfehler auf jeder unterstützten Plattform, die von der Änderung betroffen ist.
## Heap-Allokationen vermeiden und Geschwindigkeitsgewinne mit Benchmarks messen
- Vermeide Heap-Allokationen in Datenpfaden, in denen ein Verhalten ohne Garbage Collection eine Architekturanforderung ist.
- Verwende Puffer und gepoolte Objekte erneut und mache die Übertragung des Besitzes ausdrücklich.
- Speichere Analysedaten spaltenweise, wenn Komprimierung und vektorisierte Operationen von dieser Anordnung abhängen.
- Halte SIMD, Speicherverwaltung und plattformspezifische Optimierungen hinter engen nativen Grenzen.
- Trenne Speicherung, Parsing, Planung, Codegenerierung, Ausführung, Protokollverarbeitung und Hintergrundarbeit.
- Verwende angepasste Sammlungen nur, wenn ihr Allokations- und Bereinigungsverhalten verstanden und getestet ist.
- Miss Leistungsänderungen mit repräsentativen Benchmarks statt nach Intuition.
- Ergänze eine Optimierung um Korrektheitstests, Ressourcenprüfungen und eine dokumentierte Abwägung.
- Schwäche weder Kompatibilität noch Fehlergenauigkeit, um eine nicht gemessene Beschleunigung zu erzielen.
## Vor der Fertigmeldung den finalen Diff prüfen und die Ergebnisse berichten
- Prüfe den endgültigen Diff auf die Reihenfolge der Mitglieder, Kompatibilitätsgrenzen, NULL-Verhalten, Ressourcenbesitz und versehentliches Unicode in Protokollen.
- Führe die fokussierten Java-, SQL-, Rust-, nativen und Integrationstests aus, die von der Änderung betroffen sind.
- Bestätige, dass deterministische Abfragen den strengen Zusicherungspfad mit erneutem Lesen verwenden.
- Bestätige, dass externe Eingaben keine nicht behebbare native Panik auslösen können.
- Verifiziere, dass für jeden untersuchten Fehler eine nachweisgestützte Einordnung und eine dokumentierte Reproduktion vorliegen.
- Stelle sicher, dass Pull-Request-Metadaten, Labels, Testplan, Commit-Text und Issue-Verweise der Repository-Richtlinie entsprechen.
- Prüfe, dass verschachtelte Repositories und übergeordnete Zeiger in der richtigen Reihenfolge committet wurden.
- Melde keinen Abschluss, solange obligatorische Prüfungen Fehler oder Warnungen aufweisen.
- Berichte die ausgeführten Befehle, beobachteten Ergebnisse, verbleibenden Risiken und bewusst nicht getesteten Bereiche.
