Zum Inhalt

Jade/JDL: Lokale Syntaxerweiterungen, Entzuckerung und CompilerDB

Arbeitsnotiz · 17. September 2026 · nicht normativ
Gegenstand: Wie eine zusätzliche Oberflächenform wie do in JDL erkannt, übersetzt, typgeprüft und in der CompilerDB verwaltet werden könnte.
Leseregel: [D] = in den herangezogenen Projektunterlagen dokumentierte Entscheidung; [E] = in der Gesprächszusammenfassung als Nutzerentscheidung markiert; [V] = hier ausgearbeiteter Vorschlag; [O] = noch offen. Jeder Codeblock mit neuen API-Namen ist eine Skizze, kein kompilierbarer JDL-Code.

0. Das Bild in 30 Sekunden

Ein Paket kann eine neue Schreibweise anbieten, ohne neue VM-Befehle oder einen zweiten Typprüfer einzuführen. Dafür braucht es mindestens zwei getrennte Teile: Eine Grammatik macht den Ausdruck für den Parser erkennbar; eine Übersetzung ersetzt ihn durch bereits ausdrückbares JDL. Anschließend entsteht daraus die gemeinsame strukturierte Kernform. Die CompilerDB verwaltet diese Schritte als abhängige Query-Ergebnisse.

Auswahl der aktiven Syntaxpakete (vor dem Parsen)
        │
        ▼
Grammar-Blueprint → Grammar-/Parser-Descriptor
        │
        ▼
JDL-Quelltext → Parser → Oberflächen-AST / internes DoSyntax
        │
        ▼
Syntaxübersetzung: do → normales JDL (z. B. verschachtelte match)
        │
        ▼
Entzuckerung in die strukturierte Kernform
        │
        ▼
Typprüfung · Rows · Muster-/Move-Analyse · Drops
        │
        ├── Semantic Views / Beweise / Labels
        └── IR-Builder → IR → Verifier → Ausführung

CompilerDB: beantwortet Queries, verfolgt Reads,
            cached Ergebnisse und hält ihre Provenance.

Wichtig: Die Grammatik ist Compile-Zeit-Konfiguration. Das spätere with im Programm ist Runtime-Ressourcenverwaltung. Dass do innerhalb eines with steht, aktiviert die Grammatik nicht.

1. Was schon feststeht und was nicht

Aussage Status Einordnung
Plugin-Syntaxerweiterungen sind Sugar; ihr Ergebnis muss als gewöhnliches JDL ausdrückbar sein und dessen Prüfungen durchlaufen. [D] Plugin-Spec §10, Regel P-1
Grammatik wird über Blueprint, Meta/Materialisierung und Grammar-/Parser-Descriptor dem Parser zugänglich. [D] Plugin-Spec §10.1
Frontend-Provider sind von bloßen Datenformat-Parsern getrennt. [D] Plugin-Spec §9.4
Provider-Auswahl ist eindeutig; Änderungen an aktiven Providern müssen CompilerDB-Inputs/Invalidierung beeinflussen. [D] Plugin-Spec §9.3
Der Parser kann eine Query direkt mit einem AST beantworten; dafür braucht es keinen DescriptorStore-Commit. [D] „Wie Jade übersetzt“, §3
Oberflächenkonstrukte sollen in eine kleine, geschlossene strukturierte Kernform entzuckern; Views und IR stammen aus derselben getypten Kernform. [V] Gesprächszusammenfassung §9.2, noch nicht die alte Plugin-Spec
with ist ein eigener Körper; ret darin verlässt den with-Körper. [E] Gesprächszusammenfassung §10.1
Konkrete GrammarSpec-/SyntaxBuilder-API, do-Syntax, lokale Aktivierung, db.coreForm(...). [O]/[V] Beispiele dieses Dokuments, nicht festgelegt

Die Naht zwischen zwei Dokumentständen: Die bestehende Plugin-Spec verlangt ausdrückbares JDL als Ergebnis. Die neue Kernform-Idee aus §9.2 skizziert, dass ein Konstrukt selbst zur Kernform übersetzt. Der konservative, heute widerspruchsarme Weg ist deshalb: Erweiterung → normales JDL → Kernform. Ein direkter Weg Erweiterung → CoreExpr müsste explizit als gleichwertiger Frontend-Vertrag entschieden und in der Plugin-Spec nachgezogen werden.

