Zum Inhalt

Status: Archiv/Informativ Prioritaet bei Konflikt: Es gelten immer 00 bis 08. Hinweis: Diese Datei ist historischer oder ergaenzender Kontext und nicht normativer Kern.

Anhang S – Subsystem-Kapselung und Zustandsintegrität

Status: Kern-Architekturprinzip
Gültigkeitsbereich: Dieses Dokument legt verbindliche Architekturregeln für alle Jade-Subsysteme fest, wie sie ihren internen Zustand verwalten und wie sie miteinander interagieren dürfen.
Es gilt normativ für alle Komponenten (Type Engine, Memory Engine, Generator, VM, Plugin Broker, Effect System, Scheduler usw.).


S.1 Motivation

Jade besteht aus mehreren kooperierenden Subsystemen:

  • Type Engine
  • Memory Engine
  • Generator
  • VM / Runtime
  • Effect System
  • Plugin Broker
  • Scheduler / Concurrency Layer
  • weitere spezialisierte Dienste

Jedes dieser Systeme besitzt eigenen internen Zustand und eigene Invarianten.
Um langfristige Wartbarkeit, Korrektheit und klare Verantwortlichkeiten zu gewährleisten, gelten folgende zentrale Architekturregeln:

  1. Strikte Kapselung
    Der interne Zustand eines Subsystems darf niemals direkt von anderen Subsystemen verändert werden.
  2. Wohldefinierte Schnittstellen
    Alle Zustandsänderungen erfolgen ausschließlich über explizite APIs des jeweiligen Subsystems.
  3. Explizite Invarianten
    Jedes Subsystem definiert klar, welche Bedingungen für seinen Zustand immer gelten müssen.
  4. Deterministische Zustandsübergänge
    Öffentliche Operationen führen von einem gültigen Zustand in einen anderen gültigen Zustand. Zwischenzustände sind intern erlaubt, aber nach außen unsichtbar.

Dieser Anhang beschreibt diese Regeln und ihre konkrete Anwendung auf die Hauptkomponenten.


S.2 Subsystem Encapsulation Law (Kapselungsgesetz)

Subsystem-Kapselungsgesetz

  1. Jedes Subsystem besitzt einen klar abgegrenzten internen Zustand, für den es allein verantwortlich ist.
  2. Kein anderes Subsystem darf diesen Zustand direkt lesen oder schreiben. Insbesondere gilt:
  3. Keine fremden Zeiger auf interne Tabellen, Strukturen oder Arrays
  4. Kein gemeinsam genutzter, von mehreren Subsystemen direkt beschriebener Speicher
  5. Alle Interaktionen zwischen Subsystemen laufen ausschließlich über wohldefinierte Schnittstellen:
  6. Queries (nur lesend / beobachtend)
  7. Commands (verändernd, mit klar beschriebenem Effekt)
  8. Zustandsänderungen dürfen nur vom jeweiligen Subsystem selbst durchgeführt werden – als Reaktion auf eigene Commands.
  9. Subsysteme teilen niemals direkt mutable Referenzen auf ihren Zustand. Erlaubt sind:
  10. Kopien
  11. Handles / Opake Identifier
  12. Snapshots
  13. abgeleitete read-only Views

Konsequenz:
Kein Subsystem „pfuscht“ in den Datenstrukturen eines anderen herum. Jede Zustandsänderung ist eine bewusste Entscheidung des Zustands-Eigentümers.


S.3 Queries vs. Commands

Alle öffentlichen APIs eines Subsystems werden in genau zwei Kategorien unterteilt:

Queries (nur lesend)

  • Beobachten den Zustand, verändern ihn aber nicht
  • Beispiele:
  • type_engine.getTypeInfo(TypeId)
  • mem_engine.getLayout(TypeId)
  • effects.getFunctionEffects(FnId)
  • plugin_broker.listLoadedPlugins()
  • Queries dürfen intern cachen – dieser Cache liegt aber vollständig in der Verantwortung des Subsystems.

