Jeder Migrationsfehler, den wir je in anderer Software gesehen haben, kommt aus derselben Ecke: “Erst die Daten aufräumen” wird als Problem des Kunden behandelt statt als Problem des Produkts. Das wollten wir nicht bauen. Also sind wir früh selbst auf einen echten Fall gestoßen, und der hat uns etwas Unerwartetes gelehrt: Manchmal lautet die richtige Antwort auf “sollte das die KI übernehmen” schlicht nein.
Die Migration, die uns den Unterschied gelehrt hat
Wir hatten einen echten Export aus einem alten CRM zu übernehmen: 349 Firmen, 491 Notizen, größtenteils Anruf-Historie auf Slowenisch geschrieben, 393 Kontakte. Der naheliegende Schritt wäre gewesen, das durch Neo laufen zu lassen, unseren KI-gestützten Import, denselben, der eine unsaubere Tabelle liest und daraus saubere Datensätze vorschlägt.
Wir haben uns dagegen entschieden. Die Quelldaten waren bereits strukturiert, bereits bereinigt, bereits korrekt. Ein KI-Durchlauf hätte nichts hinzugefügt außer Risiko: ein Modell, das echte slowenische Anrufnotizen umformuliert oder zusammenfasst und dabei still Präzision in Texten verliert, die exakt so bleiben mussten, wie sie geschrieben waren. Also haben wir einen zweiten, separaten, bewusst KI-freien Weg gebaut: exaktes, deterministisches Kopieren, per Legacy-Datensatz-ID zugeordnet, mit Erhalt der Original-Zeitstempel, ohne dass irgendwo ein Sprachmodell beteiligt ist.
Der Bau dieses Wegs hat echte Lücken zutage gefördert, die wir sonst nicht gefunden hätten: ein Formularfeld, das das Backend seit wer weiß wie langer Zeit still verworfen hatte, weil die dahinterliegende Datenbankspalte nie existiert hatte, Kontakte, die mangels eines richtigen Platzes in Freitextnotizen gequetscht wurden. Beides für immer behoben, nicht nur für diese eine Migration.
Das ist heute die tatsächliche Form der Migration Engine: Neo für das ehrliche Durcheinander, werft uns eure schlimmste Tabelle vor die Füße und wir sagen euch klar, was wir daraus machen konnten und was nicht, und ein stiller, exakter Kopierweg für Daten, die bereits vertrauenswürdig sind und nur unversehrt ankommen müssen. Zwei verschiedene Probleme. Wir haben aufgehört, so zu tun, als wären sie eins.
Erst mal zu etwas kommen, das überhaupt testenswert ist
Nichts von dem Testing unten zählt, wenn darunter nichts Echtes liegt. Ehrlich gesagt fing ein Teil davon, wie wir hierhin kamen, aus Zufall an. Bildschirmaufnahmen wurden ständig aufgeschoben, hauptsächlich schlichte Widerwilligkeit, sich hinzusetzen und etwas ordentlich aufzunehmen, also war der eigentliche Workaround, einfach zuzusehen, wie die KI live durch die App klickt, und mitzuschreiben, was passiert. Das entpuppte sich als eine der besten Debugging-Methoden, auf die wir im ganzen Projekt gestoßen sind, kein cleverer Plan, sondern ein Nebenprodukt davon, etwas anderes nicht tun zu wollen. Ein paar echte Features gibt es heute, weil ein Bug genau so aufgefallen ist.
Der größere Aufbau folgte einer ähnlichen Form, weniger nach großem Design als nach Notwendigkeit: ein echtes Stück nach dem anderen, jedes von Anfang bis Ende getestet, bevor das nächste begann, weil ein Projekt dieser Größe auf keine andere Art vernünftig bleibt. Was uns wirklich überrascht hat: Die Basis-Testsuite hat am Ende Dinge vorhergesagt, die niemand von ihr verlangt hatte. Fügt man Monate später ein neues Feature hinzu, hat Velvet manchmal aufgedeckt, dass ein benachbartes Teil die ganze Zeit still halbfertig herumlag und darauf wartete, bemerkt zu werden. Nicht weil irgendjemand Beteiligter besonders scharfsinnig ist. Ein Test, der den Button tatsächlich klickt und das echte Ergebnis prüft, findet auf seine Art einfach Dinge, die jemand beim Code-Überfliegen nicht finden würde.
Velvet
Irgendwann unterwegs bekam unsere eigene End-to-End-Testsuite einen Namen, statt einfach nur “die Tests” zu sein. Wir nennen sie Velvet. Rund fünftausend Zeilen Playwright, über zwölf benannte Suiten, Smoke, Regression, der Vault, das AI Village, Action-Bus-Abläufe, harte Grenzfälle, Stress, unter anderem, ausgeführt gegen fünf separate synthetische, bestückte Testfirmen. Sie steuert die echte, laufende Anwendung, Backend und Frontend beide live, keinen gemockten Ersatz für eines von beiden.
Innerhalb der benannten Regressionssuiten sind KI-Aufrufe auf deterministische Antworten gemockt, absichtlich, nicht als Abkürzung. Bei echtem Volumen stoßen echte KI-Aufrufe an Browser-Verbindungslimits und erzeugen Fehler, die nichts damit zu tun haben, ob das Produkt tatsächlich funktioniert. Das Mocking dort isoliert eine ehrliche Frage, funktioniert die Verkabelung, von einer anderen, ist die tatsächliche Antwort der KI gut, die separat getestet wird, echt.
Die Disziplin unter jeder Schicht
Fünf Regeln gelten überall, wo in diesem Projekt getestet wird, nicht nur in Velvet:
Eine Vorhersage schriftlich festhalten, bevor der Test läuft, damit ein Bestehen hinterher nicht still zu dem umdefiniert werden kann, was zufällig passiert ist. Ein Test, der nur bestätigt, dass ein Button existiert, ist kein Test; er muss den Button klicken, auf die echte Antwort warten, inklusive echter KI-Latenz, und den tatsächlich resultierenden Zustand prüfen. Jedes Feature wird so ausprobiert, wie es funktionieren soll, und so, wie es eine echte, mal nachlässige, mal feindselige Person tatsächlich falsch benutzen würde. Wenn sich ein “Fehler” als Bug im Testskript statt im Produkt entpuppt, wird das ebenfalls gemeldet, nicht still gepatcht und vergessen. Und ein Fix ist nicht fertig, wenn der Code kompiliert; er ist fertig, wenn genau das Szenario, das kaputt war, echt neu durchgelaufen ist und bestanden hat.
Jenseits von Velvet: sieben Schichten, nicht eine
Velvet ist eine Schicht von sieben. Echte, nicht gemockte KI-Verifikation läuft separat, ein Einmal-Skript gegen die lebende App mit echten Modellaufrufen, danach aufgeräumt, speziell um die Art von Bug zu fangen, die nur auftaucht, weil die Antwort eines echten Modells von Durchlauf zu Durchlauf variiert. Die Langzeit-Simulation lässt simulierte Firmengeschichten laufen, einen Monat, ein Jahr, fünf Jahre, gegen echte Mandanten mit durchgehend live laufenden KI-Aufrufen, und stellt an mehreren Punkten dieselben kanonischen Fragen, um zu prüfen, ob Antworten mit wachsender Historie tatsächlich schärfer wurden, nicht nur, ob überhaupt eine Antwort kam. Eine bewusste feindliche Schicht, acht feindselige Tests, die wir den Obstacle Course nennen, versucht direkt, die Ehrlichkeits- und Sicherheitsversprechen des Produkts zu brechen: Prompt Injection, mandantenübergreifendes Datenleck, widersprüchliche Anweisungen, Widerstandsfähigkeit gegen Löschung, echte Finanzabstimmung, Umgang mit doppelten Konten. Backend-Unit- und Integrationstests decken die Sacred Spine und die Dokumentenaufnahme von Anfang bis Ende ab. Geführte Durchläufe testen die tatsächliche UI bei echten Bildschirmgrößen, Desktop und einem echten mobilen Viewport, mit Screenshots als Beleg, kein reiner Haken auf einer Liste. Sogar die präsentativen Trailer-Videos dienten als Testschicht: Jedes davon ist ein echtes Skript, das gegen die echte, lebende App läuft, und jeder Moment, der beim Review leicht daneben wirkte, wurde einzeln entweder auf einen echten Bug oder ein Timing-Problem im Skript zurückgeführt, nie ohne Prüfung als das eine oder andere angenommen.
Über alles hinweg, rund fünfundzwanzig simulierte Jahre Geschäftsaktivität, mehrere Branchen, über neuntausend echte Vault-Einträge unterwegs erzeugt, elf echte Bugs gefunden und behoben. Gesamte echte API-Ausgaben für das gesamte Programm: 9,57 Dollar.
Was wir nicht behaupten werden
Wir haben Unternehmensmaßstab nicht getestet, Tausende gleichzeitiger Mandanten auf einmal. Wir haben nicht belastungsgetestet, was mit den KI-Kosten unter wirklich intensivem, offenem täglichen Chat passiert, im Gegensatz zur skriptierten Geschäftsaktivität, um die der Großteil dieses Testings herum gebaut wurde. Während der oben beschriebenen Arbeit haben wir ein echtes Skalierungsrisiko im eigenen Embeddings-Backfill gefunden, ein einmaliges Aufholen eines großen Vaults, das einem Request-Timeout unangenehm nahekam, und wir sagen euch das, statt es still zu patchen und nichts zu sagen.
Nichts hier ist perfekt, weil nichts perfekt ist. Wofür wir tatsächlich einstehen können: dass wir unsere eigenen Behauptungen gründlich geprüft haben, bevor wir sie euch gegenüber gemacht haben, und dass wir euch sagen, was wir gefunden haben, so oder so. Das ist die ganze Disziplin. Die behalten wir bei.