11. September 2026
16 mins

Ihr Entwickler ist weg. Die erste Woche entscheidet, was es kostet.

Von Tim Rutte, Cloud & Software Architect

Patchfeld mit einem nicht gesteckten Kabel, Artikelbild

Der Anruf klingt fast immer gleich. Ein System läuft seit Jahren, es verdient Geld oder hält den Betrieb zusammen, und die Person, die es gebaut hat, ist nicht mehr da. Gekündigt, in Rente, die Agentur gibt es nicht mehr, oder der Freelancer antwortet seit sechs Wochen nicht.

Die erste Frage ist dann meist: Wie lange dauert es, bis Sie den Code verstehen?

Das ist die falsche erste Frage. Nicht, weil sie unwichtig wäre, sondern weil sie ein Problem beschreibt, das Zeit hat. Der Code läuft weiter, ob ihn jemand versteht oder nicht. Was keine Zeit hat, sind die Dinge außerhalb des Codes, und die haben in fast jedem Fall, den ich gesehen habe, ein Ablaufdatum, von dem niemand wusste.

Dieser Artikel ist die Reihenfolge, in der ich in der ersten Woche vorgehe, und die Begründung dafür. Er ist absichtlich unspektakulär. Nichts daran ist schwierig, und genau deshalb wird es übersprungen.

Die Reihenfolge vorweg, falls Sie gerade keine fünfzehn Minuten haben:

  1. Zugänge und Eigentum sichern.
  2. Den Weg nach Produktion einmal gehen.
  3. Eine Sicherung einmal zurückspielen.
  4. Fristen und abgelaufene Softwarestände erfassen.
  5. Erst danach den Code systematisch erschließen.

Der Rest des Artikels begründet diese Reihenfolge und sagt, was in jedem Schritt regelmäßig schiefgeht.

Das Dringende ist nicht der Code

Ein Softwaresystem besteht aus zwei Teilen, und nur einer davon liegt im Repository. Der andere ist alles, was nötig ist, damit der erste Teil läuft: der Server, der Zugang zum Server, die Domain, das Zertifikat, die Datenbank, die Sicherung, der API-Schlüssel beim Zahlungsdienstleister, der Weg, auf dem eine Änderung nach draußen kommt.

Der Quellcode selbst läuft nicht ab. Seine Umgebung sehr wohl. Ein Zertifikat von Let's Encrypt ist nach neunzig Tagen abgelaufen, wenn die automatische Erneuerung nicht mehr funktioniert, und kurzlebigere Laufzeiten sind inzwischen ebenfalls im Umlauf. Eine Domain läuft nach einem Jahr aus, wenn die Rechnung an eine Mailadresse geht, die es nicht mehr gibt. Ein Zugangsschlüssel wird ungültig, wenn der Anbieter ihn rotiert. Ein Paket verschwindet aus dem Verzeichnis, und der Build, der es zieht, geht damit mit. Ein Serververtrag endet, wenn die Kreditkarte abgelaufen ist.

Jeder einzelne dieser Punkte legt ein laufendes System still, ohne dass eine Zeile Code sich geändert hat. Und viele davon lassen sich in der ersten Woche mit überraschend wenig Aufwand entschärfen, solange man sie überhaupt kennt. Manche nicht: Eine Domain, die auf einen Ehemaligen läuft, kann Wochen kosten. Umso mehr spricht dafür, früh nachzusehen.

Deshalb sortiert sich die erste Woche nach Verfall, nicht nach Verständnis. Was ablaufen kann, kommt zuerst. Was nur unverständlich ist, hat Zeit.

Zugänge und Eigentum, bevor irgendetwas anderes

Der erste Arbeitsschritt ist eine Liste, und die Liste hat zwei Spalten: Wo liegt es, und auf wessen Namen läuft es.

Die zweite Spalte ist die wichtigere, und sie wird regelmäßig vergessen. Zugriff zu haben und Eigentümer zu sein ist nicht dasselbe. Ich habe Projekte übernommen, in denen das Unternehmen den Server bezahlte, das Konto beim Hoster aber auf die private Mailadresse eines Ehemaligen lief. Zugriff war da, solange niemand das Passwort änderte. Handlungsfähig war das Unternehmen nicht: Es konnte den Vertrag nicht kündigen, nicht umstellen und im Streitfall nicht durchsetzen.