2. Drei verschiedene Bedeutungen von „AST bauen“

  1. Parser: erkennt Token gemäß Grammatik und erzeugt einen Oberflächenbaum, beispielsweise DoSyntax. Das ist noch keine Laufzeitsemantik.
  2. Syntaxübersetzer: baut aus diesem Baum einen gewöhnlichen JDL-Baum. Beispiel: aus einem do-Bindungsschritt wird ein match auf Result.
  3. Kernform-Entzuckerer: baut aus gewöhnlichem JDL die kleine strukturierte Kernform (Match, Bindung, Aufruf, Pflicht, Installieren usw.). Danach arbeiten gemeinsame Analysen und der IR-Builder damit.

Ein Builder hilft beim Zusammenbauen von Knoten. Er ersetzt weder den Parser noch die Prüfung, ob die Umformung die beabsichtigte Bedeutung bewahrt. Insbesondere kann ein Parser keine unbekannte do { ... }-Form an einen Entzuckerer weiterreichen, wenn er sie vorher nicht erkannt hat.

3. Durchgehendes Beispiel: Result-basierte do-Notation in with

3.1 Angenommene Benutzeroberfläche [V]

Die folgenden Session-Methoden, Fehler- und Profiltypen sind Beispiel-APIs. Die do-Schreibweise ist ein hypothetisches Syntaxpaket. Hier ist Result[T,E] ein Werttyp, nicht automatisch Throw[E].

// Spekulative JDL-Oberfläche
val result := with Db.session() as session {
    val answer := do Result[Profile, DbError] {
        val user    <- session.findUser(id);
        val profile <- session.loadProfile(user);
        Ok(profile)
    }

    ret answer
}

Lesart von val name <- expression: Werte expression einmal aus; bei Ok(value) binde name = value und setze fort; bei Err(error) beende die do-Berechnung mit Err(error). Der Schlussausdruck liefert das letzte Result. Das genaue Token <-, die Semikolons und do Result[...] sind nicht normiert.

3.2 Was die Erweiterung erzeugen soll

// Semantisch entsprechende gewöhnliche JDL-Form; ebenfalls schematische Syntax
val result := with Db.session() as session {
    val answer := match session.findUser(id) {
        Err(val error) =>
            Err(error)

        Ok(val user) =>
            match session.loadProfile(user) {
                Err(val error) =>
                    Err(error)

                Ok(val profile) =>
                    Ok(profile)
            }
    }

    ret answer
}

Hier gilt:

  • findUser(id) wird genau einmal ausgewertet. loadProfile(user) läuft nur bei Ok(user).
  • Ein Err wird als Wert aus der do-Berechnung zurückgegeben. Er verlässt weder die Funktion noch eigenmächtig das with.
  • Das with liefert answer mittels ret answer; erst danach verlässt der Wert die Session-Grenze, und die normale Ressourcenpflicht wird erfüllt.
  • Wenn der Rückgabewert regionengebundene oder identitätstragende Bestandteile enthält, gelten die gewöhnlichen Prüfungen und Transferregeln des with. do umgeht nichts davon.
  • Wir nehmen für dieses Beispiel an, dass findUser/loadProfile tatsächlich Result[..., DbError] zurückgeben. Wer stattdessen Throw[DbError] auslöst, wird von einem Result-do nicht automatisch abgefangen. Dazu bräuchte es einen ausdrücklich definierten anderen Vertrag.

3.3 Was ausdrücklich nicht dasselbe ist

with Db.session() verwaltet Erwerb, Installation/Bereitstellung der Ressource und release. do Result[...] definiert eine Verkettungsregel über Result-Werte. Eine bloße Ressource kann nicht automatisch festlegen, ob do Result, Option, einen Generator oder eine andere Abstraktion meint. Die Bindungsstrategie muss explizit bestimmt und typgeprüft werden. Eine spätere ressourcenspezifische do-Variante wäre ein zusätzlicher Vertrag.

4. Wie der Maintainer die Grammatik beschreiben könnte

Die Plugin-Spec nennt einen Grammar-Blueprint, legt aber keine konkrete EBNF- oder JDL-API dafür fest. Das folgende ist eine erfundene, rein deklarative API zur Illustration:

// API-SKIZZE: GrammarSpec, Sequence, Repeat usw. sind Platzhalter.
def resultDoGrammar() ->Meta{} GrammarSpec {
    ret GrammarSpec {
        id: "example::result-do/1",
        entry: .Expression,
        trigger: "do",

        form: .Sequence([
            .Token("do"),
            .TypeExpr(capture: "resultType"),
            .Token("{"),
            .Repeat(
                .Sequence([
                    .Token("val"),
                    .Pattern(capture: "binding"),
                    .Token("<-"),
                    .Expr(capture: "source"),
                    .Token(";")
                ]),
                capture: "steps"
            ),
            .Expr(capture: "last"),
            .Token("}")
        ]),

        output: .DoSyntax
    }
}

