Jade Compiler — CompilerDB & Query/Provider-System¶
Status: Normativ
Version: 0.7.0
Scope: CompilerDB-Substrate, Stage-1-Bootstrap, Ring-1-Engine-Provider, Query-System, Descriptor-Materialisierung
Priorität: Bei Widerspruch mit anderen Dokumenten gilt diese Spec für CompilerDB-Interna.
Inhaltsverzeichnis¶
- Motivation und Designziele
- Architekturformel
- Kernkonzepte
- Query — Definition und Anatomie
- Provider-Modell
- CompilerDB — Struktur und Zuständigkeit
- Query-Auswertung
- Descriptoren, Seeds und Materialisierung
db.*— Meta-Fassade- Dependency-Tracking
- Lazy Revalidierung und Early Cutoff
- Durability
- Cancellation
- Arena-Integration
- Fehlerbehandlung und Diagnostics
- Compiler-Pipeline und Engines
- Tools und Consumer
- Query-Katalog
- Erweiterung — neue Queries und Provider
- Normative Invarianten
- Implementierungshinweise
1. Motivation und Designziele¶
1.1 Das Problem¶
Ein Compiler besteht aus mehreren Compile-Time-Domänen: Source, Syntax, Name-Resolution, Typen, Meta-Records, Layouts, Dispatch, Effekte, IR, Artefakte und Diagnostics. Diese Domänen benötigen Informationen voneinander. Ohne ein strukturiertes Query-System entstehen die üblichen Freuden technischer Verwahrlosung:
- direkte Kopplungen zwischen Phasen,
- unklare Zuständigkeiten,
- keine saubere Inkrementalität,
- widersprüchliche Cache-Strategien,
- schwer testbare Spezialpfade,
- Ring-0-Hostlogik, die sich schleichend in JDL-Semantik verwandelt.
Die alte Sicht lautete: Parser, TypeEngine, Resolver und Generator sind Subsysteme, die direkt über Host-Handler Query-Ergebnisse bauen. Diese Sicht ist für Stage 1 nützlich, aber nicht mehr der normative Architekturkern.
Die neue Sicht lautet:
Die CompilerDB berechnet keine hohe JDL-Semantik. Sie verwaltet deterministische Compile-Time-Queries, Seeds, Descriptoren, Dependency-Tracking und Materialisierung. Semantik wird durch QueryProvider geliefert: im Bootstrap durch Zig, danach zunehmend durch Ring-1-JDL-Engines.
1.2 Die Lösung: Query/Provider-System¶
Alle Compile-Time-Kommunikation läuft über typisierte Queries:
Eine Query beschreibt, was bekannt sein soll. Ein Provider beschreibt, wie dieses Wissen für eine bestimmte Stage erzeugt wird.
Query = typisierte Anfrage
Provider = berechnet oder liefert das Ergebnis
CompilerDB = Cache, DepGraph, Seeds, DescriptorStore, Materializer
Descriptor = materialisiertes Compile-Time-Artefakt
Damit bleibt das Query-System stabil, auch wenn die Implementierung eines Providers von Zig nach JDL wandert.
1.3 Designziele¶
| Ziel | Beschreibung |
|---|---|
| Entkopplung | Phasen kennen Queries, nicht fremde interne Zustände. |
| Stage-Fähigkeit | Stage 1 nutzt Zig-BootstrapProvider; Stage 2+ nutzt Ring-1-EngineProvider. |
| Determinismus | Gleiche Inputs und gleiche Provider-Version erzeugen gleiche Query-Ergebnisse. |
| Inkrementalität | Änderungen revalidieren nur abhängige Query-Ergebnisse. |
| Descriptor-Zentralität | Type-, Layout-, Dispatch-, FFI- und Generator-Artefakte sind materialisierte Descriptoren. |
| Testbarkeit | Jede Query und jeder Provider ist isoliert testbar. |
| Debuggbarkeit | DepGraph, Provenance/Proof Trace und Materialisierungslog sind inspizierbar. |
| Ring-Grenzen | Zig bleibt Substrate; JDL-Engines erzeugen Semantik über Descriptoren. |
1.4 Philosophische Konsistenz¶
Die CompilerDB ist die Compile-Time-Entsprechung zum RuntimeBus:
CompilerDB -> Query -> Compile-Zeit, deterministisch, cachebar
RuntimeBus -> Command -> Laufzeit, zustandsändernd, nicht cachebar
Beide sind zentrale Substrate. Beide vermeiden direkte Fremdzugriffe und machen Zuständigkeiten sichtbar. Die zusätzliche Struktur ist Teil des Sicherheits- und Wartbarkeitsmodells.
2. Architekturformel¶
Zig / Ring 0 = Substrate + Trust Anchor
JDL / Ring 1 = Semantik + Evolution Layer
CompilerDB = Compile-Time Query/Descriptor-Substrate
RuntimeBus = Runtime Command-Substrate
Engine = JDL-seitige Auswertung und Descriptor-Erzeugung
Descriptor = materialisierter Vertrag zwischen Semantik und Maschine
Die CompilerDB besitzt keine hohe JDL-Domänenlogik. Sie verwaltet:
- QueryKeys,
- QueryResults,
- Provider-Registrierung,
- Dependency-Graph,
- Revisionen,
- Seeds,
- Descriptoren,
- Materialisierungspatches,
- Diagnostics,
- Proof-Traces,
- Arenen und Cache-Lebenszeiten.
Die CompilerDB darf Stage-1-Zig-Provider aufrufen. Ab Stage 2 darf sie auch EngineProvider aufrufen, deren Implementierung als JDL-Bytecode vorliegt. Der Wechsel des Providers darf die Query-Semantik nicht ändern, solange Query-Signatur, Eingaben und Descriptor-Schema gleich bleiben.
3. Kernkonzepte¶
3.1 Query¶
Eine Query ist eine typisierte, idempotente Anfrage an die CompilerDB. Sie beschreibt was man wissen will, nicht wie es berechnet wird.
Eigenschaften:
- deterministisch,
- cachebar,
- dependency-trackbar,
- ohne beobachtbare Seiteneffekte,
- durch genau einen aktiven Provider berechenbar.
3.2 Input Query¶
Input Queries werden von außen gesetzt. Sie haben keinen Provider.
struct FileContent { string path; } // -> string
struct BuildConfig { } // -> BuildConfigDescriptor
struct ModuleList { } // -> ModulePath[]
Schreiben erfolgt über setInput. Jede Änderung erhöht die Revision.
3.3 Derived Query¶
Derived Queries werden aus anderen Queries berechnet. Sie haben genau einen aktiven Provider.
struct GetFileAST { SourceFileId file; } // -> JadeResult!AstModule
struct ResolveType { TypeRef ref_; } // -> JadeResult!TypeDescriptor
struct GetMemoryLayout { TypeId id; } // -> JadeResult!LayoutDescriptor
3.4 Materialized Query¶
Eine Materialized Query liest ein bereits materialisiertes Descriptor- oder Seed-Artefakt.
struct GetTypeDescriptor { TypeId id; } // -> JadeResult!TypeDescriptor
struct GetRing0Facts { TypeId id; } // -> JadeResult!Ring0FactSet
struct GetDispatchTable { ProtocolId p; TypeId t; } // -> JadeResult!DispatchDescriptor
Materialized Queries werden nicht frei berechnet. Sie lesen aus dem DescriptorStore oder SeedStore. Materialisierung geschieht atomar über Patches.
3.5 QueryProvider¶
Ein QueryProvider berechnet oder liefert das Ergebnis einer Derived Query.
Provider-Arten:
BootstrapProvider Zig-Provider fuer Stage 1
EngineProvider Ring-1-JDL-Engine ab Stage 2
BuiltinProvider feste Ring-0-Facts, Intrinsic-Tabelle, primitive Seeds
GeneratedProvider aus bereits materialisierten Descriptoren abgeleitet
Die CompilerDB registriert Provider. Sie besitzt deren Semantik nicht.
3.6 SeedRecord¶
Ein SeedRecord ist ein Stage-1-Input mit axiomatischem Charakter.
Beispiele:
primitive VM-Typen
Ring-0-Facts
Intrinsic-IDs und Signaturen
Core-Protocols
minimale TypeDescriptoren
Bootstrap-Module
Descriptor-Schemata
Seeds sind die Brücke zwischen Zig-Bootstrap und Ring-1-JDL-Engines.
3.7 Descriptor¶
Ein Descriptor ist ein geprüftes, materialisiertes Compile-Time-Artefakt:
TypeDescriptor
LayoutDescriptor
LabelProfile
DispatchDescriptor
BindingTableDescriptor
FfiCallDescriptor
MarshalDescriptor
IrModule
LoweredModule
Proto
VmModuleArtifact
EngineDescriptor
Descriptoren sind kein Kommentar zum Build. Sie sind der Vertrag, den spätere Phasen und Ring-0-Domänen konsumieren.
3.8 MaterializationPatch¶
Compile-Zeit-Funktionen und Engines schreiben nicht direkt in beliebige CompilerDB-Tabellen. Sie erzeugen Patches:
Der Materializer validiert und committed diese Patches atomar. Dadurch bleiben Cache, DepGraph und Provenance konsistent.
3.9 Semantic View¶
Eine Semantic View ist keine eigene CompilerDB-Kategorie. Sie ist ein Nutzungsmuster einer gewöhnlichen Derived Query, deren Ergebnis ein Compiler-Subject entlang einer wiederverwendbaren Analyseachse projiziert.
Beispiele, Namen nicht als öffentliche API normiert:
GetControlFlowView(FunctionSubject) -> ControlFlowView
GetCallView(FunctionSubject) -> CallView
GetEffectView(FunctionSubject) -> EffectView
GetProgressView(LoopSubject) -> ProgressView
Eine View:
- ist deterministisch, cachebar und dependency-tracked wie jede Derived Query;
- muss kein Descriptor sein;
- wird nur bei Bedarf berechnet;
- kann im Bootstrap durch Ring 0 und später durch JDL-Semantik erzeugt werden;
- beschreibt eine Analyseachse, nicht einen AST-Kind;
- wird von der CompilerDB inhaltlich nicht interpretiert.
Mehrere Sprachkonstrukte dürfen dieselbe View bedienen. Die konstrukt-spezifische Projektion geschieht innerhalb der JDL-Semantik des eindeutigen QueryProviders, nicht durch konkurrierende Provider für denselben Query-Vertrag.
Semantic Views führen insbesondere keine zweite ViewRegistry, keinen ViewId und keine eigene Result-Kategorie ein.
4. Query — Definition und Anatomie¶
4.1 Query-Struktur¶
Eine Query ist ein reiner Datensatz. Felder sind Parameter. Methoden gehören nicht in die Query.
4.2 QueryKey¶
Jede Query hat einen stabilen Cache-Schlüssel:
Normativ:
- identische Query-Parameter erzeugen denselben QueryKey,
- Serialisierung ist kanonisch,
- Feldreihenfolge ist stabil,
- keine Host-spezifischen Pointerwerte im Key,
- Provider-Version und Stage-Profil sind Teil des effektiven Schlüsselraums, wenn sie das Ergebnis beeinflussen.
4.3 QueryResult¶
struct QueryResult {
ubyte[] data;
TypeTag tag;
ulong changedAt;
ulong verifiedAt;
Durability durability;
Hash contentHash;
Option[DerivationKey] provenance;
}
Semantik:
changedAt: Revision, in der sich der Inhalt zuletzt geändert hat.verifiedAt: Revision, in der das Ergebnis zuletzt revalidiert wurde.durability: höchste Änderungsfrequenz transitiver Inputs.contentHash: kanonischer Hash des Ergebnisses.provenance: optionaler Verweis auf denDerivationRecord, der diese neu ausgeführte Ableitung erklärt. Input-Queries und reine Cache-Hits erzeugen keinen neuen Provider-DerivationRecord.
4.4 Query-Ergebnisarten¶
Einzelwert-Queries verwenden JadeResult[T]:
Check-Queries geben DiagnosticSet oder Diagnostic[] zurück.
5. Provider-Modell¶
5.1 Grundregel¶
Für jede Derived Query gibt es pro Stage-Profil genau einen aktiven Provider.
Mehrere Provider für dieselbe Query sind nur zulässig, wenn die Auswahl durch Stage, Target, FeatureSet oder BuildProfile eindeutig ist.
5.2 BootstrapProvider¶
BootstrapProvider sind Zig-seitige Ring-0-Provider. Sie existieren, damit Stage 1 die CompilerDB überhaupt befüllen kann. Ihre konkrete Registrierungs-API ist Implementierungsdetail; normativ ist nur, dass sie denselben Query-Vertrag erfüllen wie spätere EngineProvider.
Eine hostseitige Registrierungsannotation oder Funktionssignatur ist nicht Teil des normativen Query-Modells.
5.3 EngineProvider¶
EngineProvider sind Ring-1-JDL-Engines, die eine Query beantworten.
Konzeptionell:
type ResolveTypeSpec : blueprint {
subject: TypeRef
}
provide DescriptorEngine[ResolveTypeSpec, TypeDescriptor] for TypeEngine {
def describe(spec: ResolveTypeSpec) -> Result[TypeDescriptor, DiagnosticSet] {
// liest CompilerDB-Queries, erzeugt Descriptor
}
}
Die CompilerDB ruft EngineProvider über eine VM-interne, deterministische Stage-2-Ausführung auf. Der Provider darf nur über die CompilerDB-Fassade lesen und Patches zurückgeben.
5.4 BuiltinProvider¶
BuiltinProvider liefern axiomatische Facts:
- primitive Ring-0-Facts,
- Intrinsic-Tabellen,
- Core-Opcode-Descriptoren,
- Bootstrap-Symbole.
Diese Facts sind lesbar, aber nicht durch Compile-Zeit-Funktionen überschreibbar.
5.5 GeneratedProvider¶
GeneratedProvider beantworten Queries aus materialisierten Descriptoren.
Beispiel:
Der Provider berechnet keine neue Semantik. Er projiziert vorhandene Descriptoren in eine Query-Antwort.
5.6 Provider-Reinheit¶
Provider müssen deterministisch sein. Für Derived Queries gilt:
- kein Dateisystemzugriff außer über Input Queries,
- kein Netzwerk,
- keine Uhrzeit,
- kein zufälliger Seed,
- keine RuntimeBus-Commands,
- keine direkte Mutation fremder Domänen.
Stage-1-Zig-Provider dürfen intern Zig-Strukturen nutzen, müssen aber nach außen denselben Query-Vertrag erfüllen wie spätere EngineProvider. Ja, auch wenn Ring 0 hier technisch mehr könnte. Das ist genau der Grund, es nicht zu tun.
5.7 View- und Proof-Provider¶
Für Semantic-View- und Proof-Queries gilt unverändert die Grundregel aus §5.1: pro Query-Vertrag und Stage-Profil existiert genau ein aktiver Provider.
Mehrere logische Beweisregeln sind daher keine konkurrierenden QueryProvider. Sie werden innerhalb der JDL-Implementierung des zuständigen Providers komponiert oder über eindeutig getrennte Unterqueries ausgedrückt. Dasselbe gilt für neue Sprachkonstrukte: Ein neues Konstrukt registriert nicht einen zweiten GetControlFlowView-Provider, sondern beteiligt sich über eine Ring-1-Semantikschnittstelle am eindeutigen View-Provider. Die konkrete JDL-Protokollform ist Sache der jeweiligen Fachspec.
Die Fähigkeit, einen QueryProvider zu registrieren, verleiht außerdem nicht automatisch die Autorität, sealed/core Sicherheitsurteile zu definieren oder zu ersetzen. Solche Proof-Verträge dürfen ihren zulässigen Provider-Geltungsbereich enger beschränken.
6. CompilerDB — Struktur und Zuständigkeit¶
6.1 Normative Struktur¶
Die CompilerDB besitzt keine direkten semantischen Subsystem-Pointer als normativen Bestandteil des Modells. Eine Implementierung darf interne Bootstrap-Objekte verwenden, aber sie sind Provider-Details, nicht CompilerDB-Semantik.
Normativ ist:
struct CompilerDb {
QueryCache cache;
DepGraph deps;
ProviderRegistry providers;
SeedStore seeds;
DescriptorStore descriptors;
Materializer materializer;
DiagnosticStore diagnostics;
ProvenanceStore provenance;
Arena keyArena;
Arena resultArena;
Arena depArena;
Arena provenanceArena;
ulong currentRevision;
ActiveQueryStack activeQueries;
DurabilityState durability;
Cancellation cancellation;
}
DescriptorStore und ProvenanceStore haben unterschiedliche Aufgaben. Der DescriptorStore hält kanonische, immutable Semantik. Der ProvenanceStore hält revisionsgebundene DerivationRecords über ausgeführte Ableitungen, einschließlich Reads, Ausgang und gegebenenfalls Materialisierung. Provenance ist nicht Teil des semantischen Descriptor-Hashes und darf nach Implementierungspolitik verdichtet oder verworfen werden. Eine gescheiterte Ableitung kann Provenance besitzen, obwohl kein Descriptor entstanden ist.
6.2 Zuständigkeit¶
Die CompilerDB darf:
- Inputs setzen,
- Queries auswerten,
- Provider auswählen,
- Ergebnisse cachen,
- Dependencies tracken,
- Descriptoren speichern,
- Patches materialisieren,
- Diagnostics sammeln,
- Proof-Traces referenzieren.
Die CompilerDB darf nicht:
- JDL-Domänenlogik hart kodieren,
- Ring-0-Facts überschreiben,
- RuntimeBus-Commands ausführen,
- Scheduler/JME/FFI-Zustand manipulieren,
- beliebige Mutation aus Compile-Zeit-Funktionen zulassen,
- Provider-internen Zustand als öffentliche API exponieren.
6.3 Input setzen¶
void setInput(Q, V)(CompilerDb* db, Q input, V value, Durability dur = Durability.Medium) {
auto key = makeKey(input, db.keyArena);
auto data = serializeCanonical(value, db.resultArena);
auto prev = db.cache.get(key);
bool changed = prev is null || !bytesEqual(prev.data, data);
db.cache.put(key, QueryResult {
data: data,
tag: TypeTag.of!V,
changedAt: changed ? db.currentRevision : prev.changedAt,
verifiedAt: db.currentRevision,
durability: dur,
contentHash: hash(data),
provenance: null
});
if (changed)
db.durability.markChanged(dur, db.currentRevision);
db.currentRevision++;
}
Eager-Invalidierung ist verboten. Revalidierung ist lazy.
7. Query-Auswertung¶
7.1 Algorithmus¶
T query(T, Q)(CompilerDb* db, Q q)
if (isQuery!Q)
{
auto key = makeKey(q, db.keyArena);
if (db.activeQueries.contains(key))
return handleCycle!T(db, q);
if (auto cached = db.cache.get(key)) {
if (cached.verifiedAt == db.currentRevision) {
trackDep(db, key);
return deserialize!T(cached.data);
}
if (canSkipRevalidation(db, key, cached)) {
cached.verifiedAt = db.currentRevision;
trackDep(db, key);
return deserialize!T(cached.data);
}
bool depsChanged = false;
foreach (dep; db.deps.dependenciesOf(key)) {
revalidate(db, dep);
auto depResult = db.cache.get(dep);
if (depResult !is null && depResult.changedAt > cached.verifiedAt) {
depsChanged = true;
break;
}
}
if (!depsChanged) {
cached.verifiedAt = db.currentRevision;
trackDep(db, key);
return deserialize!T(cached.data);
}
}
return recompute!T(db, q, key);
}
7.2 Neuberechnung¶
T recompute(T, Q)(CompilerDb* db, Q q, QueryKey key) {
auto prevActive = db.activeQueries.push(key);
db.deps.clearDependencies(key);
scope(exit) db.activeQueries.pop(prevActive);
checkCancellation(db);
auto provider = db.providers.resolve!Q(db.stageProfile);
auto result = provider.compute!T(q, db);
auto derivation = db.provenance.recordProvider(
key, provider, db.deps.dependenciesOf(key), result
);
auto data = serializeCanonical(result, db.resultArena);
auto cached = db.cache.get(key);
bool changed = cached is null || !bytesEqual(cached.data, data);
db.cache.put(key, QueryResult {
data: data,
tag: TypeTag.of!T,
changedAt: changed ? db.currentRevision : cached.changedAt,
verifiedAt: db.currentRevision,
durability: computeDurability(db, key),
contentHash: hash(data),
provenance: derivation
});
trackDep(db, key);
return result;
}
7.3 Zyklusbehandlung¶
Query-Zyklen sind Fehler. Zyklustolerante Derived Queries sind im aktuellen Modell nicht vorgesehen; semantische Fixpunkte werden als lokal begrenzte Provider-Berechnungen nach §7.4 formuliert. Jade vermeidet allgemeine globale Fixpoint-Berechnung im Meta- und Descriptor-Pfad.
Bei Zyklus:
liefert die CompilerDB ein strukturiertes Diagnostic mit Query-Trace.
7.4 Proof-Queries und lokale Closures¶
Proof-Queries sind normale Derived Queries. CompilerDB kennt die fachliche Bedeutung eines Proofs nicht. Ein Label-Query kann beispielsweise ein LabelJudgement liefern; ein Totalitätsquery darf eine andere Ergebnisform besitzen.
Begrifflich gilt:
Fact bereits bekannte semantische Information
Obligation zusätzlich nachzuweisende Aussage einer Fachregel
Proof nachvollziehbare Ableitung aus Facts und erfüllten Obligations
Ein semantischer Fixpunkt darf die Query-Zyklusregel nicht umgehen. Eine endliche Worklist oder SCC-Auswertung ist nur innerhalb einer einzelnen terminierenden Provider-Auswertung zulässig:
Provider
-> Ausgangsfakten über db.* lesen
-> lokale endliche Arbeitsdomäne aufbauen
-> Worklist / Fixpunkt berechnen
-> genau ein QueryResult publizieren
Nur externe db.*-Reads erzeugen CompilerDB-Dependency-Kanten. Temporäre Worklists und Faktentabellen sind Provider-Arbeitszustand, kein CompilerDB-Zustand. Ein Zyklus Q(A) -> Q(B) -> Q(A) bleibt dagegen ein CompilerDB-Fehler.
8. Descriptoren, Seeds und Materialisierung¶
8.1 SeedStore¶
Der SeedStore enthält axiomatische Stage-1-Einträge:
PrimitiveTypeSeed
Ring0FactSeed
IntrinsicSeed
CoreProtocolSeed
BootstrapModuleSeed
DescriptorSchemaSeed
Seeds gelten als Input-Queries mit hoher Durability.
8.2 DescriptorStore¶
Der DescriptorStore enthält materialisierte Compile-Time-Artefakte:
TypeDescriptor
LayoutDescriptor
MetaRecordDescriptor
ProvideDescriptor
DispatchDescriptor
FfiCallDescriptor
IrModule
LoweredModule
VmModuleArtifact
Descriptoren sind immutable nach Commit. Änderungen erzeugen neue Descriptor-Versionen oder neue Revisionen.
8.3 MaterializationPatch¶
Provider und Compile-Zeit-Funktionen erzeugen Patches:
type MaterializationPatch : enum =
| SetMeta { target: TypeSubject, field: str, value: Tag }
| AddType { desc: TypeDescriptor }
| AddProvide { desc: ProvideDescriptor }
| AddDispatch { desc: DispatchDescriptor }
| AddArtifact { desc: ArtifactDescriptor }
| AddDiagnostic { entry: DiagnosticEntry }
Der Materializer prüft:
- Ring-Level,
- Ring-0-Facts,
- TypeSubject-Kompatibilität,
- Descriptor-Schema,
- Coherence-Regeln,
- Provider-Berechtigung,
- Konflikte mit bestehender Materialisierung.
Erst danach wird committed.
8.4 Kein Direkt-Schreiben aus Compile-Zeit-Funktionen¶
db.setMeta(...) in Compile-Zeit-Funktionen ist syntaktische Fassade. Semantisch erzeugt es einen MetaPatch. Der Patch wird nach erfolgreicher Meta-Auswertung atomar materialisiert.
Dadurch bleiben Diagnostics, Rollback, Caching und Provenance konsistent. Direkte Mutation ist verboten, weil sie partielle Compilerzustände erzeugen könnte.
8.5 MetaContext und ApplyRefinement¶
Compile-Zeit-Funktionen werden nicht mit rohem CompilerDB-Zugriff ausgeführt. Jeder Meta-Aufruf erhält intern einen MetaContext:
// kanonische Struktur, nicht user-facing Syntax
type MetaContext : struct {
db: MetaDbView
target: Option[TypeSubject]
phase: MetaPhase
namespace: ModulePath
proof: ProofTraceBuilder
}
db im Meta-Funktionsrumpf ist context.db. Die Fassade darf Queries lesen und Patches erzeugen, aber keine Descriptoren selbst committen.
Refinements werden als ApplyRefinement-Records erfasst:
Die Query EvaluateRefinement evaluiert diese Anwendung und liefert ein PatchSet. Der Materializer committed dieses PatchSet erst nach Ring-, Coherence- und Konfliktprüfung.
8.6 Ring-0-Facts¶
Ring-0-Facts primitiver VM-Typen sind axiomatische Seeds:
Sie sind über Queries lesbar:
Sie sind nicht durch Patches überschreibbar.
9. db.* — Meta-Fassade¶
9.1 Grundregel¶
db.* ist keine freie Datenbank-API. Jeder db.*-Aufruf ist eine kuratierte Fassade über eine definierte Query oder einen MaterializationPatch.
db ist immer die MetaDbView aus dem MetaContext, nicht die rohe CompilerDB. Source-seitig wirkt db implizit; kanonisch ist jeder Zugriff context.db.*.
db.target() -> Context Target
db.fields(of: T) -> Query GetFields(T)
db.meta(of: T, f) -> Query GetMeta(T, f)
db.ring0Fact(T, f) -> Query GetRing0Fact(T, f)
db.hasProvide(P,args) -> Query LookupProvide(P,args)
db.setMeta(...) -> MetaPatch
9.2 Lesende Fassade¶
db.target() -> TypeSubject
db.fields(of: TypeSubject) -> [FieldDef]
db.typeOf(field: FieldDef) -> Type
db.name(t: TypeSubject) -> str
db.typeParam(t: TypeSubject, index: i32) -> Type
db.phantomParam(t: TypeSubject, name: str) -> Tag
db.refinements(of: TypeSubject) -> [Refinement]
db.meta(of: TypeSubject, field: str) -> Option[Tag]
db.metaRing(field: str) -> Ring
db.hasProvide(protocol, args) -> bool
db.variants(of: TypeSubject) -> [VariantDef]
db.isMutable(field: FieldDef) -> bool
db.isConcreteType(t: Type) -> bool
db.typeKind(t: TypeSubject) -> TypeKind
db.ring0Fact(t: TypeSubject, field: str) -> Option[Tag]
db.isRing0Fact(t: TypeSubject, field: str) -> bool
db.target() ist nur während der Auswertung einer Refinement-Meta-Funktion definiert. Außerhalb eines ApplyRefinement-Contexts ist der Zugriff ein Compile-Time-Fehler.
9.3 Schreibende Fassade¶
Schreibende Operationen erzeugen Patches:
db.setMeta(target, field: str, value: Tag) -> MetaPatch
db.createStruct(name: str, fields) -> TypeDescriptorPatch
db.createEnum(name: str, variants) -> TypeDescriptorPatch
db.fnType(params, returnType) -> TypeDescriptorPatch
db.constructType(base, args) -> TypeDescriptorPatch
db.constructRefinement(r, args) -> RefinementPatch
db.addProvide(desc) -> ProvidePatch
Eine Compile-Zeit-Funktion darf Patches erzeugen, aber nicht committen. Commit ist Aufgabe des Materializers.
9.4 Diagnostics¶
db.Never ist der Bottom-Typ nach einem Fehler und verhindert Folgefehler, ohne die Auswertung mit Exceptions zu zerreißen.
10. Dependency-Tracking¶
10.1 Automatisches Tracking¶
Wenn Query A während ihrer Auswertung Query B liest, registriert die CompilerDB:
Beispiel:
CheckFunction(f)
-> BuildFunctionIR(f)
-> ResolveType(T)
-> GetFields(T)
-> GetFileAST(file)
-> FileContent(file)
Der Provider muss keine Kanten manuell eintragen.
10.2 DepGraph¶
struct DepGraph {
QueryKey[][QueryKey] dependencies;
QueryKey[][QueryKey] dependents;
void addEdge(QueryKey from, QueryKey to);
QueryKey[] dependenciesOf(QueryKey key);
QueryKey[] dependentsOf(QueryKey key);
void clearDependencies(QueryKey key);
}
dependentsOf ist für Debugging und optionale Tools erlaubt. Normative Revalidierung nutzt dependenciesOf lazy.
10.3 Keine fremden direkten Abfragen¶
Provider dürfen andere Phasen nicht direkt aufrufen.
Nicht zulässig:
Zulässig:
auto ast = db.query!(JadeResult!AstModule)(GetFileAST { file });
auto sym = db.query!(JadeResult!SymbolDescriptor)(LookupSymbol { name, scope });
Auch Ring-1-Engines lesen ausschließlich über die Query-Fassade.
11. Lazy Revalidierung und Early Cutoff¶
11.1 Prinzip¶
Bei Input-Änderung wird nichts transitiv invalidiert. Die CompilerDB erhöht die Revision. Query-Ergebnisse werden erst beim nächsten Zugriff revalidiert.
Ein Ergebnis wird nur neu berechnet, wenn eine Dependency sich inhaltlich geändert hat.
11.2 Beispiel¶
Kommentaränderung:
FileContent.changedAt = 12
GetFileAST neu berechnet, AST contentHash identisch
GetFileAST.changedAt bleibt 7
ResolveType sieht keine geänderte Dependency
CheckFunction bleibt gültig
Typänderung:
FileContent.changedAt = 13
GetFileAST contentHash geändert
ResolveType neu berechnet
CheckFunction neu berechnet
11.3 Ergebnis-Early-Cutoff¶
Wenn ein Provider neu läuft, aber dasselbe kanonische Ergebnis erzeugt, bleibt changedAt unverändert. Abhängige Queries werden dadurch nicht unnötig neu berechnet.
12. Durability¶
12.1 Klassifikation¶
enum Durability {
Low, // aktive Datei, Editor-Input
Medium, // Projektdateien, lokale Konfiguration
High // Stdlib, Seeds, externe pinned Dependencies
}
Seeds, primitive Ring-0-Facts und Compiler-Versionen haben High-Durability.
12.2 Kurzschluss¶
Eine Query speichert die maximale Durability ihrer transitiven Inputs. Wenn seit der letzten Verifikation keine Inputs dieser Durability-Klasse geändert wurden, kann die Revalidierung übersprungen werden.
bool canSkipRevalidation(CompilerDb* db, QueryKey key, QueryResult cached) {
return cached.verifiedAt >= db.durability.lastChanged(cached.durability);
}
13. Cancellation¶
13.1 Zweck¶
LSP- und REPL-Szenarien erzeugen häufig neue Revisionen, während alte Berechnungen noch laufen. Cancellation verhindert, dass veraltete Provider unnötig weiterrechnen.
13.2 Regel¶
Cancellation darf den Cache nicht korrumpieren.
- Vor
cache.putabgebrochene Berechnungen hinterlassen den alten Cache. - Patches abgebrochener Provider werden nicht committed.
- Dependencies werden bei der nächsten vollständigen Neuberechnung sauber ersetzt.
13.3 Checkpoints¶
Checkpoints sind zulässig:
- vor Provider-Aufruf,
- vor teuren Materialisierungsschritten,
- zwischen EngineProvider-Phasen.
Cancellation ist keine semantische Änderung. Sie beendet nur eine Berechnung.
14. Arena-Integration¶
14.1 Arena-Arten¶
keyArena QueryKeys
resultArena serialisierte Query-Ergebnisse
depArena Dependency-Kanten
provenanceArena DerivationRecords und Proof-/Diagnostic-Provenance
providerArena temporäre Provider-Daten
Provider dürfen temporäre Arenen nutzen, aber Query-Ergebnisse, die über Provider-Grenzen hinaus leben, müssen in resultArena oder DescriptorStore kopiert werden.
14.2 Descriptor-Lebenszeit¶
Descriptoren leben mindestens so lange wie die CompilerDB-Revision, in der sie gültig sind. Persistente Descriptoren können in einem separaten DescriptorStore über Revisionen hinweg gehalten werden.
14.3 Keine fremden Arena-Pointer¶
Query-Ergebnisse dürfen keine Pointer in Provider-interne Arenen enthalten. Sie müssen kanonisch serialisierbar sein.
15. Fehlerbehandlung und Diagnostics¶
15.1 Diagnostics als Werte¶
Provider werfen keine semantischen Exceptions. Fehler sind Werte:
oder Check-Ergebnisse:
15.2 JadeResult¶
15.3 Diagnostic-Struktur¶
struct DiagnosticEntry {
Phase phase;
Severity severity;
SourceSpan span;
string summary;
string explanation;
Hint[] hints;
Note[] notes;
Option[DerivationKey] provenance;
}
Diagnostics können auf eine DerivationKey-Provenance und darüber auf fachliche Proof-Traces zeigen. Das ist besonders wichtig für Compile-Zeit-Funktionen, Refinements, Provides und Ring-0-Fact-Konflikte.
16. Compiler-Pipeline und Engines¶
16.1 Stage-1-Pipeline¶
Stage 1 darf Zig-BootstrapProvider verwenden:
Source
-> BootstrapTokenizerProvider
-> BootstrapParserProvider
-> BootstrapTypeProvider
-> SeedDescriptorProvider
-> MinimalIRProvider
-> BootstrapGeneratorProvider
Diese Provider sind Implementierungswerkzeuge, nicht die finale Semantik.
16.2 Stage-2-Pipeline¶
Ab Stage 2 sind zentrale Phasen als Ring-1-JDL-Engines formulierbar:
ParserEngine -> AST / ParserDescriptor
NameResolverEngine -> SymbolDescriptor / ScopeDescriptor
TypeEngine -> TypeDescriptor / LayoutDescriptor / LabelProfile
ProtocolDispatcherEngine -> DispatchDescriptor / BindingTableDescriptor
FfiBindingEngine -> FfiCallDescriptor / MarshalDescriptor
IRBuilderEngine -> IrModule
GeneratorEngine -> VmModuleArtifact / Proto
Die CompilerDB ist weiterhin Kommunikations- und Cache-Schicht. Engines greifen nicht direkt aufeinander zu.
16.3 Generator¶
Der Generator ist read-only gegenüber semantischen Descriptoren. Er darf Artefakte erzeugen, aber keine Type-, Effect-, Dispatch- oder FFI-Semantik nachträglich erfinden.
LoweredModule
+ TypeDescriptor
+ LayoutDescriptor
+ DispatchDescriptor
+ FfiCallDescriptor
-> GeneratorEngine
-> VmModuleArtifact
Generator-Artefakte können als Materialized Query oder ArtifactPatch in die CompilerDB eingetragen werden.
16.4 IRBuilder¶
Der IRBuilder ist kein allwissendes Frontend. Er konsumiert getypte AST-/Descriptor-Ergebnisse über Queries und erzeugt IR. Typprüfung, Effektprüfung und Provide-Auflösung müssen vorher materialisiert sein.
17. Tools und Consumer¶
17.1 Consumer-Begriff¶
Ein Consumer nutzt Queries lesend, registriert aber keine normativen Provider für Compiler-Semantik.
Beispiele:
Consumer dürfen eigene Darstellungsqueries definieren, sofern diese keine Compiler-Wahrheiten materialisieren.
17.2 LSP¶
Der LSP liest Queries wie:
Er setzt Input Queries bei Dateiänderungen und nutzt Cancellation.
17.3 jade doc¶
jade doc ist Consumer der CompilerDB. Dokumentation entsteht aus denselben Type-, Symbol-, Effect- und Descriptor-Queries wie der Compiler. Sie soll Quelltext nicht separat interpretieren, damit Dokumentation und Compiler-Wahrheiten konsistent bleiben.
18. Query-Katalog¶
Dieser Katalog ist initial und nicht abschließend.
18.1 SourceDomain¶
FileContent(path) -> str
ModuleList() -> [ModulePath]
BuildConfig() -> BuildConfigDescriptor
ProjectSpecInput() -> ProjectSpec
18.2 SyntaxDomain¶
GetFileTokens(file) -> JadeResult[TokenStream]
GetFileAST(file) -> JadeResult[AstModule]
GetAstNode(nodeId) -> JadeResult[AstNode]
GetDocComment(subject) -> JadeResult[DocNode]
18.3 NameDomain¶
GetModuleId(path) -> JadeResult[ModuleId]
LookupSymbol(name, scope) -> JadeResult[SymbolDescriptor]
GetExports(module) -> [SymbolDescriptor]
GetReferences(symbol) -> [SourceSpan]
18.4 TypeDomain¶
ResolveType(ref) -> JadeResult[TypeDescriptor]
GetTypeDescriptor(typeId) -> JadeResult[TypeDescriptor]
GetFields(typeId) -> [FieldDef]
GetVariants(typeId) -> [VariantDef]
GetTypeKind(typeId) -> TypeKind
GetRing0Facts(typeId) -> JadeResult[Ring0FactSet]
GetRing0Fact(typeId, field) -> Option[Tag]
18.5 MetaDomain¶
GetMetaRecord(subject) -> MetaRecordDescriptor
GetMeta(subject, field) -> Option[Tag]
GetProofTrace(subject, field) -> ProofTrace
EvaluateRefinement(app: ApplyRefinement) -> PatchSet
18.6 Provide/DispatchDomain¶
LookupProvide(protocol, args) -> JadeResult[ProvideDescriptor]
ListProvides(subject) -> [ProvideDescriptor]
BuildDispatchDescriptor(protocol, typeId) -> JadeResult[DispatchDescriptor]
GetDispatchTable(protocol, typeId) -> JadeResult[BindingTableDescriptor]
18.7 EffectDomain¶
GetEffectSignature(funcId) -> JadeResult[EffectDescriptor]
CheckEffects(funcId) -> DiagnosticSet
BuildCallGraphDescriptor(subject) -> JadeResult[CallGraphDescriptor]
18.8 LayoutDomain¶
GetMemoryLayout(typeId) -> JadeResult[LayoutDescriptor]
GetRegisterLayout(functionId) -> JadeResult[RegisterLayout]
GetAbiLayout(typeId, abi) -> JadeResult[AbiLayoutDescriptor]
18.9 IRDomain¶
BuildFunctionIR(functionId) -> JadeResult[IrFunction]
BuildModuleIR(moduleId) -> JadeResult[IrModule]
LowerModuleIR(moduleId) -> JadeResult[LoweredModule]
VerifyLoweredModule(moduleId) -> DiagnosticSet
18.10 ArtifactDomain¶
GenerateVmModule(moduleId, target) -> JadeResult[VmModuleArtifact]
GenerateBridgeArtifact(bindingId, target) -> JadeResult[BridgeArtifact]
GetArtifactHash(artifactId) -> ArtifactHash
18.11 AnalysisDomain¶
Semantic Views und Proof-Queries liegen fachlich in ihren jeweiligen Domains; dieser Katalog zeigt nur typische Formen. Die Namen sind noch nicht als öffentliche API normiert.
GetControlFlowView(functionId) -> JadeResult[ControlFlowView]
GetCallView(functionId) -> JadeResult[CallView]
GetEffectView(functionId) -> JadeResult[EffectView]
GetProgressView(subject) -> JadeResult[ProgressView]
ProveMetaTotality(metaSubject) -> TotalityJudgement
BuildLabelProfile(subject) -> JadeResult[TruthProfile]
19. Erweiterung — neue Queries und Provider¶
19.1 Neue Query definieren¶
- Query-Struct definieren.
- Ergebnis-Typ dokumentieren.
- Determinismus- und Durability-Regeln festlegen.
- Provider registrieren.
- Query in Katalog oder Domain-Spec aufnehmen.
19.2 Zig-BootstrapProvider hinzufügen¶
Query: GetFunctionCallGraph(FuncId) -> JadeResult[CallGraphDescriptor]
Provider: Zig-BootstrapProvider, nur Stage-1-Pfad
19.3 JDL-EngineProvider hinzufügen¶
type GetFunctionCallGraphSpec : blueprint {
function: FuncId
}
provide DescriptorEngine[GetFunctionCallGraphSpec, CallGraphDescriptor] for EffectEngine {
def describe(spec: GetFunctionCallGraphSpec) -> Result[CallGraphDescriptor, DiagnosticSet] {
// liest db.* Queries und erzeugt Descriptor
}
}
19.4 Eindeutigkeit¶
Zwei Provider für dieselbe Query und dasselbe Stage-Profil sind ein CompilerDB-Initialisierungsfehler.
19.5 JDL-definierte neue Query-Verträge¶
Ein vorhandener Query-Vertrag kann ab Stage 2 bereits durch einen JDL-EngineProvider erfüllt werden. Noch nicht abschließend normiert ist dagegen, wie JDL vollständig neue Query-Verträge registriert, solange QueryKey und Query-Arten in der Bootstrap-Darstellung hostseitig über Query-Struct/TypeTag identifiziert werden.
Für vollständige Ring-1-Erweiterbarkeit muss die spätere allgemeine Vertragsregistrierung mindestens garantieren:
stabile kanonische Query-Identität
kanonisch serialisierbares Parameter-Schema
kanonisch serialisierbares Result-Schema
Schema-/Provider-Versionierung im Cache-Schlüsselraum
Coherence und Authority bei Registrierung
identische Cache-/DepGraph-/Cancellation-Semantik für Bootstrap und JDL
Diese Lücke ist allgemein, nicht View-spezifisch. Eine neue Semantic View begründet daher keine ViewRegistry oder andere Sondermechanik in Ring 0. Ein bestehender Descriptor-/Provide-Mechanismus soll wiederverwendet werden, wenn er diese Anforderungen vollständig tragen kann; ein neuer QueryContract-Typ ist damit noch nicht beschlossen.
20. Normative Invarianten¶
- CompilerDB besitzt keine hohe JDL-Semantik. Sie orchestriert Queries, Provider, Cache, Seeds, Descriptoren und Materialisierung.
- Keine direkte Phasenkommunikation. Provider und Engines lesen andere Phasen ausschließlich über Queries.
- Provider sind deterministisch. Gleiche Inputs, gleiche Provider-Version, gleiche Stage-Konfiguration ergeben gleiche Ergebnisse.
- Input Queries haben keinen Provider. Sie werden gesetzt.
- Derived Queries haben genau einen aktiven Provider. Mehrdeutigkeit ist Fehler.
- Materialized Queries lesen Descriptoren oder Seeds. Sie erfinden keine neue Semantik.
- Compile-Zeit-Funktionen mutieren nicht direkt. Schreibende
db.*-Operationen erzeugen Patches. - Compile-Zeit-Funktionen laufen in einem MetaContext.
dbist eine MetaDbView;targetkommt nur ausApplyRefinement. - Der Materializer committed atomar. Ring-Level, Ring-0-Facts und Coherence-Regeln werden geprüft.
- Ring-0-Facts sind axiomatisch. Sie sind lesbar, aber nicht überschreibbar.
- Descriptoren sind immutable nach Commit. Änderungen erzeugen neue Revisionen oder Descriptor-Versionen.
- Dependency-Tracking ist automatisch. Provider tragen Query-Abhängigkeiten nicht manuell ein.
- Revalidierung ist lazy. Keine eager-transitive Invalidierung.
- Diagnostics sind Werte. Semantische Fehler werden nicht als Exceptions propagiert.
- Generator erzeugt Artefakte, keine neue Semantik. Semantik muss vorher als Descriptor materialisiert sein.
- RuntimeBus ist nicht über CompilerDB erreichbar. Compile-Time-Queries führen keine Runtime-Commands aus.
- Stage 1 darf Zig-BootstrapProvider nutzen. Das ist Bootstrap, nicht endgültige Architektur.
- Stage 2+ darf Ring-1-EngineProvider nutzen. Zig bleibt Substrate und Recovery Path.
- Semantic Views sind gewöhnliche Derived Queries. CompilerDB besitzt keine View-spezifische Semantik oder Registry.
- Proof-Queries sind gewöhnliche Derived Queries. Ihr fachliches Judgement wird von der zuständigen Semantikspec definiert, nicht von CompilerDB.
- Query-Zyklen bleiben Fehler. Lokale endliche Worklist-/Fixpunktalgorithmen laufen innerhalb einer terminierenden Provider-Auswertung.
- Ein Proof-Query hat genau einen aktiven Provider pro Stage-Profil. Mehrere Beweisregeln werden innerhalb der Fachsemantik komponiert.
- Providerregistrierung ist keine universelle Beweisautorität. Sealed/core Proof-Verträge dürfen den zulässigen Provider-Geltungsbereich beschränken.
- Neue View-Arten rechtfertigen keine Ring-0-Sonderprimitive. Vollständig neue JDL-Query-Verträge benötigen jedoch die allgemeine, noch zu normierende datengetriebene Vertragsregistrierung aus §19.5.
21. Implementierungshinweise¶
21.1 Zig-Implementierung darf pragmatisch sein¶
Die Zig-Implementierung darf intern Objekte wie Parser, BootstrapTypeProvider oder SeedLoader besitzen. Diese Objekte sind Provider-Details und nicht Teil des normativen CompilerDB-Modells.
21.2 Provider-Versionierung¶
Provider-Versionen sollten im Query-Key-Raum berücksichtigt werden, wenn sie das Ergebnis ändern können. Sonst erhält man stale Cache-Ergebnisse nach Engine-Updates. Ein Klassiker, den man nur einmal debuggen möchte, danach glaubt man wieder an klare Versionierung.
21.3 Canonical Serialization¶
Alle Query-Keys, Query-Results und Descriptoren benötigen kanonische Serialisierung. Nicht-deterministische Map-Reihenfolgen sind verboten. Listen müssen stabil sortiert sein, wenn ihre semantische Ordnung irrelevant ist.
21.4 Persistenter Cache¶
Persistente Caches dürfen nur Ergebnisse wiederverwenden, wenn folgende Werte übereinstimmen:
CompilerDB schema version
Query schema version
Provider version
Seed hash
BuildConfig hash
Target descriptor hash
Input content hashes
21.5 Provenance und Proof Trace¶
Provenance und fachliche Proof Traces sind keine Debug-Spielerei. Ein DerivationRecord erklärt eine konkrete Query-Ableitung; darin referenzierte fachliche Proof-Traces erklären einzelne semantische Urteile. Diese Trennung ist notwendig für:
:whyin der REPL,- IDE-Diagnostics,
- Refinement-Erklärungen,
- Ring-0-Fact-Konflikte,
- Coherence-Fehler bei Provides,
- Reproducibility-Audits späterer Artefaktpfade.
Normativ darf Provenance die semantische Identität eines Descriptors nicht beeinflussen. Zwei verschiedene Ableitungen dürfen denselben semanticPayload materialisieren und damit denselben kanonischen Descriptor referenzieren. Umgekehrt muss auch eine fehlgeschlagene Ableitung erklärbar bleiben, obwohl sie keinen Descriptor erzeugt.
21.6 Stage-Übergang¶
Beim Übergang von Stage 1 zu Stage 2 muss die CompilerDB explizit dokumentieren, welche Queries vom BootstrapProvider auf EngineProvider umgestellt werden. Ein stiller Provider-Wechsel ohne Stage-Profil ist verboten.
21.7 Granularität semantischer Views¶
Eine Semantic View soll die kleinste sinnvoll wiederverwendbare semantische Projektion sein, nicht den kleinsten darstellbaren Fakt. Millionen mikroskopischer Queries können Dispatch, Serialisierung und Dependency-Buchhaltung teurer machen als die eigentliche Analyse.
ControlFlowView(function) ist deshalb typischerweise sinnvoller als eine Query pro CFG-Kante, sofern keine unabhängige Invalidierungsnotwendigkeit den feineren Schnitt rechtfertigt.
Änderungsprotokoll¶
0.7.0¶
- Ring-0-Bootstrap von historischem D-Vokabular auf Zig aktualisiert; D-spezifische Providerannotation aus dem normativen Modell entfernt.
- Normatives
TypeFnContext-/TypeFnDbView-Altvokabular aufMetaContext/MetaDbViewund gewöhnliche Compile-Zeit-Funktionen migriert; historische Änderungsprotokolle bleiben als Historie erhalten. ProofStore/ProofId-Altmodell aufProvenanceStore/DerivationKeyabgeglichen; Query-Antwort, kanonische Descriptor-Semantik und Ableitungsbegründung sind getrennte Wissensarten.- Semantic Views als gewöhnliches Derived-Query-Nutzungsmuster eingeordnet; keine View-spezifische Registry oder Ring-0-Primitive.
- Proof-Queries, Facts/Obligations/Proofs und lokale endliche Closure-/SCC-Auswertung gegenüber CompilerDB-Query-Zyklen abgegrenzt.
- Provider-Eindeutigkeit für View-/Proof-Queries sowie Autoritätsgrenze sealed/core Proof-Verträge präzisiert.
- AnalysisDomain-Beispiele und Granularitätsregel ergänzt.
- Offene Self-Hosting-Lücke für vollständig JDL-definierte neue Query-Verträge explizit in §19.5 erfasst.
0.6.1¶
TypeFnContextundTypeFnDbViewals kanonisches Ausführungsmodell für TypeFns ergänzt.ApplyRefinementals interne Darstellung vontarget :> Refinement(args)eingeführt.db.target()als Zugriff auf das aktuelle Refinement-Target definiert.EvaluateRefinementauf ApplyRefinement-Records geschärft.- Normative Invarianten um Context-/Target-Semantik ergänzt.
0.6.0¶
- CompilerDB von D-Subsystem-Modell auf Query/Provider-Modell umgestellt.
- DescriptorStore, SeedStore und Materializer normativ eingeführt.
@handlesauf D-BootstrapProvider beschränkt.- Ring-1-JDL-EngineProvider als Stage-2-Normalpfad eingeführt.
db.*als kuratierte Query-/Patch-Fassade definiert.- Direkte TypeFn-Mutation durch Patch-Materialisierung ersetzt.
- Generator als Artefakt-Provider, aber nicht als Semantik-Produzent geschärft.
0.5.0¶
- Historische Fassung: CompilerDB als Subsystem-API mit D-Handlern und
@handles.