Die Liste, die ich anlege, umfasst mindestens diese Positionen:

  • Repository: Wo liegt der Quellcode, wer hat Schreibrechte, und existiert eine Kopie außerhalb dieses Dienstes? Ein Repository, das nur bei einem Anbieter liegt, hängt an einem Konto.
  • Server und Hosting: Welche Maschinen laufen, bei wem, auf welchen Vertrag, und wer bekommt die Rechnung? Wichtig auch, was es nicht mehr geben sollte: bezahlte Instanzen, die nichts mehr tun, finde ich bei Übernahmen regelmäßig.
  • Domains: Bei welchem Registrar, mit welchem Ablaufdatum, mit welchem Konto verknüpft, und läuft die automatische Verlängerung? Dazu die Frage, wer den DNS-Eintrag ändern kann. Das ist der Schalter, mit dem sich die Adresse eines Unternehmens umlegen lässt.
  • Zertifikate: Laufzeit, Erneuerungsweg, und ob die Erneuerung automatisch geschieht oder an einem Termin hängt. Wenn sie automatisch geschieht: wo, durch was, und was schlägt Alarm, wenn es einmal nicht klappt?
  • Datenbank: Wo liegt sie, wer hat Zugang, und liegt sie auf derselben Maschine wie die Anwendung? Falls ja, ist das ein eigener Punkt für später.
  • Dienste von außen: Zahlungsdienstleister, Mailversand, Suchdienst, Kartendienst, Warenwirtschaft. Für jeden davon: welcher Vertrag, welcher Schlüssel, wo liegt der Schlüssel, und wessen Konto hängt daran?
  • Mail: Die Adressen, an die Systemmeldungen und Rechnungen gehen. Wenn eine davon einem Ehemaligen gehört, hat das System einen blinden Fleck genau dort, wo es Alarm schlagen würde.

Diese Liste zu erstellen ist keine Ingenieursarbeit. Es ist Telefonieren, in Rechnungen der Buchhaltung nachsehen und Mailpostfächer durchsuchen. Es dauert typischerweise ein bis zwei Tage und fördert fast immer mindestens eine Lücke zutage, die vorher niemand für möglich gehalten hätte.

Was danach kommt, ist die eine Stunde, die den ganzen Aufwand wert ist: Alles, was auf einer privaten Adresse läuft, wird umgeschrieben. Alle Zugänge Ehemaliger werden entzogen, auch die, von denen man annimmt, dass sie ohnehin nicht mehr benutzt werden. Und jedes Konto, an dem eine Zahlung hängt, bekommt eine Adresse, die auch in zwei Jahren noch jemand liest.

Der Weg nach draußen, einmal von Hand gegangen

Die zweite Frage, die vor dem Code kommt: Wie gelangt eine Änderung in Produktion, und funktioniert dieser Weg noch?

Das ist keine rhetorische Frage. Bei einem System ohne Betreuung liegt die letzte Auslieferung oft ein Jahr zurück. Seitdem hat sich die Welt darunter weitergedreht: Der Build braucht eine Node-Version, die es im Basisbild nicht mehr gibt. Ein Zugangstoken für die Registry ist abgelaufen. Ein Paket ist aus dem Verzeichnis verschwunden. Der Server nimmt den SSH-Schlüssel nicht mehr, weil das Betriebssystem inzwischen aktualisiert wurde.

Ein Auslieferungsweg, der ein Jahr nicht benutzt wurde, ist mit hoher Wahrscheinlichkeit kaputt. Und man merkt es zum schlechtesten Zeitpunkt: dann, wenn eine Änderung dringend ist.

Deshalb liefere ich in der ersten Woche einmal aus. Nicht mit einer Änderung, die etwas bewirkt, sondern als kontrolliertes Nichts: der bereits laufende Stand noch einmal ausgerollt, oder eine Änderung ohne Wirkung auf das Verhalten. Ein „nur ein Leerzeichen" ist dafür übrigens keine gute Wahl, sobald Vorlagen, gebündelte Dateien oder Prüfsummen im Spiel sind. Gibt es eine Testumgebung, geht der erste Lauf dorthin. Ziel ist nicht die Änderung, sondern der Nachweis, dass der Weg begehbar ist. Was dabei bricht, bricht in einer Situation, in der es nicht drängt.

Dieselbe Übung gilt für die Gegenrichtung. Wenn eine Änderung schiefgeht, wie kommt der vorherige Stand zurück, und wie lange dauert das? Bei einem übernommenen System lautet die Antwort erschreckend oft: indem man die Änderung rückwärts nachbaut. Das ist kein Rückweg, das ist eine zweite Änderung unter Zeitdruck.

