// Fallstudie
Pokkum: 100 % vibe-coded, produktiv im Einsatz
Wie entsteht mit KI-Agents in sechs Wochen ein Supply-Chain-Tool, dem man vertrauen kann? Die Antwort liegt nicht im Prompt, sondern in den Leitplanken.
Pokkum baut aus einer SvelteKit-App ein OCI-Container-Image, ohne Dockerfile, ohne Docker-Daemon und bit-für-bit reproduzierbar. Man kann es sich als „ko für SvelteKit“ vorstellen. Der Code ist auf GitHub öffentlich.
Der Anlass war ein konkretes Sicherheitsproblem: Das Distroless-Node-Image meines Hauptprojekts hatte eine CVE ohne verfügbaren Fix. Statt sie per Ignore-Regel von Version zu Version mitzuschleppen, wollte ich ein Image, das von Grund auf minimal und nachprüfbar ist.
Der eigentliche Zweck war ein anderer. Vibe-Coding wird am Markt zunehmend verlangt. Ich hatte viel KI-gestützt entwickelt, aber nie rein per Vibe-Coding. Pokkum ist deshalb ein bewusster Selbstversuch: Ich wollte herausfinden, was funktioniert, was nicht und was es braucht, damit ich das Ergebnis mit gutem Gewissen ausliefern kann.
Was Pokkum kann
Kurz zum Produkt, damit die Methode einen Massstab hat. Pokkum ist kein Spielzeugprojekt, sondern ein Supply-Chain-Werkzeug mit rund 60’000 Zeilen Go und 17 CLI-Befehlen:
- Builds ohne Daemon für amd64 und arm64, direkt aus Go in die Registry.
- Nachprüfbare Reproduzierbarkeit: Alle Zeitstempel im Image leiten sich aus
SOURCE_DATE_EPOCHab.pokkum verifybaut neu und vergleicht auf drei Ebenen: Manifest, Layer und einzelne Dateien. - Supply-Chain-Security: SBOM (SPDX), SLSA-v1.0-Provenance, Cosign/DSSE-Signaturen und keyless Sigstore-Prüfung der Base-Images.
- Drei Build-Strategien: layered mit eigenem PID-1-Supervisor in Go, exe als Single Binary via Bun und static mit einem kleinen Go-Webserver, ganz ohne Node oder Bun.
- Deployment inklusive: Kubernetes mit gehärteten Manifesten und Rollback, dazu direkte Deployments auf Dokploy und SwiftWave.
- Hermetische Builds ohne Netzwerkzugriff für air-gapped Umgebungen.
Im Einsatz: Ich deploye inzwischen die meisten meiner Apps und Sites mit Pokkum. Deshalb kann es direkt auf Dokploy und SwiftWave ausliefern, die beiden PaaS, die ich selbst betreibe.
Am deutlichsten zeigt sich der Unterschied bei statischen Sites. Pokkum packt nur die Dateien und einen kleinen Go-Webserver auf ein Base-Image ohne libc. Das Ergebnis ist 8,1 MB gross, gegenüber 73 MB bei der besten von Hand optimierten Variante (Caddy auf Distroless). Das sind 89 % weniger, bei null kritischen CVEs.
Bei Apps mit serverseitiger Logik braucht es eine JavaScript-Runtime, und die Grösse ist nicht mehr die spannende Zahl: Gegenüber einem sauber optimierten Dockerfile spart Pokkum nur rund 17 %. Entscheidend ist die Angriffsfläche: null kritische CVEs, keine Shell im Image und keine Build-Konfiguration, die jemand pflegen muss.
Die zentrale Erkenntnis: Leitplanken machen schnell
Die naheliegende Annahme lautet: Der schnellste Agent kommt am schnellsten ans Ziel. Bei Pokkum war es umgekehrt.
Angefangen habe ich mit Google Antigravity und Gemini Flash (3.5, später 3.6 und 3.7). Das fühlte sich schnell an: Features kamen in hohem Takt, die Oberfläche ist angenehm. Dann liess ich Claude Code die Commits reviewen, und es fand weit mehr Probleme als erwartet. Stubs waren als „implementiert“ gemeldet, Fehler blieben unerwähnt, und die Go-Version wurde wiederholt heruntergestuft.
Ab diesem Punkt habe ich umgestellt. Claude Code wurde der primäre Agent, obwohl er pro Aufgabe langsamer ist. Dafür hält er sich an Regeln, und genau das macht Leitplanken erst wirksam. 328 der 399 Commits sind mit Claude Opus oder Sonnet entstanden.
// adr
Primärer Coding-Agent: Zuverlässigkeit vor Rohtempo
finalcontext
Nach den ersten Wochen mit Gemini Flash in Antigravity zeigten Reviews, dass viele als fertig gemeldete Features Stubs oder Fehler enthielten. Die Nacharbeit frass den Geschwindigkeitsvorteil wieder auf.
decision
Claude Code als primärer Agent, eingebettet in Systemprompts, Test-Suite und Clean-Context-Sweep.
gains
- Regeln aus dem Systemprompt werden zuverlässig befolgt, auch unbequeme wie „Stubs ausdrücklich melden“.
- Deutlich stärker im Code-Review: findet Fehler, die andere Agents übersehen oder verschweigen.
- Weniger Nacharbeit und dadurch unter dem Strich das höhere Tempo.
costs
- Pro Aufgabe langsamer als Antigravity.
- Die Oberfläche ist weniger komfortabel.
consequences
- Der Engpass verschob sich vom Schreiben zum Prüfen. Deshalb floss die meiste Energie in automatisierte Verifikation statt in bessere Prompts.
alternatives
- Google Antigravity mit Gemini Flash — Schnell, aber unzuverlässig: meldete Stubs als fertig und stufte eigenmächtig die Go-Version herunter.
- DeepSeek Harness mit DeepSeek V4 Flash — Das Modell hatte Probleme mit Tool-Calls und verfing sich in Schleifen, der Harness war noch nicht ausgereift. Blieb mit eigenem Systemprompt (DSH.md) als Ergänzung im Mix.
Die vier Leitplanken
// Spielregeln fest verdrahtet
Systemprompts statt Prompts
Meine Prompts sind kurz. Die eigentliche Arbeit steckt in Systemprompts, die auf den jeweiligen Agent zugeschnitten sind.
Meine eigentlichen Prompts sind kurz und unspektakulär. Die Arbeit steckt in den Systemprompts, und zwar einem pro Agent: CLAUDE.md für Claude Code, AGENTS.md für andere Agents und DSH.md für DeepSeek Harness. Dazu kommt Serena MCP als Gedächtnis des Repos. Elf Memory-Dateien halten Architektur, Konventionen, Tech-Stack und offene Entscheidungen fest, damit kein Agent das Projekt jedes Mal neu einlesen muss.
Die wichtigsten Regeln:
- Hexagonale Architektur:
internal/portsdarf keine anderen Projektpakete importieren. Ein Test prüft das bei jedem Lauf per AST-Analyse (internal/architecture_test.go). Ein Agent kann die Grenze also nicht unbemerkt verletzen, und ich übrigens auch nicht. - Keine Systemuhr im Build: Alles, was ins Image gelangt, leitet seine Zeitstempel aus
SourceDateEpochab.time.Now()ist dafür tabu. - Build-Sandbox: Injektionen passieren nur im virtuellen
.pokkum/-Verzeichnis, nie im Quellcode des Users. - Zero Fake Implementations: Stubs und Platzhalter müssen ausdrücklich gemeldet werden und gelten nie als fertig.
- Verifikation vor Abschluss: Keine Aufgabe ist erledigt, bevor die fünfstufige Suite grün ist (
make verify). - Kein Silent Patching: Gefundene Fehler werden offen benannt, nicht stillschweigend korrigiert.
Der Prompt ist kurz, die Spielregeln sind fest verdrahtet. So wird aus einem generischen Modell ein Entwickler, der die Architektur des Projekts kennt und respektiert.
// Mehr Testcode als Produktivcode
Die Test-Suite als Ersatz für Vollverständnis
Bei 60’000 Zeilen Code kann ich nicht jede Zeile selbst beurteilen. Die Tests übernehmen diese Rolle. Rückblickend würde ich noch konsequenter vorgehen: Test-Driven Development von Anfang an.
Bei rund 60’000 Zeilen Produktivcode kann ich nicht jede Zeile selbst beurteilen, zumal ich Pokkum in meiner Freizeit entwickle. Die Test-Suite ist deshalb mein objektiver Ersatz für das fehlende Vollverständnis.
Hier sind Agents vorhersehbar stark, besonders wenn man sie ausdrücklich nach Randfällen fragt. Noch besser wurden die Tests, als ich die Reihenfolge umdrehte: Bei neuen Features liess ich zuerst Dokumentation und Beschreibung schreiben, bei schwierigen ein Konzept, und erst danach den Code. So hatten die Tests eine Spezifikation, gegen die sie prüfen konnten.
Die CI führt sechs Workflows aus, darunter kontinuierliches Fuzzing, einen OSV-Scanner als Stolperdraht für neue CVEs und einen Wächter über die Sigstore-Vertrauensbasis (TUF).
Was ich beim nächsten Mal anders machen würde: konsequent auf Test-Driven Development setzen. Bei Pokkum entstanden viele Tests nach dem Code. Ein Test, der vor dem Code existiert, ist die schärfste Waffe gegen Stubs: Er definiert, was „fertig“ bedeutet, bevor der Agent es behaupten kann, und lässt sich nicht nachträglich an eine halbe Implementierung anpassen.
// Frische Augen auf Knopfdruck
Der Clean-Context-Sweep
Ein Sub-Agent ohne Gesprächsverlauf prüft jedes grössere Feature. Er findet, was der Haupt-Agent übersieht.
Ein Agent, der ein Feature gerade gebaut hat, ist der schlechteste Prüfer dafür. Er teilt seine eigenen Annahmen und übersieht dieselben Fehler ein zweites Mal. Deshalb startet nach jedem nicht-trivialen Feature ein Sub-Agent mit leerem Kontext. Er bekommt nur die Liste der geänderten Dateien und eine knappe Spezifikation, keinen Gesprächsverlauf und keine Debug-Spuren.
Der Prüfer lässt die volle Suite laufen, schreibt 2 bis 3 adversariale Tests, also gezielte Versuche, den Code mit Randfällen zu brechen, und sucht nach Logikfehlern, unerwünschten Seiteneffekten, Race Conditions und Ressourcenlecks. Jeder Befund wird gegen den echten git diff abgeglichen. Korrigiert wird offen, nie still.
// Das Repo lernt, nicht der Agent
Lessons.md: Fehler verbessern das System
121 Post-Mortems mit Ursache und neuer Regel. Agents vergessen zwischen Sitzungen alles, das Repo nicht.
Jeder Fehler, den die Verifikation findet, landet in Lessons.md: Kategorie, Ursache, Fundort, Fix und eine Regel, die ihn künftig verhindert. Inzwischen sind es 121 Einträge. Agents vergessen zwischen zwei Sitzungen alles, das Repo nicht.
Zwei Beispiele zeigen, wie sich dadurch die Leitplanken selbst verbessert haben:
- Die Suite hatte eine Lücke. Ursprünglich war sie vierstufig. Ein Eintrag hielt fest, dass
gofmt,go vetundgo testFehler übersehen, diegolangci-lintfindet. Seither hat die Suite fünf Stufen. - Eine Regel am falschen Ort ist keine Regel. Nach einem Vorfall am 17. August stand eine wichtige Prüfregel nur im Serena-Gedächtnis. Am 1. September lief ein Agent, der das Protokoll korrekt befolgte, in exakt denselben Fehler. Die Regel steht seither dort, wo sie gelesen wird: direkt bei der Beschreibung der Verifikations-Suite.
Was schiefging und wo meine Grenze liegt
Die grösste Stolperfalle war nicht fehlende Intelligenz, sondern fehlende Ehrlichkeit. Mit Antigravity und Gemini Flash habe ich erlebt:
- Stubs, die nie durch echte Logik ersetzt wurden.
- Falsche Erfolgsmeldungen: Ein Feature galt als „implementiert“, obwohl es nur angerissen war.
- Stille Fehler, die der Agent nicht meldete, weil er sie nicht bemerkte.
- Eigenmächtige Änderungen, etwa eine heruntergestufte Go-Version, um die niemand gebeten hatte.
Mit DeepSeek V4 Flash im DeepSeek Harness waren es andere Probleme: unzuverlässige Tool-Calls und Schleifen, aus denen der Agent nicht mehr herausfand.
Zur Fairness: Mit Claude Code habe ich falsche Erfolgsmeldungen nicht erlebt. Ich bin allerdings erst gewechselt, nachdem ich die Probleme bemerkt und die Leitplanken eingeführt hatte. Ob Claude ohne sie dieselben Fehler gemacht hätte, kann ich deshalb nicht sagen. Die Leitplanken bleiben so oder so: Sie fangen solche Fehler ab, egal von welchem Modell sie kommen.
Nicht alle Fehler kamen von den Agents. Meine eigenen:
- Zu viele Flags. Pokkum hat weit über 100 Flags. Um die Methode zu prüfen, musste ich Funktionen tatsächlich bauen, und fast jede brachte einen Schalter mit. Heute schlage ich selbst im README nach, sobald ich etwas Ungewöhnliches bauen will. Eine abgespeckte Version habe ich erwogen, aber verworfen, solange kaum jemand ausser mir Pokkum nutzt. Für ein Produkt mit echten Nutzern wäre das die erste Baustelle.
- Die Release-Pipeline. Bis die Veröffentlichung auf npm funktionierte, war ich bei etwa v0.5. Auch mit KI-Hilfe brauchte es viele Anläufe, und am Ende war ich so erschöpft, dass ich den Weg dorthin kaum nachvollziehen könnte. Die Lehre: Eine neue Release-Pipeline probiere ich künftig zuerst an einem Projekt ohne Risiko aus, statt darauf zu setzen, dass sie beim ersten Versuch klappt.
Bei der Frage, welche Bereiche ich den Agents überlasse, habe ich bewusst nichts ausgeklammert, auch nicht heikle Bereiche wie Signaturen, Reproduzierbarkeit oder den PID-1-Supervisor. Die Grenze liegt für mich nicht bei der Domäne, sondern bei der Frage: Kann ich es verifizieren?
- Vertrauensanker
- Adversariale Tests Clean-Context-Reviews Abgleich mit git diff Root Cause in Lessons.md
Vertraue ich dem Agent? Nur bedingt. Wenn ich unsicher war, habe ich den Code nicht selbst neu geschrieben, sondern recherchiert, bis ich die Sache einordnen konnte. Der Reflex, lieber alles selbst zu machen, kam seltener als erwartet. Das Vertrauensproblem liess sich fast immer mit Verifikation und Recherche lösen.
Offene Frage: Geht das auch mit kleinen Modellen?
Claude ist beim Programmieren hervorragend, vielleicht das Beste, was es derzeit gibt. Das wirft eine unbequeme Frage auf: Hat Pokkum funktioniert, weil die Methode trägt, oder weil das Modell so stark ist?
Das will ich als Nächstes herausfinden: Lässt sich ein Projekt auch mit kleineren Modellen zu 100 % vibe-coden? Relevant ist das nicht nur akademisch. Kleine Modelle lassen sich lokal betreiben, und das ist überall dort gefragt, wo Code oder Daten das Haus nicht verlassen dürfen.
Meine Hypothese: Ja, wenn das Umfeld mehr Verantwortung übernimmt. Drei Hebel sehe ich:
- Der Harness statt des Agents: Es gibt Harnesses für kleinere Modelle, die Aufgaben vom Modell in den Harness verlagern und so das fehleranfällige Tool-Calling robuster machen.
- Code-Intelligenz statt Kontext: Kleinere Kontextfenster verlangen Werkzeuge wie Serena, die gezielt die relevanten Symbole liefern, statt ganze Dateien einzulesen.
- Klare Grenzen: Die hexagonale Architektur schneidet das Projekt in kleine Einheiten mit klaren Schnittstellen. Eine Aufgabe passt so in einen kleinen Kontext.
Test-Suite und Clean-Context-Sweep blieben unverändert. Sie prüfen das Ergebnis, egal welches Modell es geschrieben hat. Was ein starkes Modell schneller macht, könnte ein kleines Modell überhaupt erst befähigen.
Fazit
Hat sich der Selbstversuch gelohnt? Ja. Pokkum ist als v1.2.1 veröffentlicht, und ich deploye damit inzwischen die meisten meiner Apps und Sites. Das Problem, mit dem alles begann, ist gelöst. Wertvoller ist aber, was ich über die Methode gelernt habe:
Was ich davon in ein Team mitbringe:
- Einen erprobten Workflow für KI-gestützte Entwicklung: Systemprompts, Verifikationsprotokoll und Fehlerkultur, die ein Team übernehmen und anpassen kann.
- Das Urteilsvermögen, welcher Agent für welche Aufgabe taugt, und die Ehrlichkeit, Grenzen offen zu benennen.
- Praxiswissen in Supply-Chain-Security: reproduzierbare Builds, SBOM, SLSA, Signaturen und gehärtete Container.