Rolle der Platzhalter: .TypeExpr, .Pattern und .Expr sollen an bestehende JDL-Grammatik delegieren, nicht noch einmal Typen, Muster und Ausdrücke erfinden. .Token(";") ist hier nur eine einfache Abgrenzung für den Entwurf. Die Grammatik muss eindeutig unterscheiden, wo die Liste der Bindungsschritte endet und der Schlussausdruck beginnt. Die Zeichenfolge <- muss vom Lexer außerdem als passendes Token geliefert werden können; falls der Lexer das nicht hergibt, reicht eine Parser-Regel nicht.

Mögliches internes Parser-Ergebnis:

DoSyntax
├─ resultType: Result[Profile, DbError]
├─ steps
│  ├─ Bind(user,    session.findUser(id))
│  └─ Bind(profile, session.loadProfile(user))
└─ last: Ok(profile)

DoSyntax ist ein kurzlebiger Oberflächenknoten, kein vierzehnter Kernformknoten. Für v0.1 muss das Frontend daraus anschließend ausdrückbares JDL gewinnen. Herkunft/Quellspannen sind an jeder Umschreibung mitzunehmen; die konkrete Provenance-Form ist in der Plugin-Spec offen.

Warum ein Grammar-Blueprint statt eigenem Parser?

Der Maintainer soll festlegen, welche Form erkannt wird; ein gemeinsamer Parser verarbeitet die bereits bekannten Untergrammatiken. Sonst müsste jeder Syntaxautor selbst Klammerung, Fehlermeldungen, Namensräume und JDL-Ausdrücke nachbauen. Ein Plugin mit einem allgemeinen Datenparser für JSON/Markdown erhält dadurch noch keine Autorität, JDL-Quelltext zu verändern.

5. Wie die Syntaxübersetzung in JDL aussehen könnte

Wichtige Korrektur gegenüber frühen Skizzen: Core.Match { ... } als Wertkonstruktion und SyntaxBuilder als Meta-Service sind zwei verschiedene Ideen. Wenn ein Builder frische, hygienische Bindungsidentitäten oder kontrollierte Ausgabeknoten bereitstellt, muss sein Service in der Meta-Row stehen. Dann dürfen nicht im Funktionsrumpf plötzlich globale core.*-Aufrufe auftauchen.

Ein Bindungsschritt ließe sich schematisch so expandieren:

// API-SKIZZE; SyntaxExpr statt CoreExpr: P-1-konservativer Weg.
def expandStep(
    step: DoBindSyntax,
    rest: SyntaxExpr
) ->Meta{SyntaxBuilder} SyntaxExpr {
    val error := SyntaxBuilder.newBinding(step.origin)

    ret SyntaxBuilder.match(
        subject: step.source,
        arms: [
            SyntaxBuilder.arm(
                pattern: SyntaxBuilder.errPattern(error),
                body: SyntaxBuilder.errValue(error)
            ),
            SyntaxBuilder.arm(
                pattern: SyntaxBuilder.okPattern(step.binding),
                body: rest
            )
        ],
        origin: step.origin
    )
}

Die Funktion beschreibt eine Umformung, sie führt session.findUser(...) nicht zur Compile-Zeit aus. step.source ist Syntax; eine ausgewertete Session existiert in der Meta-Phase nicht. Der Übersetzer nimmt den Schlussausdruck als Start und verarbeitet die Bindungsschritte von hinten nach vorne:

last = Ok(profile)

voriger Schritt:
match session.loadProfile(user) {
    Err(e)  => Err(e)
    Ok(profile) => last
}

noch ein Schritt davor:
match session.findUser(id) {
    Err(e)  => Err(e)
    Ok(user) => [obiges match]
}

Eine echte API müsste zusätzlich garantieren, dass step.binding hygienisch eingebunden, error stabil eindeutig und die Quellzuordnung für jeden erzeugten Arm erhalten bleibt. Reine Datenkonstruktoren brauchen keinen Service. SyntaxBuilder lohnt als Service nur, wenn er tatsächlich Kontextzustand/Autorität bereitstellt; sonst wäre die Row bloß dekorativ.

6. Wie Grammatik und Übersetzer zusammenkommen

