Zum Inhalt

JDL — Engine-/Descriptor-Modell

Status: Normativer Architekturzusatz
Geltungsbereich: Blueprints, Engines, CompilerDB, RuntimeBus, Scheduler, Descriptoren, Bootstrapping
Ergänzt: jdl-blueprint-spec.md, jdl-typefn-spec.md, jdl-vm-scheduler-spec.md, 08-intrinsics-vm-api.md, jade-compiler-db-spec.md
Zweck: Gemeinsame Begriffe für die Trennung zwischen JDL-Semantik und Ring-0-Mechanik


1. Architekturformel

D / Ring 0      = Substrate + Trust Anchor
JDL / Ring 1    = Semantik + Evolution Layer
Blueprint       = deklarative Beschreibung
Engine          = Auswertung einer Beschreibung
Descriptor      = materialisierter Vertrag zwischen JDL-Semantik und Ring-0-Domäne

Jade verfolgt kein vollständiges Self-Hosting-Dogma. Die VM, der Scheduler, die JME, der RuntimeBus, die CompilerDB-Speicherstruktur, die Intrinsic-Dispatch-Tabelle, der Seed-Loader und die Host-Integration bleiben Ring 0. Syscalls, Threads, FFI, epoll/io_uring und Handle-Tabellen sind Maschinenkontakt und gehören nicht in user-facing JDL.

Das Self-Hosting-Ziel ist präziser:

D besitzt Mechanik. JDL besitzt Semantik.

Ring-1-JDL-Engines erzeugen Descriptoren. Ring-0-Domänen verwalten zur Runtime Instanzen anhand dieser Descriptoren.


2. Engine-Begriffe

Der Begriff Engine ist in drei Ebenen zu trennen.

EngineDefinition     JDL-seitige Semantik und Provide-Implementierung
EngineDescriptor     materialisierter Vertrag aus Blueprint + Refinements
EngineRuntimeConfig  Ring-0-Schedulerdaten: Limits, Timer-Wheel, Capabilities
EngineInstance       laufendes Ergebnis, sichtbar über Handle/Ref

Eine EngineDefinition darf Validierungslogik, Descriptor-Erzeugung, Mapping-Regeln, Middleware-Komposition und Dependency-Auflösung enthalten.

Eine EngineDefinition darf keine Ring-0-Zustände besitzen:

  • keine Scheduler-Queues,
  • keine Handle-Tabellen,
  • keinen JME-Speicher,
  • keine OS-Filedeskriptoren,
  • keinen epoll/io_uring-State,
  • keine RuntimeBus-Port-Interna,
  • keine CompilerDB-Storage-Interna.

Ring 0 bleibt State Owner. Engines erzeugen Descriptoren und Konfigurationen.


3. Descriptoren

Ein Descriptor ist ein geprüftes, materialisiertes Artefakt. Er liegt zwischen deklarativer JDL-Semantik und mechanischer Ring-0-Ausführung.

Beispiele:

TypeEngine                -> TypeDescriptor, LayoutDescriptor, LabelProfile
ProtocolDispatcherEngine  -> DispatchDescriptor, BindingTableDescriptor
FfiBindingEngine          -> NativeLibraryDescriptor, FfiCallDescriptor, MarshalDescriptor
GeneratorEngine           -> VmModuleArtifact, Proto, RegisterLayout
Scheduler-/RuntimeEngine  -> EngineDescriptor, EngineRuntimeConfig
EffectEngine              -> EffectDescriptor, CallGraphDescriptor

Descriptoren sind nicht bloß Debug-Daten. Sie sind der Vertrag, den Ring-0-Domänen konsumieren.


3.1 CompilerDB-Provider

Compiler-nahe Engines können als QueryProvider der CompilerDB auftreten. Eine ParserEngine kann GetFileAST beantworten, eine TypeEngine ResolveType, eine ProtocolDispatcherEngine BuildDispatchDescriptor, eine GeneratorEngine GenerateVmModule.

Das macht die Engine nicht zum Besitzer der CompilerDB. Die CompilerDB bleibt Cache-, Dependency-, Seed-, Descriptor- und Materialization-Substrate. Engines lesen andere Phasen ausschließlich über Queries und geben Descriptoren oder MaterializationPatches zurück.

3.2 TypeFnContext und Patch-Materialisierung

TypeFns folgen derselben Descriptor-Grenze wie Engines. Sie werden in einem TypeFnContext evaluiert und erzeugen Patches, nicht direkte CompilerDB-Mutationen.

TypeFnContext
  db:        TypeFnDbView
  target:    Option[TypeSubject]
  phase:     TypeFnPhase
  namespace: ModulePath
  proof:     ProofTraceBuilder

Bei Refinements liefert :> das Target-Subject und erzeugt intern einen ApplyRefinement-Record. Der TypeFnEvaluator erzeugt daraus ein PatchSet. Erst der CompilerDB-Materializer committed dieses PatchSet als MetaRecord-, TypeDescriptor- oder Descriptor-Änderung.

subject :> Refinement(args)
  -> ApplyRefinement(subject, Refinement, args)
  -> TypeFnContext(target = subject)
  -> PatchSet
  -> Materializer
  -> DescriptorStore / MetaRecordStore

Damit bleiben TypeFns Teil der JDL-Semantikschicht, ohne Ring-0- oder CompilerDB-Storage-Zustände direkt zu besitzen.

4. Engine-Protocols

Für einfache Fälle bleibt ein ergonomisches Engine[B, Out] verwendbar:

