Semantic Metadata Registry — Technical Specification
The Core Tension & Fix
Three fundamental failure modes occur when a single monolithic schema serves every consumer:
Entity-First, Not Column-First
Analytics is about a dataset made of tables, relationships, entities, measures, dimensions, and hierarchies. Columns are temporary physical representations.
```typescript filename="entity-mapping-spine.ts"
// Separation of Concept (what it means) from Mapping (where it lives)
interface SemanticEntity {
semanticId: string;
semantic: "measure" | "dimension" | "entity" | "date" | "currency" | "category" | "hierarchy";
entityType?: "customer" | "vendor" | "product" | "order" | "invoice";
businessMeaning: string; // e.g. "finance.revenue"
synonyms: string[];
description: string;
}
interface ColumnMapping {
semanticEntityRef: string; // References SemanticEntity.semanticId
tableId: string;
columnName: string;
dataType: "string" | "integer" | "decimal" | "boolean" | "datetime";
isCanonicalSource: boolean;
capabilities: CapabilityMetadata;
}
```
A schema migration or column rename creates a new ColumnMapping pointing to the existing SemanticEntity — zero ripple effects through downstream prompts or query planners.
The Four Registries
The ontology splits into four peer registries based on lifecycle and ownership:| Registry | Contains | Change Frequency | Ownership |
|---|
| Semantic Registry | SemanticEntity + ColumnMapping definitions | Rarely (data model changes) | Platform Team (CI-gated) |
| Relationship Registry | Table definitions, joins, cardinality, chasm-trap rules | Rarely (schema migrations) | Platform Team (CI-gated) |
| Entity Registry | Aliases, fuzzy match rules, embeddings | Continuously (new vendors/typos) | Semi-automated pipeline |
| Statistics Registry | Min/max, null %, top values, sample data | Automated refresh cycle | Automated pipeline |
Authoring Shape: SemanticEntity & ColumnMapping
```typescript filename="semantic-registry-schema.ts"
export type SemanticKind =
| "measure"
| "dimension"
| "entity"
| "date"
| "datetime"
| "currency"
| "category"
| "identifier"
| "hierarchy";
export interface CapabilityMetadata {
supportedAggregations: Array<"sum" | "avg" | "min" | "max" | "count" | "cardinality">;
searchable: boolean;
supportsRange: boolean;
supportsAliases: boolean;
filterPriority?: number;
}
```
Keyword Reference & Derivation Rules
Capability Derivation Matrix
Capabilities are derived automatically from SemanticEntity.semantic by default, eliminating manual authoring overhead:| semantic | Aggregations | supportsRange | groupable | searchable |
|---|
| measure | Required (sum, avg, min, max) | Yes | Rare | No |
| dimension | None | Rare | Yes | Yes |
| entity | None | No | Yes | Yes (supportsAliases: true) |
| date / datetime | min, max, count | Yes | Yes | Limited |
| currency | Treated as measure | Yes | Rare | No |
Tool Registry: Automatic Codegen
Tools are auto-generated from the Semantic Registry based on concept capabilities. A concept with groupable: true automatically emits a groupBy tool.
Projection Pipeline & Query Planner
```typescript filename="planner-view.ts"
// Planner View — structural slice consumed by Query Planner & Shared Runtime
interface PlannerView {
semanticId: string;
table: string;
column: string;
dataType: string;
defaultAggregation?: string;
joinPathToCanonical: string[];
}
```
Versioning & Session Isolation
• Independent Layer Versioning: semanticModelVersion (Semantic + Relationship), registryVersion (Entity / Statistics), and projectionVersion evolve independently to prevent global cache invalidation.
• Strict Session Isolation: Multi-tenant concurrent sessions are strictly isolated. Session state (conversation history, resolved entity caches) lives 100% outside the stateless read-only registries.