MetaObjects Metamodel — Index
This documents the metamodel itself — the type / subtype / attribute
vocabulary the loader accepts — generated from the strict registry. It is
NOT documentation of a user's entities (that is meta docs --model).
Follow a link into types/<family>.md for the full attribute table, allowed
children, and cardinality of a subtype. Universal documentation attributes
(@description/@title/…) apply to every node and are listed once in
providers.md under metaobjects-documentation.
| Type.subType | Description | Page |
|---|---|---|
attr.base |
Abstract base attribute — the polymorphic/unconstrained value-type marker. Stores its value type-preserved (never stringified), accepting any type; used for an untyped attr (e.g. a field's @default, whose value-type follows the owning field's subtype). Not authored directly: a attr.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/attr.md#attrbase |
attr.boolean |
A boolean-valued metadata attribute. Coerces to and validates as true/false. | types/attr.md#attrboolean |
attr.class |
A class-/type-reference-valued metadata attribute. String-backed (a fully-qualified class or type name) used by binding facets. | types/attr.md#attrclass |
attr.double |
A double-precision floating-point-valued metadata attribute. Coerces to and validates as a number. | types/attr.md#attrdouble |
attr.expression |
A structured expression tree over a base entity's own fields (closed node grammar: field/value refs, comparisons sharing the filter op vocabulary, isNull/isNotNull, and/or/not, coalesce). Backs origin.computed; a filter object embeds canonically. Additive node kinds (arithmetic/case/via-joined refs) are #159. | types/attr.md#attrexpression |
attr.filter |
A filter-expression-valued metadata attribute. Object-shaped value that desugars a preset filter to the canonical { field: { op: value } } form (scalar→eq, array→in, null→isNull; or/and recurse). | types/attr.md#attrfilter |
attr.int |
A 32-bit-integer-valued metadata attribute. Coerces to and validates as a number. | types/attr.md#attrint |
attr.intMap |
An object-shaped attribute whose values are all integers (e.g. field.enum's @intValueMap: {memberSymbol: int}). Generic shape check only; a consumer field type layers its own semantic rules (key-set membership, uniqueness) in its own content-rule validation. | types/attr.md#attrintmap |
attr.long |
A 64-bit-integer-valued metadata attribute. Coerces to and validates as a number. | types/attr.md#attrlong |
attr.properties |
A key/value map attribute (a bag of arbitrary author-supplied properties). Object-shaped value; the registered escape hatch for author-supplied properties (exempt from the strict-attr check, ADR-0023). | types/attr.md#attrproperties |
attr.string |
A string-valued metadata attribute. Coerces to and validates as text; the default value-type for inline @-syntax attrs (array-of-string is the same subtype with isArray). | types/attr.md#attrstring |
field.base |
Abstract base field — the shared root subtype that concrete field subtypes specialize. Carries the attrs common to every field but binds no concrete data type of its own (falls back to string). Not authored directly: a field.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/field.md#fieldbase |
field.boolean |
True/false flag. Binds to the native boolean type; DB column is BOOLEAN. | types/field.md#fieldboolean |
field.currency |
Stores money as integer minor units (cents). Binds to long; the client formats via @currency/@locale. Float arithmetic for money is forbidden. | types/field.md#fieldcurrency |
field.date |
Calendar date (no time-of-day). Binds to the native date/temporal type; DB column is DATE. | types/field.md#fielddate |
field.decimal |
Precision-exact decimal (use @precision/@scale). Native TS binding is string (lossless); DB column is NUMERIC(p,s); the wire form is a string. Classified DATA_TYPE_STRING so an exact decimal is never silently rounded through a double. | types/field.md#fielddecimal |
field.double |
Double-precision (64-bit) IEEE-754 floating point. Binds to the native double/number type; DB column is DOUBLE PRECISION. Not for money — use field.currency or field.decimal. | types/field.md#fielddouble |
field.enum |
String-backed enumeration constrained to a closed set of member symbols (@values). Each member is its own stored string with no name/value divergence. | types/field.md#fieldenum |
field.float |
Single-precision floating point. Binds to the native double/number type (TS has no distinct float); DB column is REAL. Not for money. | types/field.md#fieldfloat |
field.inet |
An IP-address string (IPv4 or IPv6) (ADR-0036/0037 — a concept with a native type + behavior, so a subtype not a @stringFormat). Binds to TS string (TS has no native IP type, same as field.uuid); other ports bind to their native IP type (Java java.net.InetAddress, C# System.Net.IPAddress, Python ipaddress, Kotlin java.net.InetAddress). DB column is the Postgres-native inet type. Codegen emits an IPv4-or-IPv6 literal validator (a Zod regex union in TS — z.string().ip() was removed in Zod 4 — native IP-type parsing in the other ports); add @lenient to bind a plain string with no validator. v1 ships WITHOUT @kind — the native type subsumes ipv4/ipv6; @kind is reserved for a later ipv4|ipv6 value-constraint. | types/field.md#fieldinet |
field.int |
32-bit signed integer. Binds to the native int type; DB column is INTEGER. | types/field.md#fieldint |
field.long |
64-bit signed integer. Binds to the native long/bigint type; DB column is BIGINT. | types/field.md#fieldlong |
field.map |
An open-keyed map (Record<string,V> / dict[str,V]) stored in a single jsonb column. Keys are always strings (the JSON object constraint); the value type is set by @valueType (a scalar field subtype) or @objectRef (a value-object). | types/field.md#fieldmap |
field.object |
A nested structured value (set @objectRef to the target object). Storage is governed by @storage: flattened (prefixed columns), jsonb (single jsonb column, supports isArray), or subdocument (document-store hint). | types/field.md#fieldobject |
field.string |
Variable-length text. Binds to the native string type; DB column is VARCHAR/TEXT (use @maxLength for VARCHAR(n)). | types/field.md#fieldstring |
field.time |
Time-of-day (no calendar date). Binds to the native date/temporal type; DB column is TIME. | types/field.md#fieldtime |
field.timestamp |
Date + time-of-day instant (optionally with timezone). Binds to the native date/temporal type; DB column is TIMESTAMP(TZ). Pair with @autoSet for created/updated stamping. | types/field.md#fieldtimestamp |
field.uri |
A URI/URL string (ADR-0036/0037 — a concept with a native type + behavior, so a subtype not a @stringFormat). Binds to TS string (TS has no native URI type, same as field.uuid); other ports bind to their native URI type (Java java.net.URI, C# System.Uri, Python urllib.parse, Kotlin java.net.URI) and parse scheme/authority/path. DB column is text (Postgres has no uri type). Codegen emits a URL/URI validator (TS Zod z.string().url()). v1 ships WITHOUT @kind — the native type subsumes url/urn; @kind is reserved for a later url|urn value-constraint. | types/field.md#fielduri |
field.uuid |
Logical UUID identity scalar. A bare scalar (no required attrs, no loader value-validation) — binds to TS string (no native UUID type); DB column is Postgres-native uuid. | types/field.md#fielduuid |
identity.primary |
The primary key — one per entity; @fields names its column(s), @generation the value strategy. | types/identity.md#identityprimary |
identity.reference |
A foreign-key reference to another entity (@references target; @enforce toggles a physical FK). | types/identity.md#identityreference |
identity.secondary |
A secondary unique index on one or more fields. Always enforces uniqueness — use index.lookup for non-unique query-performance indexes. | types/identity.md#identitysecondary |
index.lookup |
A non-unique lookup index on one or more fields. Use for query-performance indexes that do NOT enforce uniqueness — declare identity.secondary for unique constraints instead. | types/index.md#indexlookup |
layout.base |
Abstract base layout — the shared root subtype for object-level UI surfaces. A layout attaches a presentation concern (grids, forms, tabs, cards) to an object. The base carries no attrs of its own; concrete subtypes add their presentation attrs. Not authored directly: a layout.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/layout.md#layoutbase |
layout.dataGrid |
A metadata-driven data grid attached to an object: declares the displayed columns, page size, default sort, and an optional preset filter the generated grid renders. | types/layout.md#layoutdatagrid |
metadata.root |
Root metadata document | types/metadata.md#metadataroot |
object.base |
Abstract object base — the shared root subtype that concrete object subtypes (entity/value/projection) specialize. Declares the structural children common to EVERY object subtype (the intersection: field/identity/validator/layout/source); subtype-specific children (relationship, template) and attrs (discriminator) ride their own subtypes. Has no runtime semantics of its own; not authored directly. A object.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED): this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/object.md#objectbase |
object.entity |
An object that owns its data: own identity, writable sources, and lifecycle. The default object subtype — a bare object: key resolves to entity. May co-locate templates (template.prompt and friends) with the owning entity. |
types/object.md#objectentity |
object.projection |
A derived read-only representation of entities. Its fields are extends-bound / origin-derived / self-declared-under-external-assembly, all read-only at the subtype level. Identity is optional and MUST extend an entity identity; sources are restricted to read-only @kinds. The declared field set IS the exposure (inclusive, fail-closed). | types/object.md#objectprojection |
object.value |
A value object — pure shape with NO identity and NO source, ever. Constructed (by caller / embedding), never populated from a store. May extends an entity's fields to reuse shape. Equality is by content. |
types/object.md#objectvalue |
origin.aggregate |
A value reduced from the related row-set reached along a relationship path (@via) from the base entity: count/sum/avg/min/max over a column (@of); any/all predicate quantifiers over a @filter; or collect (an array rollup — of the @of column, or of the carrying field.object's declared @objectRef value object when @of is omitted). | types/origin.md#originaggregate |
origin.base |
Abstract base origin — the shared root subtype for field-level provenance. A field carrying any origin.* is derived ⇒ read-only wherever it lives. The base carries no attrs of its own; concrete subtypes add their provenance attrs. Not authored directly: a origin.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/origin.md#originbase |
origin.computed |
A row-level value computed from the base entity's own fields via a structured expression tree (@expr). No related rows, no @via. Read-only; the expression's inferred type must equal the field's declared subType. | types/origin.md#origincomputed |
origin.first |
The single related row selected by @orderBy along @via, projecting its @of column (argmax then project). Latest = @orderBy desc. Read-only; empty related set (after @filter) → null, so the field must not be @required. | types/origin.md#originfirst |
origin.passthrough |
A cross-entity field reference: this projection field passes a source entity's value straight through (@from), optionally reached via a relationship path (@via). | types/origin.md#originpassthrough |
relationship.aggregation |
A shared/independent containment — the parent groups the target but does not own its lifecycle (default @onDelete set-null). | types/relationship.md#relationshipaggregation |
relationship.association |
A plain reference to another entity — no ownership; the target has an independent lifecycle (default @onDelete restrict). | types/relationship.md#relationshipassociation |
relationship.base |
Abstract relationship base — shared shape for the concrete association/aggregation/composition subtypes; not authored directly. A relationship.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED): this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/relationship.md#relationshipbase |
relationship.composition |
An owned containment — the parent owns the target's lifecycle; deleting the parent deletes the children (default @onDelete cascade). | types/relationship.md#relationshipcomposition |
requirement.architectural |
How the system is built, applied uniformly across the model. Its check is UNIVERSALITY: it fails when something VIOLATES it, which is the opposite polarity to a functional requirement. Flat by default and object-independent; it may optionally sit in a levelled tree when a quality taxonomy is being used to organise non-functional requirements. | types/requirement.md#requirementarchitectural |
requirement.functional |
What the product does for a user, stated as one violable claim. Its check is EXISTENCE: it fails when nothing implements it. Hierarchy is nesting — an L1 solution contains its L2 segments, which contain L3 services, and so on down to the levels that reference the model. | types/requirement.md#requirementfunctional |
source.base |
Abstract base source — the shared root subtype for declaring where an object's data lives (Project E). The base carries no attrs of its own; the concrete paradigm subtype (rdb) carries the physical-storage attrs, which are contributed by the db domain provider. Not authored directly: a source.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/source.md#sourcebase |
source.rdb |
The relational-database paradigm source (ADR-0007): binds an object to a physical relational object. Its physical name is the @table attr (not the structural name), and read-only-ness is DERIVED from @kind — table is writable; view, materializedView, storedProc, and tableFunction are read-only. The @table/@kind/@role/@schema/@parameterRef attrs are contributed by the db domain provider, not by core-types. |
types/source.md#sourcerdb |
template.base |
Abstract base template — the shared root subtype for the fourth pillar (FR-004, ADR-0011). A template is a typed payload bound to either a rendered text artifact (prompt/output) or a tool-call envelope. The base carries no attrs of its own; concrete subtypes add their reference + governance attrs. Not authored directly: a template.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/template.md#templatebase |
template.output |
An output / serialization template (FR-004): every rendered artifact other than an LLM prompt — a document (email, export, docs, config) or an email. Carries the generic reference + governance attrs and the @kind + email part-refs. OUTBOUND ONLY (ADR-0052) — it renders, and generates no parser. | types/template.md#templateoutput |
template.prompt |
An LLM-targeted renderable prompt template (FR-004). Carries the generic reference + governance attrs plus the LLM overlay (@maxTokens / @requiredSlots / @model / @responseRef). Its renderable body is required via @textRef. A prompt declaring @responseRef also owns the INBOUND half (ADR-0052): the parser-on-receipt, the FR-010 response-format fragment (@promptStyle), and the reply syntax (@responseFormat). | types/template.md#templateprompt |
template.toolcall |
A vendor-agnostic LLM tool-call envelope (ADR-0011). Unlike prompt/output it has NO renderable text body — the body IS the structured output schema resolved via @payloadRef. This is why toolcall is its own subtype rather than template.output + @toolName. Does NOT inherit the generic attrs. | types/template.md#templatetoolcall |
validator.array |
Bounds the element count of an array-valued field via @min/@max. | types/validator.md#validatorarray |
validator.atLeastOne |
Cardinality of presence: at least one of the named fields (@fields) must be present (NOT NULL). Entity-scoped; references fields by name (same @fields-by-name pattern as identity.*). | types/validator.md#validatoratleastone |
validator.base |
Abstract base validator — the shared root subtype concrete validators specialize. Carries the @min/@max bounds attrs but enforces no rule of its own. Not authored directly: a validator.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/validator.md#validatorbase |
validator.comparison |
Cross-field ordering: requires two sibling fields of the owning entity stand in a relational order (@left @op @right), e.g. current_hp <= max_hp or expires_at > created_at. Entity-scoped; references fields by name. Backends derive the rule (CHECK constraint, cross-field assertion) — no raw expression is stored. | types/validator.md#validatorcomparison |
validator.length |
Bounds string length / collection size via @min/@max. | types/validator.md#validatorlength |
validator.numeric |
Bounds a numeric value's magnitude via @min/@max. | types/validator.md#validatornumeric |
validator.presentIff |
Biconditional presence: the target field (@field) is present (NOT NULL) if and only if the gating field (@when) equals @equals. Models paired flag/companion-column invariants, e.g. used_at present iff is_used=true. Entity-scoped; references fields by name. | types/validator.md#validatorpresentiff |
validator.regex |
Requires the value match a regular expression (@pattern). | types/validator.md#validatorregex |
validator.required |
Fails when the value is null (NOT NULL). Equivalent to @required on the owning field: on a non-array string, generated wire-tier input validation also rejects the empty string by default unless an explicit validator.length @min: 0 opts back to presence-only. | types/validator.md#validatorrequired |
validator.requiredWhen |
One-directional conditional presence: when the gating field (@when) equals @equals, the target field (@field) must be present (NOT NULL); otherwise @field is unconstrained. Mirrors JSON Schema dependentRequired / Rails validates_presence_of :x, if:. Entity-scoped; references fields by name. | types/validator.md#validatorrequiredwhen |
view.base |
Abstract view base — the shared root subtype for field-level UI/render hints. A view declares how a field's value is rendered or edited; the base carries no attrs of its own. Not authored directly: a view.base node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. |
types/view.md#viewbase |
view.currency |
Currency display formatting (locale-aware via @locale). | types/view.md#viewcurrency |