protocol Engine[B, Out] {
    def validate(spec: B) -> Result[(), DiagnosticSet]
    def execute(spec: B) -> Out
}

Normativ ist die Descriptor-Form präziser:

protocol DescriptorEngine[Spec, Desc] {
    def describe(spec: Spec) -> Result[Desc, DiagnosticSet]
}

protocol RuntimeEngine[Spec, Desc, Out] {
    def describe(spec: Spec) -> Result[Desc, DiagnosticSet]
    def instantiate(desc: Desc) -> Result[Out, EngineError]
}

describe beweist und materialisiert. instantiate führt aus oder startet eine laufende Instanz.


5. TypeSubjects und Ring-0-Facts

Refinements wirken auf TypeSubjects. Ein TypeSubject ist jedes compile-time adressierbare Subjekt des Typsystems:

Primitive
Struct
Enum
Union
Function
Protocol
Blueprint
DescriptorSubject

Davon getrennt sind Ring-0-Facts. Ring-0-Facts primitiver VM-Typen sind axiomatisch und nicht refinable:

type i32 : primitive {
    size:   4
    align:  4
    memory: Value
    class:  SignedInteger
}

TypeFns dürfen diese Facts lesen, aber nicht überschreiben.

Zulässig:

i32 :> Derive([Inspectable])

Nicht zulässig:

i32 :> Memory(Ref)

Der Operator :> bleibt einheitlich. Die TypeFn entscheidet anhand des Subject-Kinds und der Ring-Facts, ob ein Refinement zulässig ist.


6. Blueprint-Refinements

Blueprints sind die primäre Zielkategorie für runtime-orchestrierende Refinements:

type ApiService : blueprint {
    routes: RouteSpec
    db:     DbPoolSpec
} :> Timeout(5.seconds) :> Metrics(enabled: true)

Solche Refinements konfigurieren Engine-, Scheduler- oder Lifecycle-Verhalten. Sie verändern keine Ring-0-Facts und keine primitive VM-Semantik.

Structs und Primitive können weiterhin kompatible Daten-/Typ-Refinements tragen, etwa Memory, Own, Share, Drop, Derive, Operator oder FFI-Descriptor-Informationen.


7. run()

run() ist die Aktivierungsoperation für Runtime-Engines:

run(spec, engine):
    1. Subject normalisieren
    2. materialisierte Refinement-/Meta-Descriptoren lesen
    3. Engine-Kompatibilität prüfen
    4. EngineDescriptor erzeugen
    5. SchedulerConfig aus Engine-Defaults + committed Refinements mergen
    6. CapabilitySet prüfen
    7. Middleware-Chain aus MetaConsumer-Provides bauen
    8. Descriptor materialisieren
    9. engine.instantiate(descriptor) durch Middleware-Chain
   10. Handle zurückgeben

Die Engine berührt den Scheduler nicht direkt. Der Scheduler konsumiert nur EngineRuntimeConfig.


8. FFI

FFI folgt derselben Descriptor-Grenze:

NativeLayer      rohe ABI-/Symbolbeschreibung
BindingLayer     Ownership, Marshaling, Error-Mapping, Callback-Regeln
ServiceLayer     idiomatische JDL-Vertragsoberfläche

Die JadeValue Bridge bleibt Ring 0. Sie führt mechanisch aus. FFI-Semantik entsteht in Ring 1 über Native-/Binding-/Service-Blueprints und daraus erzeugte Descriptoren.

Effects referenzieren Services, nicht native Symbole.


9. Bootstrapping

Stage 1 JDL ist ein Seed-Dialekt, kein vollständiges JDL. Der D-Bootstrapper darf ihn direkt tokenisieren und in CompilerDB-Seed-Records übersetzen.

Stage 1 Seeds enthalten:

  • primitive VM-Typen und Ring-0-Facts,
  • Intrinsic-IDs und Signaturen,
  • minimale Core-Protocols,
  • Seed-TypeDescriptoren,
  • Bootstrap-Module,
  • minimale Descriptor-Schemata.

Stage 2 lädt Ring-1-JDL-Engines und erzeugt daraus vollständige Parser-, Type-, Dispatch- und Generator-Descriptoren.

Stage 3 macht den JDL-Compiler zum Normalpfad. Der D-Bootstrap bleibt Trust Anchor und Recovery Path.


10. Normative Invarianten

  1. Ring-0-Domänen besitzen ihren Zustand selbst.
  2. Ring-1-Engines erzeugen Descriptoren, aber besitzen keine Ring-0-Subsystemzustände.
  3. Ring-0-Facts primitiver VM-Typen sind axiomatisch und nicht refinable.
  4. Refinements wirken auf kompatible TypeSubjects; runtime-orchestrierende Refinements nur auf Blueprint-/Engine-Subjects.
  5. Descriptoren sind der stabile Vertrag zwischen JDL-Semantik und Ring-0-Mechanik.
  6. Effects referenzieren Services, nicht native Symbole oder Intrinsic-Endpunkte.
  7. Die JadeValue Bridge bleibt Ring 0 und interpretiert keine JDL-Domänenlogik.
  8. Der Scheduler kennt engineId und EngineRuntimeConfig, nicht die semantische EngineDefinition.
  9. TypeFns werden in einem TypeFnContext evaluiert und erzeugen Patches; sie mutieren keine CompilerDB-Tabellen direkt.
  10. Stage 1 ist Seed-Dialekt, nicht fast-vollständiges JDL.
  11. D ist Substrate und Trust Anchor; JDL ist Semantik und Evolution Layer.