Skip to content

The Ontology ​

The ontology is Manifest's shared object model: the object types, action types, and link types an organisation has agreed on, versioned and served as the single source of structural truth.

Types ​

KindDeclares
Object typeThe properties of a thing, its primary unique key, and the match keys duplicate detection uses.
Action typeA governed change: parameters, validation, guards, and the review tier that decides whether a human approves it first.
Link typeA named, directed relationship from one object type to another, traversed from its source to its target.

Derived properties ​

A derived property is computed when it is read, from linked objects: a count, sum, average, min, max or distinct set over a path of 1–3 links, optionally filtered — "open holdings", "total units", "latest review date". It has no writer: no action or pipeline can set it, and it is never stored. It is computed per caller: the linked type's row filters apply inside the aggregate, so a caller never counts what they cannot see, and a caller who may not read the linked type sees the derived property masked. Derived properties can be filtered and sorted on, but not grouped by, matched or used as identity.

Value types, shared property types and structs ​

Three tools shape a property's values, and they compose:

ToolAnswersUse it when
Value typeWhat kind of value is this?A semantic type with rules (an EmailAddress pattern, an IsoCountryCode member set) is used in many places — properties, parameters, struct fields. Every user may only tighten it (rule R-27).
Shared property typeWhich property is this?The same named concept — description, masking — recurs across object types. Interfaces are built from them.
StructWhich values belong together?A few values travel as one (an address). Fields are scalars, enums or references; a list of structs is allowed. A struct is never filtered, sorted or matched on.

A property can use the shared property type emailAddress, which itself narrows the value type EmailAddress. Lists (List<T>) hold scalars, enums, references or structs.

Every type is authored in the designer as data. There is no compiled content assembly, no code deployment to add a type — the designer flow (draft → propose → review → publish) is the only authoring path.

A link is a walkable relation that object sets, agents (TraverseSet<Type>), and the generated SDK traverse. Every link is read from reference properties in the instance data, in one of four ways — open Edit links… on an object type's detail page to declare them:

BackingExampleReadsCardinality
ReferenceClient → its AdvisorClient's advisor: Ref(Advisor) — the link takes the property's nameOne
List of referencesClient → its favourite FundsClient's favourites: List<Ref(Fund)> — the link takes the property's nameMany
Inverse of a referenceAdvisor → its ClientsClient's advisor read backwardsMany
Through an objectClient → the Funds it holdsHolding's client and fund, hopping through each HoldingMany

A link through an object is how a relation carries its own data: the Holding has a share count, a start date, its own security. To reach the Holdings themselves, declare the inverse link too (Client → its Holdings, the inverse of Holding.client).

  • A traversal is a set. A target reached many ways — two clients with one advisor, a fund held twice — appears once, so counts and sums over a traversal are never inflated.
  • The properties must be in the agent view. Traversal reads the agent-view copy of each instance, which holds only the view's properties. The designer refuses a link whose property is hidden, and refuses hiding a property a link reads.
  • The property is held while the link stands. A property that backs a link on its own type cannot be removed, or re-typed to anything that could not back it. Renaming a never-released property renames its link with it; discarding the property drops the link.
  • The rest is checked at review. An inverse or through-an-object link reads other types' properties, so the registry check a release runs (R-24) confirms they exist, reference the right types, and are in their agent views — an approval is refused until they are.
  • Changing links is a proposal like any other. Adding a link is additive; dropping one narrows what consumers can traverse, so the designer files it as breaking.

A warehouse join table is not a link backing: traversal runs over the ontology's own instance data, and warehouse- mapped types are not traversable.

Versions ​

Designs go live by being published as an ontology version — an immutable snapshot of the whole model. Publishing is itself a governed act: the version is validated against the platform's rules, and only a valid version can publish. The published version becomes the serving registry immediately (a hot reload — no restart), and everything downstream regenerates from it, including the agent-facing tool surface.

The fail-closed registry ​

At startup the API hydrates its registry from the store's highest published version and validates it before the host binds a port. The consequences are deliberate:

  • An invalid ontology never serves. A bad publish is a crashed deploy — loud, immediate, and before any traffic — never a 500 at 2am.
  • An empty store boots an empty registry. Day one is a valid state; the first publish populates it.
  • Uniqueness is enforced by the store, not by hope. A type's primary unique key is backed by a unique index on the match index — guards give fast, friendly refusals, but the index is the race-winning truth.

Schema evolution ​

Because instances are event streams, evolving a type's shape is a first-class concern: additive changes are self-healing through the projections, and reshaping changes follow an explicit expand → migrate → contract path so readers never meet a shape they can't handle.

Manifest — the governed ontology layer.