SEA™ DSL Idioms

13 proven patterns for scalable, maintainable SEA™ DSL models.


P01: Namespaces as Contracts

Intent: Use @namespace and domain qualifiers for safe merging.

// ✅ Good
@namespace "com.example.payments"
@namespace "com.example.finance"

Entity "PaymentProcessor" in com.example.payments
Resource "Money" USD in com.example.finance

// ❌ Bad - ambiguous when composed
Entity "PaymentProcessor"        # no domain
Resource "Money" USD             # collides easily

P02: stdlib as Base Layer

Intent: Import std:* modules as foundational vocabulary.

// ✅ Good
import * as Std from "std:core"
import { HTTP_Request as Req } from "std:http"

// ❌ Avoid
// Re-declaring primitives already in std

P03: Explicit Resource Scope

Intent: Scope resources with unit + domain to prevent collision.

// ✅ Good
Resource "Money" USD in finance
Resource "Token" units in auth

// ❌ Bad
Resource "Money"       # loses unit semantics

P04: Flow Annotation Contract (REQUIRED)

Intent: Every Flow requires @cqrs annotation.

// ✅ Good - all required annotations
Flow "CreateOrder"
  @cqrs { "kind": "command" }
  @tx { "transactional": true }
from "Customer" to "Order"

Flow "OrderCreated"
  @cqrs { "kind": "event" }
  @outbox { "mode": "required" }
from "Order" to "EventBus"

// ❌ Bad - missing @cqrs
Flow "CreateOrder" from "A" to "B"

// ❌ Bad - dotted key (invalid)
Flow "GetData" @cqrs.kind "query" from "A" to "B"

Validation: flow_lint.py --strict rejects missing annotations.


P05: Flow Name Matches Resource

Intent: Name flows after the resource being moved.

// ✅ Good
Resource "Token" units in auth
Flow "Token"
  @cqrs { "kind": "command" }
from "User" to "User" quantity 1

// ⚠️ Acceptable but breaks convention
Flow "IssueToken" from "User" to "User"

P06: Relations Explain Meaning

Intent: Use Relation for semantic triples (SVO).

// ✅ Good
Relation "PaidBy"
  subject: "Invoice"
  predicate: "is paid by"
  object: "Payment"
  via: flow "Money"

P07: Policies as Constraints

Intent: Policies are machine-checkable expressions, not comments.

// ✅ Good
Policy no_negative_amount
  per Constraint Prohibition priority 10
  @rationale "Avoid invalid invoices"
  @tags ["billing", "validation"]
as: (amount >= 0)

// ❌ Bad - not a boolean expression
Policy validate_amount as:
  "Amounts should not be negative"

P08: Policy Scope via Quantifiers

Intent: Use forall/exists over collections.

// ✅ Good
Policy all_money_flows_positive as:
  forall f in flows: (f.resource = "Money" and f.quantity > 0)

// ❌ Bad - free variable (unbound)
Policy check_flow as: (f.quantity > 0)  # f is unbound

P09: Metrics Use Comprehensions

Intent: Metrics are aggregations with operational annotations.

// ✅ Good
Metric "payment_count" as:
  count(f in flows where f.resource = "Money": f.quantity)
  @threshold 100
  @severity "warning"
  @refresh_interval 300 "seconds"

P10: Instances for Scenarios

Intent: Use instances for concrete test/example data.

// ✅ Good
instance inv123 of "Invoice" {
  amount: 100 "USD",
  paid: false
}

Policy inv_has_amount as: (@inv123.amount > 0)

P11: Evolution is Explicit

Intent: Version changes with @replaces and ConceptChange.

// ✅ Good
Entity "Vendor" v1.0.0 in procurement

Entity "VendorV2" v2.0.0
  @replaces "Vendor" v1.0.0
  @changes ["added credit_limit", "added payment_terms"]
in procurement

ConceptChange "Vendor_v2_migration"
  @from_version v1.0.0
  @to_version v2.0.0
  @migration_policy mandatory
  @breaking_change true

P12: Model Minimum Then Refine

Intent: Start with skeleton, layer semantics progressively.

// Step 1: Basic structure
Entity "User" in auth
Resource "Token" units in auth
Flow "Token" @cqrs { "kind": "command" } from "User" to "User" quantity 1

// Step 2: Add constraints
Policy token_quantity_is_one as:
  forall f in flows: (f.resource = "Token" and f.quantity = 1)

P13: Mapping vs Projection

Intent: Use Mapping for structure, Projection for field transforms.

// Mapping: structure-first with target types
Mapping "SEA->CALM" for calm {
  Entity "Customer" -> CalmEntity { kind: "Actor", active: true }
}

// Projection: field/property transforms
Projection "SEA->KG" for kg {
  Entity "Customer" { nodeLabel: "Customer", props: {"id"->"customer_id"} }
}

Anti-Patterns

ID Symptom Fix
A01 Missing @cqrs on Flow Add @cqrs { "kind": ... }
A02 Dotted annotation keys Use nested JSON: @cqrs { "kind": "command" }
A03 Free identifiers Bind with forall/exists or @instance
A04 Domainless concepts Add explicit in <domain>
A05 Inert policies Ensure expression is boolean over real fields

Last Updated: January 2026