Attributes
August 6, 2026 ยท View on GitHub
Attributes are independent schema types. Declare them once in Split-YAML, then use their generated value classes wherever an entity or relation owns them.
Declare attribute types
format: typebridge.schema/v2
attributes:
person-id:
value: string
age:
value:
type: integer
range: {min: 0, max: 150}
email:
value:
type: string
regex: '^[^@]+@[^@]+$'
status:
value:
type: string
values: [active, inactive]
balance:
value: decimal
birthday:
value: date
seen-at:
value: datetime-tz
session-length:
value: duration
audit-note:
independent: true
value: string
The built-in value types are string, integer, double, decimal,
boolean, date, datetime, datetime-tz, and duration. regex, range,
and values constrain the value declaration. doc and meta attach provider
documentation and metadata. independent: true permits an attribute instance
to exist without an owner.
Run type-bridge schema check before generation. Invalid combinations,
unsupported annotations, and scalar constraint mismatches fail in the Rust
schema engine.
Generated values
=== "Python"
```python
from app_models import Age, Balance, Email
from decimal import Decimal
age = Age(36)
email = Email("ada@example.com")
balance = Balance(Decimal("12.50"))
assert age.value == 36
```
=== "TypeScript"
```ts
import { Age, Balance, Email } from "./generated/models/index.js";
const age = Age.create(36n);
const email = Email.create("ada@example.com");
const balance = Balance.create("12.50");
```
=== "Rust"
```rust
let age = Age::new(36);
let email = Email::new("ada@example.com".to_owned());
```
Integer values use Python int, JavaScript bigint, and the generated Rust
integer type. Decimal and duration boundaries remain lossless strings or native
language values according to the generated target API.
Generated attribute classes are projection values, not declaration bases. To rename an attribute or change its scalar/constraint contract, edit Split-YAML, review a migration, and regenerate.
Ownership is separate
An attribute declaration does not imply an owner. Add it under an entity or
relation's owns facts:
entities:
person:
owns:
person-id: {key: true}
age: {card: {min: 0, max: 1}}
email: {unique: true, card: {min: 0, max: 1}}
The generated model constructor and field token are derived from these facts. See cardinality, entities, and generated queries.