Vibe Coding → Produktionsreife

Vibe Coding ist brillant für Geschwindigkeit: Sie beschreiben die Intention, der Agent liefert Code, und nach zwei Stunden haben Sie ein klickbares MVP. Produktionsreife verlangt jedoch Schichten, Tests, Security-Reviews und vorhersagbare Deployments. Agenticode in Köln spezialisiert sich darauf, genau diese Lücke zu schließen – ohne die Kreativität des Vibe-Ansatzes zu ersticken.

Die Produktions-Lücke nach dem Prototyp

Typische Vibe-Codebases leiden unter flachen Strukturen: alles in wenigen großen Dateien, keine klaren Domain-Grenzen, Tests als Nachgedanke. Der Agent hat funktionierenden Code produziert – aber keinen wartbaren. Der erste Production-Bug kommt nicht vom Feature, sondern von fehlender Fehlerbehandlung, SQL-Injection-Risiken oder Race Conditions.

Produktionsreife bedeutet nicht „kein Agent mehr“. Es bedeutet: Der Agent arbeitet innerhalb einer Architektur-Hülle. Jeder Run muss Static Analysis, Unit-Tests und Diff-Limits passieren. Agenticode etabliert diese Hülle schrittweise, oft beginnend mit einem „Production Readiness Gate“ in der CI.

Holistisch betrachten wir vier Säulen: Struktur (Module, Namespaces, Dependency Injection), Verifikation (Tests, PHPStan, Security-Scans), Betrieb (Logging, Health Checks, Feature Flags) und Governance (Code Review, Policy-Updates). Fehlt eine Säule, kippt das System unter Last.

Production-Readiness-Checker: harte Kriterien vor dem ersten Deploy.
<?php

declare(strict_types=1);

namespace App\ProductionGate;

final class ProductionReadinessChecker
{
    public function execute(string $projectRoot): array
    {
        $violations = [];

        if (!$this->hasPhpStanConfig($projectRoot)) {
            $violations[] = 'phpstan.neon fehlt';
        }
        if ($this->countUntestedServices($projectRoot) > 0) {
            $violations[] = 'Services ohne zugehörige Tests gefunden';
        }
        if ($this->hasRawSqlInControllers($projectRoot)) {
            $violations[] = 'SQL in Controller-Schicht – Domain-Layer erforderlich';
        }
        if ($this->maxFileLineCount($projectRoot) > 400) {
            $violations[] = 'Dateien > 400 Zeilen – Refactoring-Gate';
        }

        return $violations;
    }

    private function hasPhpStanConfig(string $root): bool
    {
        return is_file($root . '/phpstan.neon') || is_file($root . '/phpstan.neon.dist');
    }

  // ... weitere Checks
}

Architektur-Gates für Agent-Output

Ohne Gates schreibt ein Agent dort hin, wo der Prompt am wenigsten Widerstand bietet – oft direkt in Controller oder Twig-Templates. Wir definieren Layer-Regeln: Domain-Logik nur in Services, Persistence nur in Repositories, keine Business-Logik in Templates. Diese Regeln werden als Cursor Rules und PHPStan-Custom-Rules codiert.

Ein weiteres Gate ist die Diff-Größe. Große Diffs sind schwer reviewbar und verstecken Fehler. Agenticode setzt typischerweise ein Limit von 300–500 Zeilen pro Agent-Run. Überschreitungen triggern eine Aufteilung in Sub-Tasks – ein Pattern, das Multi-Agent-Orchestrierung vorbereitet.

Security-Gates sind nicht verhandelbar: Keine Secrets im Code, prepared Statements für SQL, Input-Validierung an Systemgrenzen. Der Agent darf Features bauen – aber nicht die Sicherheitsarchitektur umgehen.

CI-Gate: Diff-Limit plus Static Analysis und Tests nach jedem Agent-Run.
#!/usr/bin/env bash
set -euo pipefail

# Agent-Run Post-Check – Teil jeder Agenticode CI-Pipeline
MAX_DIFF_LINES=400
DIFF_LINES=$(git diff --cached --numstat | awk '{s+=$1+$2} END {print s+0}')

if [ "$DIFF_LINES" -gt "$MAX_DIFF_LINES" ]; then
  echo "FAIL: Diff hat $DIFF_LINES Zeilen (Limit: $MAX_DIFF_LINES)"
  echo "Bitte Run in kleinere Sub-Tasks splitten."
  exit 1
fi

composer phpstan -- --error-format=raw
vendor/bin/phpunit --stop-on-failure
composer audit

echo "OK: Agent-Output produktionsreif für Review."

Der Weg von Agenticode: Strangler statt Big Bang

Wir reißen Vibe-Codebases nicht ab. Der Strangler-Fig-Ansatz extrahiert Schritt für Schritt Domain-Module aus dem Monolithen, während neue Features bereits in der Zielarchitektur landen. Parallel bauen wir die Testpyramide von unten: Unit-Tests für extrahierte Services, dann Integrationstests, zuletzt wenige E2E-Tests.

Jeder Strangler-Schritt ist ein abgeschlossener Agent-Run mit klarem Scope: „BillingService extrahieren“, nicht „alles refactoren“. So bleibt das System deploybar und das Risiko kontrollierbar.

Am Ende steht keine perfekte Codebase aus dem Lehrbuch, sondern eine, die unter echten Nutzerlast stabil läuft, von Ihrem Team gepflegt werden kann und weiterhin agentisch erweiterbar ist – weil die Policies und Gates etabliert sind.

Strangler-Plan als versioniertes YAML – jeder Schritt mit eigenem Scope.
strangler_plan:
  module: Billing
  steps:
    - name: extract_domain_models
      allowed_paths: ["src/Models/Billing/**"]
      verification: ["phpunit --filter=Billing"]
    - name: extract_service_layer
      allowed_paths: ["src/Services/Billing/**"]
      verification: ["phpstan", "phpunit --testsuite=Billing"]
    - name: wire_controllers
      allowed_paths: ["src/Controllers/Billing*", "config/routes/billing.php"]
      verification: ["phpunit", "smoke_test.sh"]
  rollback: "git revert HEAD --no-edit"