Ref-001: SEA™ Intermediate Representation (IR) Specification

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

  1. Stable Contract — IR is the only dependency for manifest compilation; AST changes affect only ast_to_ir.py
  2. Lossless Semantics — All domain-relevant information from AST is preserved
  3. Deterministic Output — Same input produces byte-identical output
  4. 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": { ... }
}

Meta Section

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: { ... }

Canonical ID Format

Every symbol has a stable canonical ID:

1
<kind>:<domain>:<name>[@<version>]

Examples:

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"
        }
      }
    ]
  }
}

Flow Classification Tags

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

  1. Canonical IDs — Deduplicate by ID; on conflict, error (no silent override)
  2. Reference Resolution — Convert string references to explicit { kind, id } objects
  3. Deterministic Ordering — Sort all maps by key, arrays by id field
  4. Preserve Names — Do not invent casing; preserve exactly as declared
  5. 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

Flow Annotation Extraction

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:


Validation Gates

Hard Failures (Block Pipeline)

Warnings (Allow but Flag)


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

  1. AST Isolation — Future SEA™ DSL/parser changes only affect ast_to_ir.py
  2. Multiple Backends — Same IR can generate Python, TypeScript, SBVR, RDF, CALM
  3. Semantic Stability — IR is “your contract”; manifest/codegen depend only on IR
  4. Better Diagnostics — Spans preserved for source-line error reporting