Unter der Haube

Die Engine ist ein Microkernel

Öffnest du Scellis, lädt dein Browser genau eine bewusst kleine Sache herunter: die Engine. Alles, womit du tatsächlich arbeitest — jeder Block, jede Op, jedes Modell, jeder Workflow, jeder Viewer — steckt nicht in diesem Download. Es ist Content, zur Laufzeit aus der Datenbank geliefert. Diese Trennung ist die tragende Wand der Plattform: Sie erklärt, warum neue Fähigkeiten ohne App-Update auftauchen, warum die App in Sekunden startet und warum Arbeit von vor einem Jahr noch läuft. Dieser Artikel läuft die Engine-Seite der Trennung ab; wie Content gespeichert und gehasht wird, erzählt das Datenbank-Rückgrat.

Ein Microkernel — nichts Domänenspezifisches darin#

Die kompilierte App ist ein Microkernel. Sie besitzt eine kurze, stabile Liste von Verantwortlichkeiten: Berechnung validieren und absenken, sie auf WebGPU und der CPU-Referenz ausführen, Katalog-Content laden und cachen, deine Daten persistieren und synchronisieren und das Studio rendern — samt Copilot. Diese Liste ist die ganze Engine. Nichts Domänenspezifisches lebt darin, und Domänenlogik dort unterzubringen gilt als Anti-Pattern, nicht als Abkürzung.

Eine neue Fähigkeit ist deshalb nie ein Engine-Patch. Sie ist eine Spezifikation plus Implementierung, ausgeliefert als Content — oft gebündelt als Pack — über exakt den Weg, den deine eigenen erstellten Entitäten nehmen. Veröffentliche einen neuen Block, und er erscheint beim nächsten Sync in deinem Catalog: kein Release-Zug, keine Neuinstallation. Das Engine-Bundle trägt sogar ein erzwungenes Byte-Budget — „klein“ ist eine geprüfte Eigenschaft, kein Vorsatz. Der Microkernel selbst ist quelloffen veröffentlicht unter einer Fair-Code-Lizenz, die zu einer permissiven konvergiert — die Openness-Seite beschreibt das Ring-Modell exakt.

Abhängigkeiten zeigen in eine Richtung#

Innerhalb der Engine hängen Code-Schichten streng nach unten — Tools, Contracts, der Microkernel-Kern, die Service-Schichten, die Apps — ohne Zyklen und ohne Library, die heimlich von einer App abhängt. Das ist keine Ästhetik: Ein einseitiger Abhängigkeitsgraph ist, was den Kern hinter stabilen Schnittstellen weiterentwickeln lässt, ohne dass ein Gewirr von Internas zurückgreift und eine Erweiterung zerbricht. Jedes erweiterbare Konzept ist eine string-basierte Registry statt eines fest verdrahteten Switch — einen Optimizer, einen Kernel, einen Connector hinzuzufügen ist eine Registrierung, nie ein Kern-Edit. Die Engine bleibt klein, weil die Architektur die üblichen Wege verbietet, sie wachsen zu lassen.

Ein versionierter Vertrag zwischen Engine und Content#

Content überlebt jeden einzelnen Engine-Build, also ist die Beziehung zwischen beiden ein expliziter Vertrag. Die Engine trägt eine semantische engine_version und macht ihr Können als benannte Capability-Flags sichtbar — webgpu.f16, ir.scan, secure_agg.v1. Content deklariert umgekehrt, was er braucht: Die Metadaten jeder Entität tragen ein min_engine und optional die Menge der benötigten Capabilities.

json
{
  "min_engine": "1.4.0",
  "required_capabilities": ["webgpu.f16", "ir.scan"]
}

Beachte, was Content nie tut: Er prüft keine Versionsnummern gegen eine Tabelle von Verhaltensweisen. Er benennt die Features, die er braucht — und die Engine hat sie oder eben nicht.

text
engine_version : 1.5.0
capabilities   : [ webgpu.f16, webgpu-render, ir.scan, secure_agg.v1 ]
# content tests FEATURES, never the version number:
#   requires webgpu.f16  -> present  -> runs
#   requires ir.complex  -> absent   -> refused, loudly
was der Content verlangtder Loaderein Kernelbraucht webgpu.f16ein Viewerbraucht Engine 1.2+eine Opbraucht webgpu.subgroupsdiese Enginewebgpu.f16ir.scanengine 1.5abgelehnt · kein webgpu.subgroupsdas kann diese Engine
Abb. 1 — Content benennt die Features, die er braucht, und der Loader gleicht sie mit dem ab, was diese Engine wirklich kann. Ein fehlendes Feature wird namentlich abgelehnt; eine Versionsuntergrenze ist dieselbe Prüfung, nur einfacher.