Die Form eines Pakets könnte sinngemäß so beschrieben werden:

// API-SKIZZE: Felder und Typen sind NICHT normiert.
type ResultDoExtension : blueprint {
    grammar: GrammarSpec = resultDoGrammar()
    expansion: SyntaxExpansion = SyntaxExpansion {
        input: .DoSyntax,
        transform: expandResultDo
    }
}

Das ist eine Angebotsbeschreibung, keine Installation. provide definiert Provider-/Implementierungsbeiträge; provide allein aktiviert oder installiert nichts. Ein zuständiger Compiler-Context müsste das Paket vor dem Parsen auswählen und den Parser-Descriptor registriert verfügbar machen. Die konkrete Syntax für diesen Installationsschritt ist offen.

Ein vernünftiger erster Aktivierungsbereich wäre ein Modul oder ein ausdrücklich abgegrenzter Quellbereich. Eine mögliche, noch nicht beschlossene Mechanik ist ein mit der Grundgrammatik lesbarer Modulkopf oder eine externe Build-/Context-Konfiguration, die vor dem ersten Parse die aktive Grammatikmenge festlegt. Eine beliebige Anweisung im bereits zu parsenden Rumpf kann nicht rückwirkend bestimmen, wie ihr eigener Text geparst wird: Das wäre der Bootstrap-Zirkel.

Daraus folgen Anforderungen an die Auswahl:

  • Eindeutigkeit: Zwei Pakete dürfen dieselbe Form nicht ohne definierte Disambiguierung beanspruchen. Eine Reihenfolge „wer zuerst registriert wurde, gewinnt“ ist keine belastbare Semantik.
  • Eindeutige Identität/Version: Parser-/Grammar-Descriptor und Transformationsbeitrag müssen stabil identifizierbar sein; die Namen im Beispiel sind nur illustrative Strings.
  • Lexing und Präzedenz: Neue Tokens, Einleitung do, Blockgrenzen, Interaktion mit bestehender Ausdruckspräzedenz und fremden Erweiterungen brauchen einen eigenen Vertrag.
  • Scopes: Ob ein lokaler Import eine Grammatik aktivieren darf, ist nicht entschieden. Ein normaler import von JDL-Namen und die Installation eines Compiler-Frontend-Providers sind nicht dasselbe.

7. Wie das Ergebnis in die CompilerDB gelangt

Die CompilerDB soll die Frage beantworten, nicht dem Entzuckerer Schreibrecht auf ihre Tabellen geben. Die folgenden Query-Namen sind illustrative neue Namen, nicht aus der bestehenden db-Fassade übernommen:

parse(moduleRevision, activeGrammarSet) -> SurfaceAst
expand(surfaceNode, activeSyntaxProviderSet) -> OrdinaryJdlAst
coreForm(ordinaryJdlNode) -> CoreExpr
check(coreForm) -> TypedCoreExpr
views(typedCore) -> SemanticViews
lower(typedCore) -> IR

Für die Implementierung können Schritte zusammengefasst oder anders granuliert werden. Die Trennung bezeichnet zunächst Verantwortlichkeiten; ob eine Query pro Modul, Funktion oder Ausdruck läuft, ist eine eigene Performance-/Identitätsfrage.

Query: „Kernform der Funktion F?“
   │
   ├─ liest Quellrevision             → DepGraph-Kante
   ├─ liest aktive Grammar-Descriptoren → DepGraph-Kante
   ├─ liest aktiven Übersetzer/Provider → DepGraph-Kante
   ├─ liest AST-/Expansion-Queries    → DepGraph-Kanten
   └─ liefert CoreExpr
       ├─ QueryResult → Cache
       └─ DerivationRecord → ProvenanceStore

Nicht verwechseln:

Komponente Zuständigkeit Beispiel bei do
Grammar-/Parser-Descriptor kanonisch materialisierte Grammatik-/Parserbeschreibung Was do syntaktisch erkennt
Query-Cache verwerfbares Ergebnis einer beantworteten Query Geparster AST, Expansion, Kernform
DepGraph aus tatsächlich gelesenen Inputs/Queries abgeleitete Invalidierung do-Paket oder Quelldatei hat sich geändert
ProvenanceStore warum diese Antwort in dieser Revision entstand Welche Provider- und Quellableitung beteiligt war
DescriptorStore kanonische Deskriptoren; nur Materializer schreibt Grammar-Descriptor, nicht automatisch jeder AST/Kernform-Baum

