Dieselbe PR, zwei verschiedene Reviews

Ein Entwickler aus meinem Netzwerk hat Claude Code als CI-Code-Reviewer eingerichtet. “Lass Claude einfach die PR prüfen”, sagte er mir. “Damit erwischt es Dinge, die ich übersehen würde.” Ich bat ihn, dieselbe PR zweimal durch Claude laufen zu lassen.

Das erste Review sagte, das Error Handling sehe umfassend aus. Das zweite Review markierte es als unzureichend und schlug drei Änderungen vor. Er starrte fünf Minuten lang auf den Bildschirm und fragte sich, welcher Claude jetzt recht hatte.

Beide hatten nicht recht. Beide hatten nicht unrecht. Das LLM machte probabilistische Vermutungen, statt deterministische Regeln anzuwenden. Und genau das ist das Grundproblem, wenn du KI zur Verifikation nutzt: Verifikation braucht zwei Eigenschaften, die LLMs nicht haben. Determinismus - dieselbe Eingabe erzeugt immer dieselbe Ausgabe. Vollständigkeit - alle Fehlermodi werden jedes Mal erwischt.

Das Determinismus-Problem

Lass denselben Code zweimal durch Claude Code laufen, und du bekommst möglicherweise zwei unterschiedliche Reviews. Temperatur, Context Window, Prompt-Formulierung - alles führt Varianz ein. Für Brainstorming ist Varianz ein Feature. Für Verifikation ist sie ein Bug. Du kannst keine verlässliche Software auf probabilistischen Quality Gates aufbauen.

Deterministische Checks haben dieses Problem nicht. tsc --noEmit produziert immer dieselben Fehler. ESLint mit derselben Config markiert immer dieselben Verstöße. Diese Tools wenden Regeln statt Wahrscheinlichkeiten an. Sie sind langweilig. Genau deshalb funktionieren sie.

Der O(1)-Guard-Stack

So sieht unser Pre-Commit-Stack aus. Jeder Check ist deterministisch. Jeder Check läuft in Millisekunden. Keinem davon ist wichtig, ob der Code von einem Menschen oder von Claude Code geschrieben wurde:

# Pre-commit (< 1 second total)
TypeScript strict mode      # tsc --noEmit
ESLint boundary rules       # module isolation
Import restrictions         # dependency direction
dependency-cruiser          # graph analysis
Unit tests                  # contract verification

# CI (< 30 seconds)
Full test suite
Bundle size checks
Fresh clone launch test

Die zentrale Kennzahl ist O(1) relativ zur Codebase-Größe. Type Checking ist inkrementell. Linting ist pro Datei. dependency-cruiser analysiert den Import-Graphen linear. Nichts davon wird langsamer, wenn deine vibe-codierte App wächst. Claude-Code-Reviews werden langsamer und ungenauer, je stärker deine Codebase das Context Window sprengt.

Was deterministische Checks tatsächlich erwischen

Letzte Woche hat dependency-cruiser eine PR erwischt, in der eine Screen-Komponente direkt aus einer Service-Implementierung importierte statt aus dem Barrel. Die PR kompilierte problemlos. Tests liefen durch. Cursor hatte den Import automatisch generiert. Aber er verletzte unsere Architekturregel: Nur der Composition Root importiert Implementierungen.

Ein LLM-Review hätte das vielleicht gefunden. Oder auch nicht, weil die PR groß war und der Import mitten in der Datei versteckt lag. dependency-cruiser verpasst es nie, weil es den Code nicht liest - es analysiert einen Graphen:

// .dependency-cruiser.cjs
// 8 lines. 100ms. Catches this every time, forever.
{
  name: 'no-deep-service-imports',
  comment: 'Only service barrels are public.',
  severity: 'error',
  from: { pathNot: '^src/services/' },
  to: {
    path: '^src/services/[^/]+/',
    pathNot: '^src/services/[^/]+/index\.ts$',
  }
}

Acht Zeilen. Unter hundert Millisekunden. Jede PR. Für immer. Ein Claude-Code-Review kostet Tokens, braucht Sekunden und übersieht es vielleicht. Die Rechnung ist eindeutig.

Wo KI tatsächlich hingehört

Ich bin nicht gegen KI. Ich nutze Cursor und Claude Code jeden Tag - zum Skizzieren von Code, zum Erkunden von Ansätzen, zum Schreiben von Tests, zum Debuggen. Aber ich setze sie nicht in Verifikationsrollen ein. Verifikation muss deterministisch sein. Sie muss langweilig sein. Sie muss jedes einzelne Mal identisch ablaufen.

Guardrails sollten unsichtbar und unvermeidbar sein. Sie sollten Probleme finden, ohne dass jemand daran denken muss, sie auszuführen. Genau das liefern deterministische Checks: ein Sicherheitsnetz, das nie schläft, nie müde wird und nie den Kontext verliert, wenn deine Codebase wächst.

Das Autotomy Expo Starter Pack bringt TypeScript Strict Mode, ESLint Boundary Rules, dependency-cruiser-Config und Pre-Commit-Hooks bereits vorkonfiguriert mit. Du bekommst Cursor-Geschwindigkeit für die Generierung. Du bekommst Maschinenpräzision für die Verifikation. So machst du Vibe Coding, ohne die Produktion zu zerlegen.