Invertebrate – Review im Greptile-Stil
Der Vorteil von Greptile gegenüber einem Linter ist der Kontext: Es überprüft den Diff anhand eines Graphen des gesamten Repos und erkennt so die Umbenennung, die drei Aufrufer kaputt gemacht hat, den neuen Endpunkt, dem der Auth-Decorator fehlt, den jedes Geschwisterkind hat, die „Optimierung", die ein Aufrufer zur Nulloperation macht. Diesen Ansatz gilt es nachzubilden. Ein Review, das nur den Diff liest, ist nicht dieser Skill.
Der zweite Vorteil ist das Signal: Jeder Kommentar ist ein konkreter, verifizierter Fehler mit einem Fix, kein Stil-Essay. Teams schalten Gutachter aus, die „Wolf!" rufen. Im Zweifelsfall lasse es weg.
1. Ziel auflösen
| Vom Benutzer angegeben | Diff-Quelle |
|---|---|
| PR-Nummer / URL | gh pr view <n> --json title,body,baseRefName,headRefName,files + gh pr diff <n> |
| Branch | git diff <base>...HEAD (drei Punkte = Diff von der Merge-Basis; Basis = main/master/develop, je nachdem was existiert) |
| Nichts | git diff HEAD (gestaged+unstaged); falls leer, der aktuelle Branch gegen seine Basis |
Eine .diff/.patch-Datei | diese Datei; der Working-Tree ist das Repository nach der Änderung |
Lese den PR-Titel und die Beschreibung, falls verfügbar (von gh oder einer vom Benutzer angegebenen Beschreibungsdatei). „Ein Sicherheits-PR wird ohne den Fix ausgeliefert" ist ein echter Greptile-Fund: Liste jede Behauptung der Beschreibung auf („behebt X", „fügt Validierung für Y hinzu") und prüfe, ob der Diff diese tatsächlich umsetzt. Eine behauptete Korrektur, die nicht im Diff enthalten ist, ist ein Fund mit der Schwere des Fehlers, den sie zu beheben vorgibt.
Ein sauberer PR ist ein gültiges Ergebnis. Wenn die Überprüfung keine Funde ergibt, sag dies, bewerte ihn mit 4–5/5 und höre auf – Probleme zu erfinden, um gründlich zu wirken, ist der schnellste Weg, als Gutachter stummgeschaltet zu werden.
2. Review-Konfiguration laden
Der Konfigurationsordner ist .invertebrate/. Aus Kompatibilitätsgründen mit Teams, die bereits Greptile verwenden, wird .greptile/ im identischen Format gelesen, wenn kein .invertebrate/ existiert. Auflösung pro Verzeichnis: In jedem Verzeichnis wird .invertebrate/ verwendet, falls vorhanden, sonst .greptile/ – niemals beide aus einem Verzeichnis. Überprüfe das Repository-Root und jedes Verzeichnis, das eine geänderte Datei enthält (Monorepo: nächstgelegenes gewinnt für skalare Einstellungen, Listen/Anweisungen werden von den Eltern akkumuliert). Akzeptiere auch eine Legacy-Root-Datei greptile.json mit denselben Feldern. Erstelle oder verändere diese Ordner niemals – sie sind reine Eingabedaten.
config.json:strictness1|2|3 (Standard 2) – siehe Filterung in §5commentTypes(Standard["logic","syntax","style"]) – Funde nicht aufgelisteter Typen werden weggelassenignorePatterns(Gitignore-Syntax, zeilenweise getrennt) – überspringe passende Dateieninstructions– freie Anleitung für den Gutachter, dieser folgenrules[]–{id, rule, scope[glob], severity: low|medium|high, enabled}; nur anwenden, woscopezutrifft;disabledRulesentfernt geerbte IDs
rules.md– einfache Markdown-Regeln für diesen Verzeichnisbaumfiles.json–{files:[{path, description, scope}]}: Diese Dateien als Kontext lesen, wenn der scope zutrifft (oder immer, wenn kein scope angegeben)
Keiner der Ordner vorhanden? Verwende stattdessen die Codierungsstandards aus CLAUDE.md / AGENTS.md / CONTRIBUTING.md als Regeln. Vermerke im Bericht, welche Konfiguration angewendet wurde.
Ein Regelverstoß wird zu einem Fund, der die Regel zitiert (Regel: <id or first words>). Regel-Schweregrad wird abgebildet: high→P1, medium→P2, low→P2.
3. Kontextgraphen erstellen (der entscheidende Teil)
Für jeden geänderten Hunk identifiziere die Symbole, die er definiert, entfernt, umbenennt oder deren Signatur/Semantik ändert (Funktionen, Methoden, Klassen, Typen, exportierte Konstanten, Routen, DB-Spalten, Konfigurationsschlüssel, Umgebungsvariablen, Ereignisnamen).
Suche für jedes dieser Symbole im gesamten Repo, nicht nur in geänderten Dateien:
- Aufrufer / Referenzen –
Grepnach dem alten und neuen Namen. Ein entferntes/umbenanntes Symbol mit überlebenden Referenzen ist ein garantierter Fehler. - Geschwisterkind – Code, der die gleiche Art von Aufgabe erledigt (andere Endpunkte im Router, andere Handler desselben Interfaces, andere Migrationen). Neuer Code, der ein von jedem Geschwisterkind befolgtes Muster überspringt (Auth-Decorator, Audit-Log, Validierung, Transaktion, Lock,
await) ist ein Top-Greptile-Fund. - Aufgerufene – lies die Implementierung von allem, was der neue Code aufruft und dessen Vertrag relevant ist (wirft es eine Exception? Gibt es null zurück? Sperrt es bereits? Ist es asynchron?).
- Datenfluss – woher die Eingaben kommen (benutzergesteuert? URL-Parameter?) und wohin sie gehen (SQL/HogQL, Shell, Dateisystempfad, dynamische Codeausführung, HTML).
Führe eine kurze Liste: Symbol → Dateien, die davon abhängen → was die Änderung mit ihnen macht. Verwende sie für Funde; gib sie nicht im Bericht aus.
4. Jagd
Gehe den Diff mit dem Graphen in der Hand durch. Kategorien, die Greptile tatsächlich meldet, mit echten Beispielen:
- Logik – Schleife verlässt vorzeitig und hinterlässt partiellen Zustand; Flag/Bedingung invertiert; aliased value entgeht einer Prüfung; Warnungen erreichen den Benutzer nie.
- Refactoring – Umbenennung hinterlässt undefinierte Aufrufer; verschobener Code verliert einen Seiteneffekt.
- Sicherheit – Fehlende Authentifizierung/Autorisierung bei neuem Endpunkt; Injection über Benutzereingaben in Query/Shell/Pfad; Sandbox/Scope-Escape (Symlinks, Mounts,
~, Variablenexpansion); null/fehlendes Feld umgeht eine Sicherung. - Validierung – Leere/fehlerhafte Eingabe wird als gültig akzeptiert; gültige Eingabe wird abgelehnt; unverankerte Regex.
- Laufzeit / Syntax – Aufruf einer undefinierten Methode; fehlendes
await; falsche Argumentanzahl; Typkonflikt; Code, der nicht kompiliert. - Fehlerbehandlung – Verschluckte Ausnahmen; rohe Tracebacks/Geheimnisse an Clients durchgestochen; Ressource im Fehlerpfad auf falschem/undefiniertem Handle geschlossen.
- Nebenläufigkeit – Check-then-act und Read-modify-write-Race-Conditions; gemeinsam genutzter veränderlicher Zustand über Tasks/Threads hinweg; Startreihenfolge verliert Ereignisse.
- Datenverlust / Integrität – Nicht-atomare Schreibvorgänge; Doppelanwendung bei Wiederholung; stilles Abschneiden; gelöschte Daten erscheinen wieder.
- Performance – N+1-Abfragen, O(n²) auf häufigem Pfad, eine „Optimierung", die eine stille Nulloperation ist.
- Alignment / Leckage – Grundwahrheit oder Geheimnisse werden über einen Status-/Debug-Endpunkt oder Log offengelegt.
Überprüfe jeden Kandidaten, bevor du ihn behältst. Du musst angeben können: die genaue Zeile, die konkrete Eingabe/den Zustand, der sie auslöst, und das falsche Ergebnis. Wenn du den Fehler nicht konstruieren kannst, verwirf ihn. Lies den umgebenden Code erneut – die Hälfte der plausibel aussehenden Fehler wird drei Zeilen später behandelt.
5. Klassifizieren und filtern
Jeder Fund erhält:
- Schweregrad – P0 muss vor dem Merge behoben werden (Sicherheitslücke, Datenverlust, Absturz auf häufigem Pfad, Build-Bruch). P1 sollte behoben werden (falsches Verhalten, kaputter Randfall, Regelverstoß mit hohem Schweregrad). P2 in Erwägung ziehen (Wartbarkeit, kleinere Performance, Regel mit niedrigem Schweregrad).
- Typ –
logic(Fehler, Verhalten, Randfälle),syntax(wird nicht kompilieren/laufen, Sprachmissbrauch),style(Qualität, Benennung, Konventionen).
Filtere nach strictness:
- 1 – behalte P0, P1, P2.
- 2 (Standard) – behalte P0, P1; behalte P2 nur, wenn es gegen eine explizit konfigurierte Regel verstößt.
- 3 – behalte P0, plus diese P1s: Sicherheit, vom Benutzer erreichbare Abstürze/500er und Verstöße gegen konfigurierte Regeln mit
high-Schweregrad. Strictness 3 bedeutet „nur, was jemanden aufwecken würde oder was das Team explizit angefordert hat", und ein remote auslösbarer Absturz ist qualifiziert.
Dann entferne Typen, die nicht in commentTypes sind. Reine Formatierung, die ein Formatter beheben würde: niemals melden.
6. Konfidenzwert (0–5)
| Wert | Bedeutung |
|---|---|
| 5/5 | Produktionsbereit – merge |
| 4/5 | Kleinere Feinarbeit – merge nach kleinen Korrekturen (nur P2s) |
| 3/5 | Implementierungsprobleme – Feedback zuerst adressieren (irgendein P1) |
| 2/5 | Signifikante Fehler – Überarbeitung nötig (mehrere P1s oder ein P0, der einfach zu beheben ist) |
| 0-1/5 | Kritische Probleme – neuer Ansatz nötig (P0 Sicherheit/Datenverlust oder Design ist falsch) |
Werte sind kontextabhängig: Der gleiche Fehler in Zahlungen/Auth/Migrationen wird niedriger bewertet als in einem internen Skript. Gib einen Satz Begründung.
7. Diagramm
Wähle aus, was sich geändert hat; überspringe bei trivialen Diffs (Dokumentation, Konfigurationsbumps, <~20 Zeilen lokaler Logik):
- sequenceDiagram – Multi-Komponenten-Interaktionen, API/Request-Flows, asynchrone/nebenläufige Reihenfolge (zeige die Race-Condition, falls vorhanden)
- erDiagram – Schema-/Datenmodelländerungen
- classDiagram – Klassen-/Interface-Hierarchieänderungen
- flowchart – Kontrollfluss-/Geschäftslogikänderungen
Diagrammiere die Änderung, nicht das gesamte System. Halte es auf unter ~15 Knoten. Markiere den fehlerhaften Schritt mit einem Note / Label.
8. Ausgabe
Verwende exakt diese Struktur (Abschnitte können nur weggelassen werden, wo angegeben):
## Invertebrate Review – <PR-Titel oder Branch>
### Zusammenfassung
<2–4 Sätze, Klartext: was die Änderung macht, wen/was sie betrifft, warum. Dann 1 Satz zum Hauptrisiko.>
### Konfidenzwert: N/5
<ein Satz warum>
### Funde
| # | Schwere | Typ | Ort | Problem |
|---|---|---|---|---|
| 1 | P0 | logic | `path/file.ts:42` | <kurzer Titel> |
(Bei keinen: „Keine Probleme gefunden.")
### Diagramm
```mermaid
...
```
(Abschnitt bei trivialen Änderungen weglassen)
### Inline-Kommentare
#### 1. [P0 · logic] <kurzer Titel>
`path/file.ts:42`
<Was falsch ist, das konkrete Fehlerszenario und – falls dateiübergreifend – welche anderen Dateien brechen und warum. 2–5 Sätze.>
```diff
- alte Zeile
+ korrigierte Zeile
```
#### 2. ...
---
<sub>Überprüft <N> Dateien · Konfiguration: <.invertebrate- oder .greptile-Pfad | CLAUDE.md | Standard> · strictness <n> · <Commit-SHA, falls bekannt></sub>
Änderungsvorschläge müssen echt, minimal und auf den tatsächlichen Code anwendbar sein. Wenn die Korrektur über Dateien verteilt ist, zeige den Hunk jeder Datei mit ihrem Pfad als Überschrift. Falls kein sicherer Ein-Hunk-Fix existiert, beschreibe ihn, anstatt einen zu erfinden.
Nach dem Bericht biete an: „Sage fix all, fix P0 oder fix #2 und ich werde sie anwenden." Wende Korrekturen nicht unaufgefordert an.
9. Auf GitHub veröffentlichen (nur auf Anfrage: --post, „post it", „kommentiere den PR")
Das Veröffentlichen ist nach außen gerichtet – führe es nur auf ausdrückliche Anfrage für diesen PR durch.
- Hole
owner/repo(gh repo view --json nameWithOwner -q .nameWithOwner) und den Head-SHA (gh pr view <n> --json headRefOid -q .headRefOid). - Inline-Kommentare können nur auf Zeilen abzielen, die im PR-Diff vorhanden sind (rechte Seite, neue Zeilennummern). Funde auf Zeilen außerhalb des Diffs werden nur in den Zusammenfassungstext aufgenommen.
- Schreibe das Review-JSON in eine temporäre Datei und veröffentliche es in einem Aufruf:
{
"commit_id": "<head sha>",
"event": "COMMENT",
"body": "<der vollständige Markdown-Bericht aus §8 minus dem Abschnitt Inline-Kommentare>",
"comments": [
{"path": "src/file.ts", "line": 42, "side": "RIGHT",
"body": "**P0 · logic** — <titel>\n\n<erklärung>\n\n```suggestion\n<ersatz für genau zeile 42>\n```"}
]
}
gh api repos/<owner>/<repo>/pulls/<n>/reviews --method POST --input review.json
Verwende GitHub ```suggestion-Blöcke nur, wenn der Ersatz genau die kommentierten Zeilen abdeckt (verwende start_line + line für mehrere Zeilen). Ansonsten verwende einen ```diff-Block. Verwende niemals REQUEST_CHANGES/APPROVE, es sei denn, der Benutzer fragt danach. Melde die Review-URL aus der Antwort.