Commands (verändernd)

  • Verändern den internen Zustand des Subsystems
  • Beispiele:
  • type_engine.internType(TypeDescriptor)
  • mem_engine.createArena(ArenaConfig)
  • plugin_broker.loadPlugin(PluginSpec)
  • scheduler.spawn(TaskSpec)
  • Commands müssen sicherstellen, dass nach Rückkehr alle Invarianten des Subsystems wieder erfüllt sind.

Regel:
Andere Subsysteme dürfen nur Queries und Commands aufrufen – niemals interne Hilfsfunktionen oder Datenstrukturen direkt manipulieren.


S.4 State Invariants (Zustands-Invarianten)

Jedes Subsystem muss seine eigenen State Invariants explizit dokumentieren – Bedingungen, die nach Rückkehr jeder öffentlichen API-Funktion gelten müssen.

S.4.1 Type Engine – Beispiele

  • Jeder TypeId referenziert genau einen gültigen TypeDescriptor
  • Alle Typreferenzen sind gültige TypeIds
  • Die Policies eines Typs sind widerspruchsfrei (share, memory, ffi, …)
  • Internierung ist stabil: gleicher logischer Typ → gleicher TypeId

S.4.2 Memory Engine – Beispiele

  • Jeder Handle zeigt entweder auf gültigen Speicher oder ist als ungültig markiert
  • Arenen enthalten nur Objekte, die durch sie selbst allokiert wurden
  • Referenzzähler werden nie negativ
  • Layout-Informationen (size, align, Offsets) sind konsistent und unveränderlich

S.4.3 Generator – Beispiele

  • Jeder IR-Knoten gehört zu genau einem Modul und einem gültigen IR-Graphen
  • Sprungziele verweisen auf existierende Basic Blocks
  • Der Kontrollflussgraph ist vollständig (außer explizit markiertem unreachable)
  • Nach Abschluss ist der Generator-State entweder weggeworfen oder konsistent

Prinzip:
Temporäre Invariantenverletzungen sind während interner Abläufe erlaubt, dürfen aber niemals über die öffentliche API sichtbar werden.


S.5 Der Generator: Read-only Konsument

Der Generator nimmt eine Sonderrolle ein:

Design-Regeln für den Generator

  1. Er behandelt alle anderen Subsysteme als read-only Dienste → ruft ausschließlich Queries auf
  2. Er verändert niemals direkt den Zustand anderer Subsysteme (Ausnahme: klar dokumentierte Initialisierungs- / Registrierungspfade)
  3. Der Generator ist deterministisch → gleiche Eingaben → gleicher Bytecode / IR / Maschinencode

Der Generator ist somit ein reiner Abbildungsautomat von getyptem JDL-Code auf verschiedene Ausgabeformate – ohne Rückschreibzugriff.


S.6 Determinismus und „Keine Magie“

Für alle Kernpfade der Jade-Toolchain gelten:

  1. Determinismus
    Gleiche Eingaben (Quelltext + Konfiguration + Profilingdaten) → gleiche Artefakte
  2. Keine stillen Korrekturen
    Fehler werden gemeldet – nicht heimlich repariert
  3. Keine versteckten Nebenwirkungen
    Nicht dokumentierte I/O oder State-Änderungen sind verboten
  4. Explizite Optimierungspässe
    Optimierungen geschehen in klar benannten, separaten Schritten
    (z. B. inline_trivial_calls, lower_effects, simplify_branches)

S.7 Zusammenfassung – Die Kernprinzipien

  • Subsysteme kapseln ihren Zustand strikt
  • Interaktionen laufen ausschließlich über Queries und Commands
  • Jedes Subsystem definiert und garantiert explizite Invarianten
  • Der Generator ist ein reiner, deterministischer read-only Konsument
  • Keine Magie – alle intelligenten Entscheidungen sind explizit, nachvollziehbar und konfigurierbar

Diese Regeln bilden die Grundlage dafür, dass Jade langfristig erweiterbar, debuggbar und formal analysierbar bleibt – auch bei Hinzunahme neuer Backends, Optimierer und Subsysteme.