Was dabei entsteht, schreibe ich mit. Nicht als Dokumentation im großen Sinn, sondern als eine Datei, auf der steht, was ich getan habe, in welcher Reihenfolge und was ich dabei gelernt habe. Am Ende der Woche ist das die erste belastbare Betriebsanleitung, die dieses System je hatte, und sie ist entstanden, weil jemand den Weg einmal gegangen ist statt ihn zu beschreiben.

Eine Sicherung, die nie zurückgespielt wurde, ist keine

Fast jedes System, das ich übernehme, hat Sicherungen. Fast keines hat eine erprobte.

Das ist ein Unterschied, den man erst im Ernstfall bemerkt, und dann ist er teuer. Eine Sicherung besteht aus vier Eigenschaften, und drei davon werden üblicherweise nicht geprüft:

  • Sie existiert. Das wird geprüft, meist an einem grünen Häkchen in einer Oberfläche.
  • Sie ist vollständig. Häufig gesichert wird die Datenbank. Nicht gesichert werden die hochgeladenen Dateien, die Konfiguration außerhalb des Repositories und die Zustände, die nur im Cache leben. Eine Datenbank ohne die Dokumente, auf die sie verweist, stellt kein Geschäft wieder her.
  • Sie liegt woanders. Eine Sicherung auf derselben Maschine schützt vor einem Bedienfehler, nicht vor dem Verlust der Maschine, und nicht vor einer Verschlüsselung durch einen Angreifer, die alles einschließt, was von dieser Maschine aus erreichbar war.
  • Sie lässt sich zurückspielen. Das ist die einzige Eigenschaft, die zählt, und die einzige, die man nur durch Ausprobieren erfährt.

Der Test dafür ist ein halber Tag. Man nimmt die jüngste Sicherung, baut daraus eine Umgebung neben der Produktion auf, und sieht nach, ob die Anwendung startet und ob die Daten stimmen. Was dabei herauskommt, sind zwei Zahlen, die vorher niemand hatte: wie lange eine Wiederherstellung tatsächlich dauert, und welchen Datenstand die Sicherung tatsächlich zurückbringt. Das sind Ist-Werte. Ihnen gegenüber stehen die Zielwerte, also der Ausfall und der Datenverlust, die Ihr Geschäft gerade noch verträgt; das ist gemeint, wenn von RTO und RPO die Rede ist. Interessant wird es erst im Vergleich der beiden, und den kann nur führen, wer den Test einmal gemacht hat.

In dem halben Tag steckt noch ein zweiter Ertrag, der oft mehr wert ist als der erste. Wer aus einer Sicherung eine laufende Umgebung aufbaut, muss zwangsläufig herausfinden, was das System zum Starten braucht: welche Dienste, welche Umgebungsvariablen, welche Verzeichnisse, welche Version wovon. Das ist genau das Wissen, das mit dem Entwickler gegangen ist, und es lässt sich auf diesem Weg zurückholen, ohne dass jemand es erzählen muss.

Was in den nächsten Monaten von allein abläuft

Der vierte Punkt der ersten Woche ist eine Terminliste. Sie besteht aus allem, was einen Stichtag hat, und sie entsteht aus drei Quellen.

Verträge und Registrierungen: Domains, Zertifikate, Lizenzen, Serververträge, Wartungsverträge. Jeder mit Datum. Was in den nächsten sechs Monaten fällig wird, gehört in den Kalender einer Person, nicht in eine Datei.

Softwarestände ohne Unterstützung: Die Sprachversion, die Datenbankversion, das Betriebssystem, das Framework. Für jedes davon gibt es ein veröffentlichtes Ende der Sicherheitsunterstützung, und bei einem System ohne Betreuung liegt erfahrungsgemäß mindestens eines davon in der Vergangenheit. Das ist selten sofort gefährlich und selten unwichtig: Ohne Sicherheitsaktualisierungen wird jede künftige Lücke zu einer, die offen bleibt.

Abhängigkeiten mit bekannten Lücken: Ein Werkzeuglauf über die Paketliste zeigt in wenigen Minuten, welche installierten Pakete gemeldete Schwachstellen haben. Bei einem Bestand ohne Pflege ist die Liste selten leer, und sie beantwortet noch keine Frage, sondern stellt eine: Welche dieser Pakete sind an Wegen beteiligt, die von außen erreichbar sind?

Wichtig ist, was aus dieser Liste nicht folgt. Sie ist keine Aufgabenliste für die erste Woche. Sie ist die Grundlage, um zu entscheiden, was in den nächsten drei Monaten passiert, und sie verhindert die beiden häufigsten Fehlschlüsse: dass alles gleich dringend ist, und dass nichts dringend ist.

Erst jetzt der Code, und auch dann nicht als Umbau

