Entities

The foundational data objects that your system operates on

What are Entities?

Entities are the domain objects in your system. A user, a workspace, a subscription, an invoice — each is an entity with typed fields, constraints, and a module assignment. Entities are declared in YAML and become nodes in the AI System Graph, giving AI agents and the compiler a formal understanding of your data model.

Unlike database schemas or ORM models, entity specs are framework-agnostic. They describe what the data looks like and what rules it must follow, not how it is stored. The compiler and runtime use entity specs to generate types, validate inputs, and enforce invariants.

EntitySpec Structure

interface EntitySpec {
  name: string;          // unique entity name, e.g. "user"
  description: string;   // human-readable description
  fields: EntityField[]; // typed fields with constraints
  module: string;        // owning module, e.g. "users"
  invariants?: string[]; // invariant names bound to this entity
}

Field Types

Each field has a name, a type, a required flag, an optional description, and optional constraints.

interface EntityField {
  name: string;
  type: string;              // string, number, boolean, date, enum, reference
  required: boolean;
  description?: string;
  constraints?: FieldConstraint[];
}

Supported field types include:

Field Constraints

Constraints are declarative rules attached to individual fields. They are checked by the runtime and surfaced in generated metadata.

Constraint TypeValue TypeExample
minnumberAmount must be at least 0
maxnumberQuantity must not exceed 1000
minLengthnumberName must be at least 1 character
maxLengthnumberName must not exceed 255 characters
patternstring (regex)Email must match a valid email pattern
enumstring[]Status must be one of [active, cancelled, past_due]
uniquebooleanEmail must be unique across all records

Each constraint can also carry an optional message string for custom error messages.

Module Assignment

Every entity belongs to exactly one module, declared via the module field. This assignment creates a belongs_to edge in the AI System Graph from the entity node to the module node. Module boundaries control which capabilities can access which entities — a capability in the billing module can only reference entities from billing or from modules listed in billing's allowedDependencies.

Invariant Binding

Entities can declare a list of invariant names via the invariants field. These are business rules that must hold for the entity — for example, "email must be unique across all users" or "invoice amount must be positive." Each invariant binding creates an enforces edge in the graph from the invariant node to the entity node.

YAML Example: SaaS Billing

Here are the user and subscription entities from the SaaS billing example app:

entities:
  - name: user
    description: A registered user who can own workspaces and subscriptions
    module: users
    fields:
      - name: id
        type: string
        required: true
        description: Unique user identifier
      - name: email
        type: string
        required: true
        description: User email address
      - name: name
        type: string
        required: true
        description: Display name
      - name: role
        type: string
        required: true
        description: System role (admin, member, billing_admin)
      - name: created_at
        type: date
        required: true
        description: Account creation timestamp
    invariants:
      - email_must_be_unique

  - name: subscription
    description: A billing subscription linked to a workspace
    module: billing
    fields:
      - name: id
        type: string
        required: true
        description: Subscription identifier
      - name: workspace_id
        type: string
        required: true
        description: Workspace this subscription belongs to
      - name: plan
        type: string
        required: true
        description: Subscription plan (free, pro, enterprise)
      - name: status
        type: string
        required: true
        description: Subscription status (active, cancelled, past_due, trialing)
      - name: billing_cycle
        type: string
        required: true
        description: Billing cycle (monthly, yearly)
      - name: current_period_start
        type: date
        required: true
        description: Start of current billing period
      - name: current_period_end
        type: date
        required: true
        description: End of current billing period
    invariants:
      - subscription_must_have_workspace
      - no_duplicate_active_subscription

How Entities Participate in the Graph

Each entity creates the following relationships in the AI System Graph:

These edges let AI agents trace from an entity to everything that touches it: which capabilities read or write it, which invariants constrain it, which module owns it, and which flows involve it.

AI-Safe Change Workflows

When an AI agent proposes to modify an entity (adding a field, changing a type, removing a constraint), the Change Protocol uses the AI System Graph to compute the full impact. Every capability that uses_entity on the modified entity is flagged. Every invariant that enforces on it is checked. Every generated route handler, test scaffold, and metadata file that references the entity is listed for refresh. This ensures the agent understands the full blast radius before making the change.