Eine AST- oder Kernform-Query kann direkt Resolved(value) liefern, ohne PatchSet und ohne Materializer. Den Cache beschreibt die Query-Ausführung nach ihrem terminalen Ausgang, nicht der Provider. DepGraph-Kanten entstehen durch Queries/Inputs, die der Provider tatsächlich liest, nicht durch handgeschriebene Abhängigkeitslisten.

Invalidierung bei Plugin-Wechsel: Selbst unveränderter JDL-Quelltext kann anders geparst werden, wenn sich aktive Grammatik oder Transformationsprovider ändern. Deshalb muss die Provider-Auswahl selbst ein sichtbarer CompilerDB-Input sein. Eine Registry-Änderung außerhalb des Query-Modells mit anschließendem Cache-Hit wäre falsch.

Die Meta-Row dabei

// API-SKIZZEN, kein normierter Query-Name
def expandResultDo(node: DoSyntax)
    ->Meta{SyntaxBuilder} SyntaxExpr {
    // Konstruktion über den deklarierten SyntaxBuilder-Service
}

SyntaxBuilder bezeichnet eine Compile-Zeit-Anforderung. Er ist nicht Teil der Runtime-Effect-Row des späteren findUser-Programms. Falls ein Entzuckerer andere Compilerinformationen benötigt, müsste er dafür ausschließlich die freigegebene Meta-/CompilerDB-Lesesicht verwenden, damit Reads im DepGraph erscheinen. Die konkrete db.coreForm(...)-API steht noch nicht im dokumentierten db-Katalog.

8. Warum die Kernform danach wichtig bleibt

Der Grund für die neue Kernform-Idee ist nicht bloß „weniger AST-Knoten“: Würden Semantic Views den Oberflächen-AST anders interpretieren als der IR-Builder, könnte ein Beweis über anderen Code gelten als den tatsächlich ausgeführten. Die gemeinsame getypte Kernform soll diese Abweichung beseitigen.

gewöhnliches JDL
  ↓
strukturierte Kernform: Match · Bindung · Aufruf · Block · ...
  ↓ Typprüfung / Move / Drop
getypte Kernform
  ├─ Views / Labels / Proofs
  └─ IR-Builder → Verifier

Die in der Gesprächszusammenfassung vorgeschlagenen 13 Kernknoten sind [V] und bilden keine beschlossene öffentliche Builder-API. Plugins dürfen damit jedenfalls keine neuen unprüfbaren Kernknoten oder ein eigenes Ausnahmesystem einschmuggeln. Ob Plugin-Frontendbeiträge künftig direkt CoreExpr liefern dürfen, ist ausdrücklich mit der bestehenden P-1-Regel zu harmonisieren.

9. Fehlerquellen und Mindesttests

Fehler Was Jade bzw. der Maintainer prüfen muss
Ausdruck zweimal ausgewertet Nebenwirkung im linken do-Schritt; exakt ein Aufruf
Err als Throw behandelt Err muss Result-Wert bleiben; eigener Test mit äußerem with
Cleanup übersprungen with-Ressource wird auch bei frühem Err regulär freigegeben
Namen kollidieren generierte interne Namen sind hygienische Bindungs-IDs, keine Strings wie __tmp1
Typen passen nicht beide Zweige ergeben dasselbe Result[T,E]; Fehler- und Werttypen müssen passen
Quellspannen gehen verloren Diagnostik zeigt auf ursprüngliches do und den problematischen Bindungsschritt
Lexer/Parser uneindeutig Tests mit verschachteltem do, match, Klammern und mehreren aktivierten Paketen
Cache wird stale Austausch/Deaktivierung des Syntaxproviders invalidiert abhängige Parse-/Expansionsergebnisse
Effekt- oder Scope-Grenze verschwindet typisierte Kernform und Verifier kontrollieren Rows, Moves, Unwind, Ressourcenpflichten
Benutzerabsicht ≠ tatsächliche Expansion Semantik-Tests auf Oberflächen- und ausgeschriebener JDL-Form; ein Verifier beweist nicht die Absicht des Plugin-Autors

Die wichtigste Grenze: Ein Verifier kann Sicherheit der erzeugten Repräsentation kontrollieren, aber nicht erraten, was der Maintainer mit do ursprünglich gemeint hat. Dafür braucht es präzise Expansionsregeln, Tests und nachvollziehbare Diagnostik.

