Warum ein Fork keine eigene Lizenz tragen kann
Wir haben monatelang einen AGPL-Fork gepflegt und wollten daraus ein eigenes Produkt machen. Das ging nicht, und zwar aus einem Grund, den man vorher nachlesen kann. Was wir stattdessen getan haben und was der Neubau an Fehlern zutage gefördert hat.
Mit KI erzeugtes Bild. Mehr zur KI-TransparenzWir haben ein knappes halbes Jahr lang einen Fork eines Open-Source-Werkzeugs gepflegt, 46 Veröffentlichungen, ein paar tausend Installationen im Monat. Dann wollten wir daraus etwas machen, das uns gehört: eigene Lizenz, offen für die meisten Zwecke, mit der Möglichkeit, später eine bezahlte Erweiterung anzuhängen.
Das ging nicht. Der Grund steht in einer Datei, die im Repository von Anfang an lag, und wir hätten ihn am ersten Tag lesen können.
Die Datei heißt LICENSE
Das Ursprungswerk steht unter der AGPL-3.0, das Copyright liegt bei einer fremden Firma. Die AGPL ist starkes Copyleft. Jede Ableitung bleibt AGPL, und ob man selbst dreißig Veröffentlichungen und den Großteil des heutigen Codes beigetragen hat, ändert daran nichts. Man ist Miturheber am Zusatz, nicht Inhaber am Ganzen.
Praktisch heißt das: umbenennen ist keine Neulizenzierung. Ein Fork, der “NeuerName” heißt und ansonsten derselbe Baum ist, bleibt AGPL. Wer daran ein Bezahlmodell hängt, verkauft etwas, dessen Quelltext er jedem Empfänger offenlegen muss, und braucht für ein Dual-Lizenz-Modell das Copyright, das er nicht hat.
Das ist keine Grauzone und keine Auslegungsfrage. Es ist der Zweck der Lizenz.
Also von vorn, und zwar getrennt
Die Alternative ist ein eigenständiges Werk. Das ist mehr Arbeit als ein Umbenennen, aber es ist auch die einzige Fassung, die dauerhaft trägt.
Dabei kommt es auf eine Unterscheidung an, die im Alltag leicht verwischt.
Geschützt ist die konkrete Umsetzung, nicht das Wissen über das Problem. Dass
Hooks unter Windows in cmd.exe überleben müssen, ist eine Tatsache über
Windows. Dass ein Abhängigkeits-Pin erst gilt, wenn die Lockdatei ihn zeigt,
ist eine Tatsache über den Paketmanager. Solche Erfahrungen darf man mitnehmen,
den Code nicht.
Bei uns sah die Trennung so aus. Die Spezifikation trägt als ersten Abschnitt eine Erklärung, die jeden Beitragenden bindet: kein Blick in den fremden Baum, Umsetzung ausschließlich aus dem Dokument. Jeder Arbeitsauftrag wiederholte das wörtlich. Ein Abschnitt der Spezifikation listet die Betriebserfahrungen der Vorjahre als Anforderungen, in eigenen Worten, ohne eine Zeile fremden Quelltext. Und der Commit-Verlauf hält bei jeder Entscheidung fest, warum sie so gefallen ist.
Der Verlauf ist dabei kein Beiwerk. Wer kurz nach dem Archivieren eines AGPL-Forks ein ähnliches Werkzeug veröffentlicht, bekommt die naheliegende Frage gestellt. Eine Historie, die bei jedem Schritt zeigt, was warum entschieden wurde, ist die Antwort. Ein Repository mit einem einzigen “initial commit” ist das Gegenteil davon.
Was das Bauen zutage gefördert hat
Der interessantere Teil ist nicht die Lizenz, sondern was auffällt, wenn man eine Zusage von Grund auf umsetzt statt sie zu erben.
Eine Abhängigkeit, die still nach Hause telefoniert. Wir wollten eine Bibliothek für lokale Einbettungen nehmen. Sie zieht ein Paket mit, das Modelldateien selbständig herunterlädt. Das klingt harmlos, macht aber die zentrale Zusage falsch, dass jeder ausgehende Pfad in einem Register steht, das man ausdrucken kann. Eine Zusage, die nicht stimmt, ist schlechter als keine. Die Berechnung selbst ist ein Tabellennachschlag mit Mittelwertbildung, also haben wir sie selbst geschrieben und die Abhängigkeit ist aus dem Baum verschwunden.
Ein Typ, der beschreibt statt zu erzwingen. Die einzige Funktion, die einen
HTTP-Client bauen darf, nahm einen Parameter namens EgressPurpose entgegen.
Sie las sich wie eine Absicherung. Sie prüfte den Zweck sogar gegen sich selbst.
Und sie rief die eigentliche Genehmigung nie auf, im ganzen Crate kein einziges
Mal. Ein Parameter, der eine Absicht benennt, lässt die Aufrufstelle sich selbst
beschreiben. Erst ein Parameter, der das Mittel zur Prüfung verlangt, macht das
Fragen unumgänglich.
Ein flackernder Test, der ein echter Fehler war. Ein Test bestand einzeln und fiel im Verbund. Dahinter steckten zwei Uhren: die eine Schicht stempelte mit Nanosekunden, die Ablage kürzte auf Millisekunden. Der zurückgegebene Wert war also größer als der geschriebene, und ein Filter, der aus einer Zeile gebaut wurde, fand genau diese Zeile nicht mehr. Ein Leser hätte eine Lücke in einem lückenlosen Protokoll gesehen.
Eine Oberfläche, die erfundene Zahlen ausgeliefert hätte. Die Weboberfläche lief standardmäßig gegen Attrappen. Die Binärdatei bettet sie ein. Ein Veröffentlichungsbau hätte also einen Compliance-Bildschirm ausgeliefert, der ausgedachte Egress-Zähler und Audit-Zeilen zeigt, ausgerechnet dort, wo der ganze Zweck darin besteht, geglaubt zu werden. Ein Hinweisfeld auf der Seite schützt einen Entwickler, der hinschaut, und schützt nichts an einer Binärdatei, die jemand anderem in die Hand gedrückt wird. Heute verweigert das Build-Skript so einen Bau.
Und ein Test, der eine Regel gar nicht sehen konnte. Für den Protokollserver gilt, dass über die Standardausgabe ausschließlich Protokoll geht. Zur Probe haben wir eine Debug-Ausgabe eingepflanzt. Alle zwölf In-Process-Tests blieben grün. Nur der Test, der den Server als eigenen Prozess startet, schlug an. Der Grund ist strukturell: ein In-Process-Test bekommt ein Paar Pipes, und dieser Strom ist nicht die Standardausgabe des Prozesses. Wenn eine Regel über einen Prozesskanal spricht, muss der Test den Prozess starten.
Was mit dem alten Projekt passiert
Es ist eingestellt und archiviert, aber nicht gelöscht, und das Paket ist deprecated statt zurückgezogen. Das ist keine Nostalgie. Wer Software unter der AGPL verbreitet hat, schuldet den Empfängern den Quelltext, und ein archiviertes Repository bleibt lesbar, während ein gelöschtes es nicht tut. Die letzte Fassung funktioniert weiter, es wird nichts weggenommen, und wer es weiterführen möchte, darf es forken.
Das neue Werkzeug heißt Cyberbrain. Es ist ein eigenständiges Werk, von Grund auf neu geschrieben, es teilt keinen Quelltext mit dem alten Projekt oder dessen Ursprung, und es trägt eine eigene Lizenz. Es ist keine Fortsetzung.
Veröffentlicht ist es noch nicht.
Die Lehre, falls Sie vor derselben Frage stehen
Lesen Sie die LICENSE, bevor Sie forken, und nicht erst, wenn Sie ein Produkt daraus machen wollen. Die Frage lautet nicht, ob Sie den Fork pflegen dürfen. Das dürfen Sie fast immer. Die Frage lautet, was Sie in zwei Jahren damit vorhaben, und ob die Lizenz das dann noch zulässt.
Bei uns hat diese Frage einen Tag Arbeit an einer Umbenennung verhindert, die nie getragen hätte.