Skip to main content
Services group operations by ownership. Schemas describe the logical shape of the values that flow through those operations, transactions, and effects. Neither implies a physical boundary: a service is not a process, host, or trust boundary, and a schema is not a storage layout or wire format.

Services

A service is a logical ownership and grouping boundary for operations. The current service kinds are:
  • backend
  • frontend
  • worker
  • job
These are descriptive classifications only. A service kind does not by itself imply:
  • a process boundary
  • a network hop
  • a host or container
  • a trust boundary
  • a replica count
  • availability semantics
  • concurrency
  • transactional boundaries
  • or failure independence
Those facts must come from other declarations when they matter to a proof. For example, two operations in the same service may target different execution pools, and two operations in different services may share one pool.

Schemas

Canonical schema

A canonical schema describes the complete logical shape of a value. Its fields have a type and an optional flag.

completeness

  • complete claims that the declaration describes the complete logical schema. Subject to conformance, the verifier may treat a field absent from a complete schema as nonexistent.
  • partial explicitly permits the real schema to contain undeclared fields. The verifier may reason about declared fields, but it must not infer that undeclared fields do not exist.

Fragment schema

A fragment is a projection or aliasing view over another declared schema:
source identifies the source schema. mapping maps each fragment field name to a FieldPath in the source. A mapping asserts semantic identity of the referenced value across the fragment boundary, so it may preserve value lineage even when a field is renamed. A fragment does not:
  • create a new independent value
  • create a new storage object
  • imply that unmapped source fields are absent
  • or establish ordering or idempotency by itself
Fragment chains must remain acyclic and resolvable.

Field types

Scalar types

The current primitive logical types are: string, bool, int, float, decimal, uuid, timestamp These are logical types. No storage width, precision, locale, timezone encoding, or wire representation is implied beyond what the scalar name itself requires.

Schema reference

References another declared schema as the logical type.

List

Declares a collection of values of the nested type. A list does not itself imply uniqueness, sortedness, stable ordering across executions, bounded length, or set semantics.

Shorthand syntax

A field and its type may be declared in shorthand instead of the canonical map:
The type grammar is type := scalar-name | schema-id | "[" type "]", with an optional trailing ? on the field as a whole.
  • A name matching a scalar name is that scalar; every other name is a schema reference. A schema whose id collides with a scalar name, or ends in ?, must be declared in the canonical map form.
  • ? states optionality of the field, not of a type, so it may not appear inside one. [string?] is an error; an optional list is written "[string]?".
  • A list shorthand holds exactly one element type.
  • The shorthand may also be used for ty alone inside the canonical map, as in ty: [schema.Tag] with optional: true.
The shorthand is an authoring affordance. Serialization always emits the canonical map, so a serialized model remains a single explicit form for tooling.

Field paths

A field path identifies a nested value relative to a schema. For example, [customer, id] means the id field nested under customer. The canonical form is a sequence of components. A dotted name says the same thing:
A component containing a . must use the sequence form. Whether a path resolves is asked of the schema, not of the surface syntax.