Nach diesen vier Schritten ist das System handlungsfähig: Sie kommen überall hin, Sie können ausliefern, Sie können zurück, und Sie wissen, was wann abläuft. Jetzt lohnt es sich, in den Code zu sehen, und jetzt wird es auch nützlich, weil man einordnen kann, was man findet.

Der erste Blick ist kein Lesen von vorn nach hinten. Bei einem Bestand von einigen hunderttausend Zeilen wäre das Wochen ohne Ergebnis. Was ich stattdessen mache, sind drei Durchgänge mit unterschiedlichem Zweck.

Erstens der Umriss. Welche Einstiegspunkte gibt es überhaupt: Webanfragen, geplante Aufgaben, Warteschlangen, Kommandozeilenbefehle, Schnittstellen für andere Systeme. Diese Liste ist meist kürzer als erwartet und sagt mehr über das System als jedes Diagramm, denn sie ist vollständig überprüfbar. Besonders die geplanten Aufgaben sind hier wichtig: Cronjobs sind bei übernommenen Systemen der Ort, an dem sich Geschäftslogik versteckt, die niemand im Repository vermutet.

Zweitens die statische Analyse. Ein Analysewerkzeug über den gesamten Bestand, auf niedriger Stufe, ohne den Anspruch, die Meldungen abzuarbeiten. Der Zweck ist nicht Sauberkeit, sondern eine Karte: Wo häufen sich Meldungen, welche Bereiche sind offensichtlich unfertig, und wo steht Code, der schon zur Bauzeit nicht mehr aufging. Solche Häufungen zeigen, wo die Vorsicht hingehört.

Drittens der Geldweg. Ich verfolge den einen Ablauf, an dem das Geschäft hängt, von der ersten Anfrage bis zur Datenbank. Bestellung, Vertragsabschluss, Abrechnung, Auslieferung, je nachdem. Ein Weg, komplett, mit allem, was er anfasst. Danach kennt man das System nicht, aber man kennt den Teil, bei dem ein Fehler nicht diskutiert, sondern bezahlt wird.

Und erst dann, vor der ersten echten Änderung, kommt das Netz. Wo keine Tests existieren, schreibe ich Characterization Tests: Tests, die festhalten, was das System heute tut, ausdrücklich ohne die Frage, ob es richtig ist. Ein solcher Test darf ein falsch gerundetes Ergebnis festschreiben. Sein Zweck ist nicht Korrektheit, sondern eine Aussage darüber, ob eine Änderung etwas kaputt gemacht hat.

Das Netz muss nicht vollständig sein, und der Versuch wäre auch der falsche Weg. Es deckt den Geldweg aus dem dritten Durchgang ab und die Stellen, die als Erstes angefasst werden. Alles andere kommt dazu, wenn es dazukommen muss.

Warum das nicht früher kommt: Ein Test braucht eine Umgebung, in der das System läuft, und die entsteht erst durch den Wiederherstellungstest. Wer mit den Tests anfängt, baut sich diese Umgebung nebenbei und schlechter.

Die drei Fragen, die im Kopf des Entwicklers standen

Was bei einer Übernahme wirklich fehlt, ist nicht Dokumentation. Es ist Begründung.

Der Code zeigt, was implementiert wurde. Was er meistens nicht zeigt, ist, warum es so implementiert wurde und ob es Absicht war. Warum wird an dieser Stelle abgerundet und an jener kaufmännisch? Warum läuft dieser Abgleich um drei Uhr nachts und nicht um vier? Warum steht in dieser Abfrage eine Ausnahme für genau einen Kunden?

Jede dieser Eigenarten ist eines von zwei Dingen: eine bewusste Entscheidung, hinter der ein Grund steht, den man kennen müsste, oder ein alter Fehler, auf den sich inzwischen jemand verlässt. Von außen sehen beide gleich aus. Der Unterschied entscheidet, ob eine Änderung eine Korrektur oder ein Ausfall ist.

Deshalb frage ich in der ersten Woche nicht nur nach Zugängen, sondern nach Personen. Nicht nach Entwicklern, die es nicht mehr gibt, sondern nach denen, die mit dem System arbeiten: die Person in der Buchhaltung, die den Export jeden Monat prüft, die Person im Vertrieb, die weiß, dass man bei dieser einen Kundengruppe zweimal speichern muss. Diese Leute erklären in einer halben Stunde Verhalten, das man im Code in zwei Tagen nicht einordnen kann.