10. Offene Entscheidungen, bevor daraus eine Spec wird

  1. Frontend-Vertrag: muss ein Plugin ausdrückbares JDL liefern, oder ist ein direktes, überprüfbares CoreExpr künftig erlaubt?
  2. Grammatik-API: Schema des Grammar-Blueprints, Parser-Descriptor, Token-/Lexer-Erweiterung, Präzedenz, Fehlerdiagnostik.
  3. Lokale Aktivierung: Modul, Block oder Projekt? Woher kennt der Parser die Auswahl vor dem Parse? Wie werden konkurrierende Grammatiken aufgelöst?
  4. Query-Oberfläche: exakte Query-Namen, Granularität, Schlüssel, Schema-/Provider-Versionen, Provenance und Invalidierung.
  5. Builder-Modell: reine Wertkonstruktoren vs. autorisierter SyntaxBuilder als Meta-Service; stabile hygienische IDs, erlaubte Konstruktionen.
  6. do-Vertrag: Result-only, generisch über ein Protokoll oder ressourcenspezifisch? Welche Schlussform, welche Typerwartungen, welche Begrenzer und welche Result-Fehlertypen?
  7. Scope/Control-Flow: Ist do selbst ein Körper? Diese Skizze behandelt es als Ausdruck, nicht als neues ret-Ziel. with bleibt Körper.
  8. Sicherheits-/Kompatibilitätsregel: Wer validiert Expansionsausgaben und wie sind alte Artefakte gegen Änderungen der Grammar-/Provider-Version geschützt?

Die Fragen sind nicht durch die Codebeispiele entschieden. Insbesondere sollte der Entwurf nicht implizit eine neue universelle do-Semantik festschreiben, nur weil Result ein gutes Anschauungsbeispiel ist.

11. Mini-Glossar für später

  • Syntaxpaket: angebotener Compilerbeitrag für eine zusätzliche Schreibweise.
  • Grammar-Blueprint: deklarative Beschreibung dessen, was der Parser erkennen soll.
  • Parser-Descriptor: materialisiertes, versionierbares Ergebnis der Grammatikbeschreibung.
  • Oberflächen-AST / DoSyntax: erkannte Quellstruktur vor der Bedeutungstransformation.
  • Syntaxübersetzung/Expansion: DoSyntax → normales JDL (match auf Result).
  • Entzuckerung: gewöhnliches JDL → kleine strukturierte Kernform.
  • Kernform: gemeinsame semantische Grundlage für Analysen/Views und IR-Erzeugung; nicht Core-Bytecode.
  • SyntaxBuilder: hier nur ein vorgeschlagener Meta-Service zur kontrollierten Knoten-/Identitätserzeugung.
  • Meta-Row: Anforderungen des gerade übersetzenden Meta-Codes; nicht die Effekt-Row des übersetzten Runtime-Codes.
  • CompilerDB-Query: beantwortete Ableitung mit erfassten Reads; kein freier Schreibzugriff auf Stores.
  • with: Runtime-Ressourcenkörper mit eigener Rückgabe und normaler Cleanup-Semantik.
  • do Result: hier vorgeschlagener Sugar für die Verkettung von Result-Werten.

12. Nachschlagen und Quellenstand

Basis sind Projektdateien und die vom 17.09.2026 bereitgestellte Gesprächsnotiz, nicht eine neu verbindlich gemachte Online-Spezifikation:

  • spec-plugin-system(1).md: §§9.3–9.4, 10–10.3 (Query-/Frontendprovider, Syntax als Sugar, Grammar-Blueprint, Provenance); die Gesprächsnotiz nennt Plugin-Spec v0.3.7 vom 16.09.2026.
  • wie-jade-uebersetzt(20260912-122653).md: §3 (Cache, DescriptorStore, ProvenanceStore, DepGraph/Query-Lesen), §6.4 (db-Lesefassade).
  • spec-namespaces-und-module(3).md: §§8.3–8.4 (lokale Imports sind möglich; Services werden nicht importiert, sondern über Rows angefordert).
  • jade-gespraech-2026-09-17.md: §§9.1–9.4 (Kernform als Vorschlag), 10.1–10.3 (with und Kontrollfluss), 12 (provide ist keine Installation), 14 (offene Syntaxanmeldung).
  • Öffentlicher Einstieg: https://specs.iowling.at/. Ältere Online-Stände nicht automatisch über aktuelle Projektunterlagen stellen.

Merksatz: Grammatik erkennt. Expansion macht ausdrückbares JDL daraus. Die Kernform vereinheitlicht die Semantik. Die CompilerDB merkt sich die Ableitung. Der Verifier prüft die sicherheitsrelevante Ausführung.