Document Type
Reference / Schema Specification
Purpose
Defines the SEA™ Intermediate Representation (IR) v1.0 — a stable, normalized semantic graph contract between AST parsing and manifest generation that isolates the compilation pipeline from AST format changes.
Design Principles
- Stable Contract — IR is the only dependency for manifest compilation; AST changes affect only
ast_to_ir.py
- Lossless Semantics — All domain-relevant information from AST is preserved
- Deterministic Output — Same input produces byte-identical output
- Schema-Gated — CI validates IR against
sea_ir.schema.json before further processing
IR Philosophy
SEA™ IR is a normalized semantic graph, not a mirror of AST parsing quirks:
1
2
3
4
5
6
| symbols → entities/resources/roles/patterns/relations/dimensions/units
behavior → flows (typed: command/query/event)
constraints → policies (expression trees)
facts → instances, concept changes
measures → dimensions/units/metrics
directives → mapping/projection declarations
|
SEA™ IR v1.0 Schema
Top-Level Structure
1
2
3
4
5
6
7
8
9
10
11
| {
"irVersion": "1.0",
"meta": { ... },
"symbols": { ... },
"behavior": { ... },
"constraints": { ... },
"facts": { ... },
"measures": { ... },
"codegenDirectives": { ... },
"diagnostics": { ... }
}
|
| Field |
Type |
Required |
Description |
namespace |
string |
✅ |
Bounded context name (hard-required) |
version |
string |
❌ |
Semantic version of the context |
profile |
string |
❌ |
DSL profile (e.g., “default”) |
owner |
string |
❌ |
Owning team |
imports |
array |
❌ |
Imported symbols from other contexts |
source.astSchema |
string |
✅ |
AST schema version (e.g., “ast-v3”) |
source.seaVersion |
string |
✅ |
SEA™ CLI version (pinned in CI) |
Symbols Section
1
2
3
4
5
6
7
8
9
10
| symbols:
entities:
"entity:orders:Order": { id, name, domain, version, annotations, fields }
resources:
"resource:orders:Money": { id, name, domain, unit }
roles: { ... }
patterns: { ... }
relations: { ... }
dimensions: { ... }
units: { ... }
|
Every symbol has a stable canonical ID:
1
| <kind>:<domain>:<name>[@<version>]
|
Examples:
entity:orders:Order@1.0
resource:orders:Money
policy:orders:TotalMustBePositive@1.0
flow:orders:PlaceOrder
role:orders:Customer
Behavior Section (Flows)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| {
"behavior": {
"flows": [
{
"id": "flow:orders:PlaceOrder",
"resourceRef": {
"kind": "resource",
"id": "resource:orders:PlaceOrder"
},
"fromEntityRef": { "kind": "entity", "id": "entity:orders:Customer" },
"toEntityRef": { "kind": "entity", "id": "entity:orders:Order" },
"quantity": null,
"tags": ["command"],
"runtime": {
"transactional": true,
"idempotency": { "enabled": true, "key": "header:X-Idempotency-Key" },
"outbox": "required"
}
}
]
}
}
|
| Tag |
Meaning |
Required Annotations |
command |
Write operation |
@cqrs { "kind": "command" }, @tx |
query |
Read operation |
@cqrs { "kind": "query" } |
event |
Domain event publication |
@cqrs { "kind": "event" }, @outbox |
Constraints Section (Policies)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| {
"constraints": {
"policies": {
"policy:orders:TotalMustBePositive": {
"id": "policy:orders:TotalMustBePositive",
"name": "TotalMustBePositive",
"domain": "orders",
"version": null,
"metadata": {},
"expression": {
"kind": "op",
"op": ">",
"args": [
{ "kind": "ref", "path": "Order.total.amount" },
{ "kind": "literal", "type": "decimal", "value": "0" }
]
}
}
}
}
}
|
Expression IR
Policies use a structured expression tree (not strings):
| Kind |
Description |
Fields |
literal |
Constant value |
type, value |
ref |
Field path reference |
path |
op |
Binary/unary operation |
op, args[] |
call |
Function call |
fn, args[] |
aggregate |
Aggregation function |
fn, over |
Facts Section
1
2
3
4
5
6
| {
"facts": {
"instances": [],
"conceptChanges": []
}
}
|
Measures Section
1
2
3
4
5
6
7
| {
"measures": {
"dimensions": {},
"units": {},
"metrics": {}
}
}
|
Codegen Directives Section
1
2
3
4
5
6
| {
"codegenDirectives": {
"mappings": [],
"projections": []
}
}
|
Diagnostics Section (Optional)
1
2
3
4
5
6
7
8
| {
"diagnostics": {
"spans": {
"entity:orders:Order": { "line": 5, "column": 1 },
"flow:orders:PlaceOrder": { "line": 12, "column": 1 }
}
}
}
|
Normalization Rules
- Canonical IDs — Deduplicate by ID; on conflict, error (no silent override)
- Reference Resolution — Convert string references to explicit
{ kind, id } objects
- Deterministic Ordering — Sort all maps by key, arrays by
id field
- Preserve Names — Do not invent casing; preserve exactly as declared
- Domain Inference — If node lacks domain, inherit from
metadata.namespace
AST v2 → IR Mapping Rules
Based on AstNode variants from ast.rs:
| AST Node |
IR Location |
ID Pattern |
Entity |
symbols.entities |
entity:<namespace>:<name> |
Resource |
symbols.resources |
resource:<namespace>:<name> |
Flow |
behavior.flows |
flow:<namespace>:<resource_name> |
Policy |
constraints.policies |
policy:<namespace>:<name> |
Role |
symbols.roles |
role:<namespace>:<name> |
Relation |
symbols.relations |
relation:<namespace>:<name> |
Pattern |
symbols.patterns |
pattern:<namespace>:<name> |
Dimension |
measures.dimensions |
dimension:<namespace>:<name> |
UnitDeclaration |
measures.units |
unit:<namespace>:<name> |
Metric |
measures.metrics |
metric:<namespace>:<name> |
MappingDecl |
codegenDirectives.mappings |
mapping:<namespace>:<name> |
ProjectionDecl |
codegenDirectives.projections |
projection:<namespace>:<name> |
Instance |
facts.instances |
instance:<namespace>:<entity>:<id> |
ConceptChange |
facts.conceptChanges |
(array entry) |
Export |
Unwrap inner node, set exported: true |
— |
Flows must include annotations for runtime semantics:
Flow "PlaceOrder"
@cqrs { "kind": "command" }
@tx { "transactional": true }
@idempotency { "enabled": true, "key": "header:X-Idempotency-Key" }
@outbox { "mode": "required" }
from "Customer" to "Order"
The ast_to_ir.py compiler extracts:
tags from @cqrs.kind
runtime.transactional from @tx
runtime.idempotency from @idempotency
runtime.outbox from @outbox
runtime.readModel from @read_model (for queries)
Validation Gates
Hard Failures (Block Pipeline)
metadata.namespace missing or empty
- Flow references non-existent entity/resource
- Duplicate canonical IDs
- Unknown AST schema version
Warnings (Allow but Flag)
- Entity without fields (may be incomplete)
- Flow without CQRS classification (linter catches)
Pipeline Position
1
2
3
4
5
6
7
8
9
| SEA™ DSL (.sea)
↓ sea parse --format json
AST JSON (validated against ast-v3.schema.json)
↓ tools/ast_to_ir.py
SEA™ IR JSON (validated against sea_ir.schema.json) ← THIS SPEC
↓ tools/ir_to_manifest.py
Manifest JSON (validated against manifest.schema.json)
↓ tools/codegen/gen.py
Generated Code (src/gen/**)
|
Benefits of IR Layer
- AST Isolation — Future SEA™ DSL/parser changes only affect
ast_to_ir.py
- Multiple Backends — Same IR can generate Python, TypeScript, SBVR, RDF, CALM
- Semantic Stability — IR is “your contract”; manifest/codegen depend only on IR
- Better Diagnostics — Spans preserved for source-line error reporting