<!--
Full-page Markdown export (rendered HTML → GFM).
Source: https://neotoma.io/ar/primitives/relationships
Generated: 2026-04-27T12:50:30.624Z
-->
# Relationships
Relationships are first-class typed edges between entities, not hard-coded foreign keys. They are stored as observations and snapshots, so multiple sources can contribute to the same edge, every edge carries full provenance, and the graph stays open-ontology and queryable.
Sits next to entities. Sources produce relationship observations the same way they produce entity observations; the relationship reducer composes them into a relationship snapshot.
## Schema[#](#schema)
Relationship pattern
SQL / TS
Schema or pattern reference for this primitive.
Source → Relationship Observations → Relationship Reducer → Relationship Snapshot // Multiple sources can write the same relationship. // Each write is an immutable observation with its own provenance. // The snapshot merges them with deterministic rules. Source A (Invoice PDF): SETTLES → metadata: { amount: 1500, currency: "USD" } Source B (Bank Record): SETTLES → metadata: { amount: 1500, payment\_method: "wire" } Snapshot (merged): metadata: { amount: 1500, currency: "USD", payment\_method: "wire" } provenance: { amount: "obs\_A", currency: "obs\_A", payment\_method: "obs\_B" }
## Core relationship types[#](#core-types)
PART\_OF (hierarchical containment, e.g. invoice\_line\_item PART\_OF invoice). CORRECTS (corrections supersede originals). REFERS\_TO (mentions / references). SETTLES (payment settles invoice). DUPLICATE\_OF (entity dedupe). DEPENDS\_ON (task ordering). SUPERSEDES (versioning). EMBEDS (container embeds reusable asset, e.g. blog post EMBEDS image).
◆
## Open ontology, not hard-coded hierarchies[#](#open-ontology)
Neotoma does not hard-code parent-child columns or a fixed schema of edge types. Hierarchies emerge from edges, which means out-of-order ingestion, multiple parents, overlapping summaries, and corrections all compose without schema changes. New edge types can be introduced without migrating data.
◆
## Observation-snapshot pattern[#](#observation-pattern)
Each write to a relationship is an immutable observation that carries metadata and provenance. The reducer merges all observations for the same (source\_entity, target\_entity, type) into a single snapshot. The provenance map records, per metadata field, which observation produced which value, exactly the same shape as entity snapshots.
◆
## Queryable in both directions[#](#queryability)
Relationships are first-class rows that can be queried by source entity, target entity, type, or metadata. Read paths support traversals (find all PART\_OF children of an invoice) and reverse lookups (find every entity that REFERS\_TO this contract). Same RLS rules apply, only relationships whose source/target you own are visible.
## Invariants[#](#invariants)
Every relationship satisfies the following constraints:
MUST
- Be stored as immutable observations + a deterministically computed snapshot
- Carry full provenance, every metadata field traces to the observation that set it
- Be typed (PART\_OF / CORRECTS / REFERS\_TO / SETTLES / DUPLICATE\_OF / DEPENDS\_ON / SUPERSEDES / EMBEDS, …)
- Respect source-ownership RLS on every read path
MUST NOT
- Be modeled as foreign keys on entity tables
- Be mutated in place, corrections and supersessions create new observations
- Be created without explicit source\_entity\_id, target\_entity\_id, and type
- Bypass the relationship reducer for ad-hoc snapshot writes
## Related[#](#related)
- [Relationships subsystem doc](https://github.com/markmhendrickson/neotoma/blob/main/docs/subsystems/relationships.md) , Types, graph patterns, query examples
- [Observations](/primitives/observations) , Underlying primitive each relationship observation builds on
- [Entity merge](https://github.com/markmhendrickson/neotoma/blob/main/docs/subsystems/entity_merge.md) , DUPLICATE\_OF mechanics and merge handling
- [Architectural decisions](https://github.com/markmhendrickson/neotoma/blob/main/docs/architecture/architectural_decisions.md) , Why relationships are first-class and the graph is open-ontology
## Where to go next[#](#more)
- [All primitive record types](/primitives) , index of sources, interpretations, observations, relationships, and timeline events
- [Architecture](/architecture) , how the primitives compose into Neotoma's deterministic state
- [Terminology](/terminology) , canonical glossary of terms used across Neotoma docs