Ablehnung ist laut, nie still#

Kann die laufende Engine ein Stück Content nicht erfüllen, weigert sich der Loader, es auszuführen — über die eine kanonische Diagnose, durch die jeder Fehler in Scellis fließt. Im Katalog liest sich das als klares „braucht ein neueres Scellis“-Badge, nie als Absturz und nie als stiller Versuch, etwas zu berechnen, das die Engine nur halb versteht. Eine falsche Zahl, die richtig aussieht, ist das schlechteste Ergebnis, das wissenschaftliche Arbeit erzeugen kann — die Plattform macht es strukturell unverfügbar.

Hinweis

Stille Fallbacks sind plattformweit Defekte. Kann etwas nicht laufen, erfährst du was und warum — in einem konsistenten Format, demselben Envelope, das UI, Copilot und externe Agenten lesen.

Eine neuere Engine muss älteren Content ausführen#

Das Kompatibilitätsversprechen zeigt in eine Richtung und ist strikt: Eine neuere Engine muss jeden Content ausführen, den eine frühere Engine ausgeführt hat. Veröffentlichte Versionen sind unveränderlich, die Annahmeseite des Vertrags ist also stabil. Evolution ist additiv — ein neues Capability-Flag, eine neue Absenkungsstufe oder ein neuer Wert in einem der bewusst geschlossenen Engine-Sets (eine IR-Sprosse, eine Determinismus-Stufe, eine Toleranzklasse, ein dtype) ist rückwärtskompatibel, weil älterer Content ihn nie referenziert hat.

Erzwungen durch einen eingefrorenen Korpus#

Dieses Versprechen wird erzwungen, nicht erhofft. Ein eingefrorener Korpus repräsentativen älteren Contents wird von der aktuellen Engine erneut ausgeführt und muss innerhalb seiner deklarierten Toleranzen grün zurückkommen; ein Engine-Update, das die Zahlen eines alten Workflows verschiebt, wird vor dem Ausliefern abgefangen. Die Langlebigkeits-Garantie ist dieser Korpus. Die ehrliche Grenze: Nicht alles kann Content sein. Eine wirklich neue Engine-Fähigkeit — eine neue Sprosse der Absenkungsleiter, eine neue Determinismus-Stufe — kommt als von Maintainern gebautes Engine-Release. Content deklariert sie dann als Voraussetzung, und ältere Engines lehnen laut ab, genau wie oben.

Updates wechseln atomar; offline arbeitest du weiter#

Die Engine aktualisiert sich über denselben Bootstrap, der deinen Content synchronisiert. Eine neue Shell wird geholt, ihre Bytes werden vor der Aktivierung gegen einen signierten Hash verifiziert, dann wird atomar gewechselt — eine halb aktualisierte Engine läuft nie, und deine lokale Content-Datenbank bleibt vom Wechsel unberührt. Eine parallele Disziplin schützt den Client-Zustand über Deploys hinweg: Eine abgeleitete Daten-Epoche prüft Code gegen den Zustand, den er persistiert hat, baut alles Wiederherleitbare in Sekunden neu auf, während deine Entwürfe und ungeflushten Edits erhalten bleiben. Ein Deploy legt einen zurückkehrenden Tab nie lahm, und eine universelle Reset-Luke ist die einzeilige Rettung.

engine 1.6geladenHash geprüftengine 1.6in einem Schrittund wenn du offline bist:engine 1.5längst auf deinem Gerätläuft weiter · nichts wird gewechselt
Abb. 2 — Ganz oder gar nicht. Die neue Engine wird gegen einen signierten Hash geprüft, bevor sie überhaupt läuft, und dann in einem Schritt aktiv — eine halb aktualisierte Engine kann es nicht geben. Und bist du offline, wird gar nichts gewechselt: Die Engine, die du schon hast, läuft weiter.

Weil Scellis local-first ist, läuft eine Offline-Maschine mit ihrer gecachten Engine unbegrenzt weiter — kein erzwungenes Update, kein Fernschalter über deiner Arbeitsfähigkeit. Und Reproduzierbarkeit fährt auf demselben Vertrag: Ein Lauf pinnt sowohl seine Content-Hülle als auch die engine_version, die ihn ausgeführt hat — ein reproduziertes Ergebnis weiß also genau, welchen Engine-Vertrag es braucht. Sofortige Lieferung, ein kleiner Kern, den Content nicht destabilisieren kann, und eine Laut-ablehnen-oder-laufen-Garantie, die die Arbeit von gestern auf der Engine von morgen weiterlaufen lässt — das bringt die Trennung.