Facts as First-Class Citizens
Most programming languages start with data structures.
We define classes, structs, records — and then write functions that manipulate them.
This works well for computation. But when we try to model a real-world domain, something subtle breaks down.
The Shape of a Domain
Consider a simple statement:
Alice owns a car.
In most programming languages, this becomes something like a field on an object, a row in a database, or a key-value relationship.
But these representations hide something important: the fact itself is not first-class.
It is encoded indirectly — as a mutable field, as a database entry, as an implicit assumption in code.
And because of that, we lose clarity, composability, and the ability to reason about the domain directly.
A Different Starting Point
Approaches like Object-Role Modeling (ORM2) take a different view.
Instead of starting with objects and attributes, they start with facts:
- Person owns Car
- Car is part of Fleet
- Employee works in Department
Facts are explicit, structured, and close to how we naturally describe systems.
This makes them easier to validate with domain experts, reason about, and evolve over time.
From Modeling to Programs
Spine takes inspiration from this perspective, but explores a different direction.
What happens if facts are not just part of a model, but part of a program?
In Spine, facts are not just documentation or schema. They are elements that can be declared, composed, constrained, and used directly in defining system behavior.
The Asset System
To make this concrete, we will use a simple running example throughout these posts: the Asset System.
At its core, it describes relationships between agents and assets.
We might start with facts like:
- Agent exists
- Asset exists
- Agent owns Asset
- Asset is part of another Asset
These are not yet actions or computations. They are simply statements about what can be true in the system.
Facts Before State
In many systems, we would model ownership as a field:
asset.owner = agent
But this introduces several issues: ownership becomes tied to a specific representation, constraints are implicit, and changes are modeled as mutations.
In a fact-based approach, we instead express:
Owns(Agent, Asset)
This may seem like a small shift, but it has important consequences:
- Ownership is no longer hidden inside a structure
- It becomes something we can reason about directly
- It can participate in constraints and rules
Constraints as Part of the Model
Once facts are explicit, constraints become natural.
For example:
- An asset has at most one owner
- Part-of relationships do not form cycles
These are not comments or external validations. They are part of the system itself. They define what it means for a state of the system to be valid.
Composability of Facts
Because facts are first-class, they can be combined and extended.
We might later introduce:
Control(Agent, Asset)DelegatedAccess(Agent, Asset)
These can relate to existing facts: ownership may imply control, delegation may depend on ownership.
The important point is: we are building a network of relationships, not a hierarchy of objects.
Toward Behavior
So far, we have only described structure: what exists, what relationships can hold, what constraints apply.
But systems do not stand still. They evolve.
Ownership can change. Assets can move. Permissions can be granted or revoked.
In the next step, we will introduce rules that describe how facts can change — and how valid states of the system transition into other valid states.
A Subtle Shift
At first glance, treating facts as first-class elements may seem like a small change.
In practice, it shifts the perspective from manipulating data structures to describing systems in terms of what is true about them.
This shift will allow us to define behavior in terms of constraints, make effects explicit, and eventually reason about entire systems.
Looking Ahead
In the next post, we will extend the Asset System with simple rules: how ownership can be transferred, and what must hold before and after such a change.
This will move us from describing a system to describing how it evolves.
And as we do so, the role of facts will become even more central: they are not just data — they are the foundation on which everything else is built.