Was dabei entsteht, ist eine kurze Liste offener Fragen, die ich nicht auflöse, sondern festhalte. „Hier wird gerundet, Grund unbekannt, betrifft Rechnungsbeträge." Eine solche Notiz ist mehr wert als ihre Länge vermuten lässt: Sie verhindert, dass die nächste Person die Stelle für einen Fehler hält und behebt.

Das Ziel dieser Woche ist nebenbei, dass sie sich nicht wiederholt. Ein System, dessen Wissen in einem Kopf steckt, hat einen Bus-Faktor von eins, und genau deshalb sitzen Sie gerade in dieser Lage. Was in der ersten Woche entsteht, gehört daher nicht in mein Notizbuch, sondern in das Repository des Kunden, neben den Code, den es erklärt.

Was ich in der ersten Woche nicht mache

Die Versuchung bei einem übernommenen System ist groß, und sie zeigt sich in drei Formen.

Kein Aufräumen. In fremdem Code findet man auf jeder Seite etwas, das man anders machen würde. Das anzufassen, bevor ein Testnetz existiert, ist die riskanteste Art, Zeit zu verbrauchen: Es ändert Verhalten, ohne Verhalten zu prüfen, und wenn danach etwas nicht mehr stimmt, weiß niemand, ob es an der Änderung lag oder schon vorher so war.

Kein Versionssprung. Ein Framework oder eine Sprachversion anzuheben, ist der offensichtliche erste Schritt und der falsche. Ein solcher Sprung verändert viele Stellen gleichzeitig, in einem System, dessen heutiges Verhalten noch niemand festgehalten hat. Das Upgrade ist richtig, es kommt nur später, und es kommt in Schritten, die einzeln produktiv gehen. Was dabei auf einen zukommt, habe ich am Sprung von PHP 7.4 auf PHP 8.4 aufgeschrieben.

Kein Urteil über einen Neubau. Die Frage kommt fast immer schon im ersten Gespräch, oft mit einem Angebot in der Hand. Sie ist berechtigt, aber sie ist in der ersten Woche nicht beantwortbar. Wer den Bestand nicht beziffern kann, vergleicht eine bekannte Zahl mit einem Gefühl, und dieser Vergleich geht immer zugunsten des Neubaus aus. Warum das so oft schiefgeht, steht in einem eigenen Artikel: warum vollständige Neuentwicklungen scheitern.

Was ich stattdessen am Ende der Woche abgebe, ist unspektakulär: eine Liste von Zugängen mit Eigentümern, ein einmal gegangener Auslieferungsweg, eine erprobte Sicherung mit einer echten Wiederherstellungszeit, eine Terminliste, eine Karte des Bestandes und eine Handvoll offener Fragen. Nichts davon sieht nach Fortschritt aus. Zusammen ist es der Unterschied zwischen einem System, das jemand betreibt, und einem, das läuft, solange nichts passiert.

Wenn es schon brennt

Der Artikel bis hier beschreibt den geordneten Fall: Das System läuft, es ist nur niemand mehr da. Manchmal ist der Anlass ein anderer, und dann gilt eine kürzere Fassung.

Wenn das System gerade steht, kommt die Wiederherstellung vor allem anderen, und die Aufnahme entsteht als Nebenprodukt: Was Sie tun mussten, um es wieder zum Laufen zu bringen, ist Ihre erste Betriebsanleitung. Schreiben Sie mit, während Sie es tun, nicht danach.

Wenn es einen Verdacht auf einen Einbruch gibt, wird nicht einfach aufgeräumt. Eindämmung und Spurensicherung müssen zusammen entschieden werden: Je nach Lage kann es nötig sein, Systeme sofort zu trennen oder Zugänge zu sperren, und zugleich dürfen die Spuren nicht durch unüberlegte Änderungen verschwinden. Das ist Incident Response, keine gewöhnliche Projektübernahme, und es gehört an jemanden, der das macht.

Wenn Streit im Raum ist, etwa mit einer Agentur, deren Vertrag nicht beendet ist, kommt vor der Technik die Frage, wem was gehört. Quellcode, Nutzungsrechte an Zukäufen, Zugänge, Daten. Diese Frage in der ersten Woche zu klären ist unangenehm und billiger als jede spätere Variante.

In allen drei Fällen bleibt der Kern derselbe: Das Dringende ist nicht, den Code zu verstehen. Das Dringende ist, handlungsfähig zu sein, bevor der nächste Termin von allein eintritt. Wie eine solche Übernahme bei mir abläuft und was der Einstieg kostet, steht auf der Seite zum PHP-Projekt übernehmen. Wer nur eine Einschätzung des eigenen Stands sucht, bekommt sie ohne Gespräch über den Legacy Risk Score.