Relationships at a glance
The modelling decision
| The related thing is | Model as | Because |
|---|---|---|
| Mastered — an entity you keep | A relationship | The related entity owns its data; copies drift |
| Not mastered — no record kept | An attribute | Otherwise you invent an entity you do not master |
Never both. Two copies of one fact diverge.
Resolution by natural key
Source systems reference the other endpoint by whatever they hold — a tax identifier, an account number — not by a platform identifier.
Each source's claim is recorded as an assertion in its own right, before any link is made. That separation is what makes out-of-order loading work: the assertion records what the source said, whether or not the platform could act on it yet.
Nothing is guessed. An assertion that cannot be resolved unambiguously waits rather than picking a candidate.
States
| State | Meaning |
|---|---|
| Pending | Target not found yet; retried as data arrives |
| Resolved | A canonical edge exists |
| Ambiguous | The key matched several candidates |
| Conflicted | The target resolved, but the edge could not be created |
| Rejected | A steward rejected it |
| Expired | The source stopped asserting the fact |
Effectivity
Relationships carry an effective period, so a link that ends is closed, not deleted. Asking who held it last March returns the right answer.
Cardinality is evaluated within the window, so a one-per-endpoint relationship can legitimately have several historical occupants.
A signal worth reading
Recurring ambiguity on one rule says the key is not as identifying as assumed. Fix the rule rather than deciding the same class of case repeatedly by hand.
Next
Last verified against commit 1e1de1ad (2026-08-03)