ERDL Whitepaper
Enterprise Resource Definition Language
In the age of AI, humans write YAML. Digital systems speak ERDL.
Human-readable · Machine-readable · Readable between machines
Table of Contents
1. Overview
1.1 What is ERDL
ERDL (Enterprise Resource Definition Language) is OpenOBA's proprietary declarative business semantics description system. Built on the YAML specification and fully compatible with standard YAML syntax, it lets enterprises define business entities, fields, aliases, enumerations, rules, and agentable actions in their own industry's language.
ERDL's core breakthrough: it is not a config file for developers—it is the protocol layer between LLMs and business systems. When an Agent reads an ERDL definition, it gains a deterministic understanding of the business model—not probabilistic guesswork, but structured semantic cognition. Human-readable, machine-readable, and readable between machines—three audiences, one language.
Positioning: ERDL is OpenOBA's "semantic language hub"—upward to LLM natural language understanding, downward to databases and APIs, and laterally to industry knowledge bases. It is the infrastructure that enables free communication between enterprise digital systems and LLMs.
1.2 Problems Solved
In traditional enterprise software development, a massive translation gap exists between "business requirements" and "technical implementation." "Frame shape" in eyewear, "silhouette" in apparel, "shade" in cosmetics—business terminology varies wildly, yet traditional software requires developers to translate each term into a database column name. This translation depends on manual communication, meetings, and documentation—expensive, error-prone, and non-reusable.
ERDL makes these mappings declarative, structured, and verifiable. When AI reads ERDL, it's like an engineer reading a complete business data dictionary and rulebook—no guessing, deterministic understanding.
1.3 File Format
ERDL files use the .erdl extension, based on the YAML specification and fully compatible with YAML syntax. An industry typically uses two files:
industry-name.erdl— entity definitions, alias mappings, rulesets, semantic layer configindustry-name.actions.erdl— agentable action definitions
2. Core Design Principles
2.1 Declarative, Zero Code
Definition is implementation. Declare entities, properties, and constraints in an ERDL file, and the system auto-generates database tables, API endpoints, and frontend forms. No CRUD code to write.
2.2 Alias System: The Industry Jargon Translator
Every industry has its own jargon—the same concept expressed in different words across different industries. ERDL's alias mechanism maps industry vernacular to standard field names. When a user says "frame shape," the Agent auto-translates to shapeCode; "selling price" becomes retailPrice.
Aliases are ERDL's core mechanism for eliminating LLM ambiguity—not relying on prompt-level "please note these synonyms," but establishing deterministic mappings at the protocol level.
2.3 Hot Reload: Save and It's Live
Modify a .erdl file and it takes effect immediately—no restart required. ERDL Registry watches file changes → auto-validates semantics → hot-swaps in-memory Schema → agentor instantly gets the latest definition. Business rules go from "wait for the next release" to "edit and use."
2.4 Physical Mapping: Semantics to Storage, Direct
ERDL not only describes business semantics but directly declares physical storage mappings—table (database table name), dbColumn (column name), primaryKey. Once the agentor understands the business intent, the ERDL Entity Proxy Engine auto-translates to SQL—no manual data access layer to write.
2.5 Rule-Driven, Not Prompt-Constrained
Rulesets in ERDL define business boundary conditions—prices must be positive, membership discounts auto-calculate, inventory can't go negative. These rules are not "suggestions" for the LLM to read; they are protocol-level hard checks agented by Action Guard before the agentor acts. Output that fails any rule is rejected outright—it never enters the execution pipeline.
3. Syntax Reference
3.1 File Header
# Namespace: globally unique identifier
namespace: industry.eyewear
# Module metadata
module:
version: "1.5.0"
extends: "erd.base" # Inherit base ERDL definitions
# Description (optional)
name: "Eyewear Industry ERP Definition"
description: "Core business entities for eyewear: products, orders, customers, inventory"
3.2 Entity Definition
Entity is the core building block of ERDL, corresponding to a business object. Once an Entity is declared, the system auto-generates:
- Database table (with columns, primary key, indexes)
- REST API (CRUD + list queries)
- Frontend forms and table column configurations
- agentor-operable context
entities:
ProductSpu:
table: "product_spu" # Database table name
primaryKey: "spu_id" # Primary key column
properties:
spuId:
type: "UUID" # Data type
dbColumn: "spu_id" # Database column name
required: true # Required
spuCode:
type: "String"
dbColumn: "spu_code"
required: true
maxLength: 64 # Max character length
spuName:
type: "String"
dbColumn: "spu_name"
required: true
maxLength: 256
gender:
type: "Enum"
dbColumn: "gender"
enum: ["female","male","unisex","limited"] # Allowed values
retailPrice:
type: "Money(CNY)" # Currency type (with denomination)
dbColumn: "retail_price"
attributes:
type: "JSON" # JSON type
dbColumn: "attributes"
createdAt:
type: "DateTime"
dbColumn: "created_at"
autoGenerate: true # Auto-generated
metadata:
knowledge: "product-knowledge" # Linked knowledge base
icon: "glasses" # UI icon
category: "product" # Business category
3.3 Type System
| Type | Description | Example | DB Mapping |
|---|---|---|---|
String | String | Product name | VARCHAR |
UUID | Unique identifier | Primary key | UUID / CHAR(36) |
Integer | Integer | Stock quantity | INTEGER |
Decimal | High-precision decimal | Weight, dimensions | DECIMAL |
Float | Floating point | Price | FLOAT / DOUBLE |
Money(CNY) | Currency (with denomination) | Retail price, cost price | DECIMAL + currency marker |
Boolean | Boolean | Is active | BOOLEAN / TINYINT |
Enum | Enumeration (restricted values) | Gender, status | VARCHAR + CHECK |
DateTime | Timestamp | Created time | DATETIME / TIMESTAMP |
JSON | JSON object/array | Attributes, tags | JSON / JSONB |
3.4 Property Constraints
| Constraint | Description | Example |
|---|---|---|
required: true | Field is required | Product name must not be empty |
maxLength: 256 | Max character length | Name ≤ 256 characters |
enum: [...] | Restricted enumeration values | Gender can only be female/male |
autoGenerate: true | System auto-generates | UUID primary key, timestamps |
unique: true | Unique constraint | Product code must be unique |
3.5 Alias Mapping
The alias system maps industry terminology to standard field names. One field can have multiple industry aliases:
aliases:
ProductSpu:
"frame shape": "seriesCode"
"style": "spuName"
"tier": "productTier"
"grade": "productTier"
ProductSku:
"color code": "colorCode"
"shade": "colorCode"
"selling price": "retailPrice"
"list price": "retailPrice"
"cost": "costPrice"
"wholesale price": "costPrice"
"stock": "stockQuantity"
Customer:
"name": "contactName"
"phone": "phone"
"level": "customerLevel"
Order:
"order number": "orderNo"
"total": "totalAmount"
"paid": "actualAmount"
Alias runtime behavior: When the Agent parses user input, it first searches the alias table for a match → if found, translates to the standard field name → if not found, passes to the LLM as fuzzy semantics for inference. The system continuously accumulates new alias mappings, auto-depositing them at runtime.
3.6 Rulesets
Rulesets define business logic boundaries and perform hard validation before agentor execution. Two types of rules:
- Validation: data legality checks—failing any means rejection
- Policy: automated calculation logic, e.g. membership discounts
rulesets:
PricingRules:
# ── Policy: auto-calculate VIP discount ──
policies:
- name: "VIP 20% off"
priority: 1
entity: ProductSku
condition:
field: "customer.tier"
operator: eq
value: "VIP"
actions:
- type: calculate
params:
formula: "retailPrice * 0.8"
# ── Validation: price legality ──
validations:
- name: "Retail price must be positive"
priority: 10
entity: ProductSku
condition:
field: "retailPrice"
operator: gte
value: 1
actions:
- type: validate
params:
error: "Retail price must be greater than 0"
- name: "Selling price ≥ 1.2× cost"
priority: 10
entity: ProductSku
condition:
field: "retailPrice"
operator: gte
formula: "costPrice * 1.2"
actions:
- type: validate
params:
error: "Selling price must be at least 1.2× cost"
3.7 agentable Actions
Actions define what the agentor can agente, declaring parameter types, enum constraints, and whether human approval is required:
actions:
erdl_crud:
description: "Read/write ERDL Entity data"
params:
action:
required: true
enum: [create, read, update, delete]
entity:
required: true
values:
type: object
where:
type: object
select:
type: string_array
promote_drafts:
description: "Promote drafts to production SPU/SKU products"
params:
draftIds:
required: true
type: string_array
description: "List of draft IDs to promote"
taskId:
description: "Associated agentor task ID"
query_erp_data:
description: "Query ERP system data"
params:
data_type:
type: enum
values: [all, spu, sku, shapes, colors, materials, effects, series, rules]
aesthetics_check:
description: "Aesthetics validation—score product aesthetics"
params:
shapeCode: { required: true }
colorCode: { required: true }
gender: {}
skinToneEffect: {}
faceShapeEffect: {}
read_file:
description: "Read file contents from workspace—supports .md .txt .json .csv .xlsx .docx .pdf .html .sql .erdl"
params:
path: { required: true }
maxLines: { type: number, default: 0 }
3.8 Semantic Layer
The semantic layer is ERDL's "dictionary data snapshot" for LLMs—it injects dictionary table contents from the database into the Agent's System Prompt in structured form, so the agentor understands business context without querying each time:
semantic_layer:
dictionaries:
- name: "Effect term mapping"
source: "dict_effect_tag"
mapping_engine: "llm_bridge"
hotword_rules:
detect_from: ["social_listener", "search_log"]
normalize_to: "effect_tag"
confidence_threshold: 0.7
3.9 Sync Policy
Controls how dictionary data syncs to agentor context:
sync_policy:
dict_pulse:
mode: "on-demand" # on-demand | scheduled | real-time
source:
type: "dict"
table: "dict_effect_tag"
fields: ["effect_code", "effect_name", "effect_type"]
transform: "passthrough"
target: "system_prompt"
4. Toolchain
A complete develop-validate-deploy toolchain around ERDL, covering every step from authoring to production.
4.1 ERDL Registry Core
The ERDL Registry is the runtime engine, responsible for:
- File discovery: watches the
erdl/directory, auto-discovers all.erdlfiles - Parse & load: YAML-spec parsing → semantic validation → register into memory
- Hot Reload: detects file changes → incremental update → instant effect, no restart
- Multi-file merge: auto-merges main definition file + Actions file into one complete Schema
- Version management: tracks each loaded version, supports rollback
- Status query: provides API to query currently loaded industries, entity lists, and Schema details
4.2 Schema Resolver
Converts ERDL declarations into runtime-usable data structures. Performs the following transformations:
- Entity definitions → TypeORM Entity classes + database migration SQL
- Property constraints → DTO validation rules (class-validator)
- Enum definitions → TypeScript enums + database CHECK constraints
- Alias tables → fast-lookup hash maps
- Rulesets → Action Guard validation chains
4.3 Action Guard Core
Protocol-level execution validation engine. Before any agentor output enters system execution, Action Guard performs these intercepts:
- Action identification: parse LLM output (FC/XML/text), extract action name and parameters
- Parameter validation: check parameter types, required fields, and enum values against ERDL declarations
- Rule validation: agente all validation rules in Rulesets—any single failure means rejection
- Policy application: apply policy rules from Rulesets—e.g. auto-calculate membership discounts
- Audit logging: record the full execution chain (input → validation results → execution results)
Action Guard's core value: not prompt constraints—code-level hard validation. LLM output is uncontrollable, but Action Guard ensures at the protocol layer that only legal operations enter execution.
4.4 Schema API
Exposes REST APIs for frontend and admin console use:
| Endpoint | Method | Description |
|---|---|---|
/schema | GET | Get complete Schema for current industry |
/schema/industries | GET | List all available industries |
/schema/spu-attributes | GET | Get SPU attribute list (for dynamic forms) |
/schema/sku-attributes | GET | Get SKU attribute list |
/schema/effect-thesaurus | GET | Get effect term thesaurus |
/schema/pricing-rules | GET | Get pricing rules |
/schema/display-name | GET | Generate display name per Schema template |
4.5 Meta-Mirror
Bidirectional consistency guardian:
- Forward scan: scan backend DTOs/Entities, auto-generate or update ERDL definitions
- Reverse audit: compare ERDL declarations against actual DTO code, report inconsistencies immediately
- Quality gate: auto-check type completeness, enum consistency, field coverage
- Version guardian: version consistency + commit auditing + CHANGELOG tracking
4.6 Dev Tools
- ERDL Playground: online ERDL editor with real-time syntax validation + preview
- VS Code Extension (coming soon): syntax highlighting, autocomplete, error hints, alias lookup
- CLI tools:
erdl validatefor syntax checking,erdl difffor version diffing
5. Runtime Architecture
ERDL''s position and data flow within the OpenOBA runtime:
+------------------------------------------------------------------+
| User Input |
| "Give all VIP members 20% off eyewear selling prices" |
+---------------------------------+--------------------------------+
|
v
+------------------------------------------------------------------+
| (1) LLM Understanding + ERDL Alias System |
| "VIP" -> Customer.customerLevel |
| "eyewear" -> ProductSpu |
| "selling price" -> ProductSku.retailPrice (alias) |
| "20% off" -> pricing_policy |
+---------------------------------+--------------------------------+
|
v
+------------------------------------------------------------------+
| (2) Action Guard Interception |
| x Param validation: retailPrice must be > 0 |
| x Rule validation: PricingRules.validation passed |
| x Policy application: PricingRules.policy -> 0.8 discount |
+---------------------------------+--------------------------------+
|
v
+------------------------------------------------------------------+
| (3) ERDL Entity Proxy Engine -> SQL Translation |
| UPDATE product_sku |
| SET retail_price = retail_price * 0.8 |
| WHERE spu_id IN (...) AND sku_id IN (...) |
| (customer tier = 'VIP') |
+---------------------------------+--------------------------------+
|
v
+------------------------------------------------------------------+
| (4) Audit Log + Result Return |
| { affected: 247, audit_id: "ck-...", rollback: true } |
+------------------------------------------------------------------+
Critical paths:
- ERDL file → Registry load → Schema resolve → Agent System Prompt injection
- User natural language → Alias system translation → Action Guard validation → Entity Proxy Engine generates SQL → Execute
- Dictionary data → Sync Policy → System Prompt semantic layer → Agent context
6. Complete Code Examples
6.1 Minimal Runnable ERDL File
A complete minimal ERDL file defining a simple product management system:
# File: my-erp.erdl
namespace: industry.my_erp
module:
version: "1.0.0"
entities:
Product:
table: "product"
primaryKey: "id"
properties:
id:
type: "UUID"
dbColumn: "id"
autoGenerate: true
productCode:
type: "String"
dbColumn: "product_code"
required: true
maxLength: 64
unique: true
productName:
type: "String"
dbColumn: "product_name"
required: true
maxLength: 256
category:
type: "Enum"
dbColumn: "category"
enum: ["ELECTRONICS","CLOTHING","FOOD","OTHER"]
retailPrice:
type: "Money(CNY)"
dbColumn: "retail_price"
required: true
stockQuantity:
type: "Integer"
dbColumn: "stock_quantity"
isActive:
type: "Boolean"
dbColumn: "is_active"
createdAt:
type: "DateTime"
dbColumn: "created_at"
autoGenerate: true
metadata:
category: "product"
knowledge: "product-management"
aliases:
Product:
"product name": "productName"
"name": "productName"
"selling price": "retailPrice"
"price": "retailPrice"
"list price": "retailPrice"
"stock": "stockQuantity"
"inventory": "stockQuantity"
"category type": "category"
rulesets:
ProductRules:
validations:
- name: "Price must be positive"
priority: 10
entity: Product
condition:
field: "retailPrice"
operator: gt
value: 0
actions:
- type: validate
params:
error: "Product price must be greater than 0"
- name: "Stock cannot be negative"
priority: 10
entity: Product
condition:
field: "stockQuantity"
operator: gte
value: 0
actions:
- type: validate
params:
error: "Stock quantity cannot be negative"
6.2 Corresponding Actions File
# File: my-erp.actions.erdl
namespace: industry.my_erp
module:
version: "1.0.0"
extends: my-erp
actions:
erdl_crud:
description: "Read/write ERDL Entity data—create, read, update, delete"
params:
action:
required: true
enum: [create, read, update, delete]
entity:
required: true
values:
type: object
where:
type: object
select:
type: string_array
query_inventory:
description: "Query product inventory status"
params:
productCode: {}
category: {}
lowStock:
type: boolean
description: "Show only low-stock products"
batch_update_price:
description: "Batch adjust product prices"
params:
category: {}
discountPercent:
type: number
description: "Discount percentage, e.g. 20 means 20% off"
requireApproval: true
6.3 Eyewear Industry Complete Example (Excerpt)
OpenOBA's flagship case—Eyewear ERP—has 20 entities, 150+ aliases, and 12 business rules in its complete ERDL definition. Core excerpt:
# File: eyewear.erdl
namespace: industry.eyewear
module:
version: "1.5.0"
extends: "erd.base"
entities:
ProductSpu:
table: "product_spu"
primaryKey: "spu_id"
properties:
spuId: { type: "UUID", dbColumn: "spu_id", required: true }
spuCode: { type: "String", dbColumn: "spu_code", required: true, maxLength: 64 }
spuName: { type: "String", dbColumn: "spu_name", required: true, maxLength: 256 }
gender: { type: "Enum", dbColumn: "gender", enum: ["female","male","unisex","limited"] }
structureCode: { type: "String", dbColumn: "structure_standard_code", maxLength: 64 }
seriesCode: { type: "String", dbColumn: "series_code", maxLength: 64 }
productTier: { type: "String", dbColumn: "product_tier", maxLength: 20 }
sceneTags: { type: "JSON", dbColumn: "scene_tags" }
attributes: { type: "JSON", dbColumn: "attributes" }
metadata:
knowledge: "product-knowledge"
category: "product"
ProductSku:
table: "product_sku"
primaryKey: "sku_id"
properties:
skuId: { type: "UUID", dbColumn: "sku_id", required: true }
skuCode: { type: "String", dbColumn: "sku_code", required: true, maxLength: 128 }
spuId: { type: "UUID", dbColumn: "spu_id", required: true }
colorCode: { type: "String", dbColumn: "color_code", maxLength: 64 }
retailPrice: { type: "Money(CNY)", dbColumn: "retail_price" }
costPrice: { type: "Money(CNY)", dbColumn: "cost_price" }
stockQuantity: { type: "Integer", dbColumn: "stock_quantity" }
skinToneEffect: { type: "String", dbColumn: "skin_tone_effect", maxLength: 32 }
faceShapeEffect: { type: "String", dbColumn: "face_shape_effect", maxLength: 32 }
frameShape: { type: "String", dbColumn: "frame_material", maxLength: 32 }
weightG: { type: "Decimal", dbColumn: "weight_g" }
barcode: { type: "String", dbColumn: "barcode", maxLength: 128 }
metadata:
knowledge: "product-knowledge"
category: "product"
# (Customer, Order, OrderItem, Inventory, StructureStandard,
# DictEffectTag, DictSkuColor, KnowledgeEntry, AgentMemory,
# DraftSpu, SubSku �full entity definitions in source repo)
aliases:
ProductSpu:
"frame shape": "seriesCode"
"style": "spuName"
"tier": "productTier"
"grade": "productTier"
ProductSku:
"color code": "colorCode"
"shade": "colorCode"
"selling price": "retailPrice"
"list price": "retailPrice"
"cost": "costPrice"
"wholesale price": "costPrice"
"stock": "stockQuantity"
"weight": "weightG"
Customer:
"name": "contactName"
"phone": "phone"
"level": "customerLevel"
Order:
"order number": "orderNo"
"total": "totalAmount"
"paid": "actualAmount"
rulesets:
PricingRules:
policies:
- name: "VIP 20% off"
entity: ProductSku
condition:
field: "customer.tier"
operator: eq
value: "VIP"
actions:
- type: calculate
params:
formula: "retailPrice * 0.8"
validations:
- name: "Retail price must be positive"
entity: ProductSku
condition:
field: "retailPrice"
operator: gte
value: 1
actions:
- type: validate
params:
error: "Retail price must be greater than 0"
7. Industry Ecosystem
7.1 Published Industries
| Industry | ERDL File | Entities | Aliases | Status |
|---|---|---|---|---|
| Eyewear Retail | eyewear.erdl | 20 | 150+ | Published |
7.2 Contribute Your Industry
Have industry expertise? You only need to provide the following to participate in EDP Market:
- Industry Entity definitions: describe the core business objects and fields in your industry
- Industry alias table: commonly used terminology, jargon, and their corresponding standard fields
- Business rules: industry-specific validation rules and calculation logic
- agentable actions: common agentor action definitions for your industry
Once submitted, OpenOBA auto-generates a complete industry system prototype—including database, API, and frontend. MIT licensed, free for commercial use, shared ecosystem rewards.
7.3 Planned Industries
| Industry | ERDL File | Expected |
|---|---|---|
| Apparel / Textile | apparel.erdl | 2026 Q3 |
| Beauty / Cosmetics | beauty.erdl | 2026 Q3 |
| Consumer Electronics | 3c.erdl | 2026 Q4 |
| E-commerce / Retail | retail.erdl | 2026 Q4 |
8. Relationship with OpenOBA
ERDL is the core infrastructure of the OpenOBA platform, handling the "semantic understanding" layer. Within OpenOBA's three-layer architecture:
| Architecture Layer | Responsibility | ERDL's Role |
|---|---|---|
| ERDL Protocol Layer | Enterprise business semantics definition and transmission | Core — Entity + Alias + Rulesets + Actions |
| agentor execution Engine | ReAct reasoning chain + Action Guard security intercept | Action Guard loads validation rules from ERDL |
| Cognitive Audit Log | Full-chain traceability and rollback | Audit log records each operation's corresponding ERDL Entity/Action |
ERDL is independently reusable—it is not tied to any specific LLM or agentor framework. Any scenario requiring "make AI deterministically understand business" can independently use ERDL as its semantic protocol layer.
Vision: ERDL's long-term goal is to become the universal semantic standard for enterprise AI applications—like YAML defined configuration and Markdown defined documentation, ERDL defines enterprise business semantics. Human-readable, machine-readable, readable between machines. ERDL source code is MIT licensed, with a full-stack toolchain, open ecosystem, co-created and shared.
Next: Read the ERDL Quickstart Guide to write your first ERDL file, or visit GitHub to browse the full source code.