The position

Human-first, AI-native.

An elementary fact is the smallest thing a domain expert and a language model can both check.

Most modelling notations were designed for one reader: a person with a whiteboard, or a compiler. Fact-based modelling happens to have been designed for both, forty years before anyone needed it to be. It says everything in sentences, states every rule explicitly, and refuses to leave anything implied. That is what a domain expert needs to approve a model. It is also, exactly, what a language model needs to stop guessing.

A fact type is the rare artifact that is human-readable and machine-checkable at the same time — no summary for the person, no schema dump for the model, no drift between the two.

1artifact, three readers
0attributes to guess at
8MCP tools over the model
~2ktokens for a whole domain, verbalized

Three readers, one artifact

The usual arrangement is three documents that disagree: a diagram for the architects, a DDL file for the database, and a paragraph in a README for whoever comes next. A conceptual schema collapses them, because each reader takes a different projection of the same file.

The domain expert reads sentences

“Each Person works for exactly one Company.” No notation to learn, no legend to consult. They can say no, some contractors work for two — and that is a modelling bug caught before a table exists.

The developer reads a schema

The same model maps to SQL DDL or property-graph DDL, with a note explaining every decision. Nothing was invented in the mapping; it all came from constraints someone approved.

The model reads facts

An LLM's native input format is a sentence. Verbalization hands it the domain as a few hundred declarative sentences with every rule stated — not a picture to interpret, not table names to infer meaning from.

What LLMs have been missing

Point a coding agent at a codebase and it will reconstruct your domain from the only evidence it has: column names, foreign keys, a few migrations and whatever the last developer called things. It reconstructs a plausible domain. Plausible is the problem — the gap is invisible until production.

What the agent can see today

CREATE TABLE enrolment (
  student_id  int,
  course_id   int,
  grade       varchar(2),
  PRIMARY KEY (student_id, course_id)
);

From this it must infer: is a grade required, or pending until the term ends? Can the same student enrol twice, in a later term? Is 'A+' legal? Is an enrolment a thing in the domain, or just a row joining two others? It will answer all four. It has no way to be right.

What the fact layer says

In each population of "Student enrols
  in Course in Term", each Student,
  Course, Term combination occurs at
  most once.
Each Enrolment results in at most one
  Grade.
It is necessary that the possible values
  of Grade are {'A','B','C','D','F'}.
Each Enrolment objectifies exactly one
  "Student enrols in Course in Term" fact.

Four sentences, four answers, none of them inferred. Each was drawn as a constraint, verbalized from the constraint, and confirmed by someone who knows the registry.

Retrieval gives a model text that is similar to your domain. A conceptual schema gives it text that is true about your domain. Those are different problems, and only one of them was ever a search problem.

The fact layer is not a new invention for the AI era — it is the layer the industry skipped. Teams went from a conversation with a domain expert straight to CREATE TABLE, and the reasoning in between was never written down anywhere a machine could read it. Every agent working on that codebase now pays for it, on every prompt.

Why object-role marking, specifically

Plenty of notations claim to be readable. ORM 2 has six properties that matter to a language model, and each of them is a consequence of the same decision: facts carry roles, not attributes.

It is already text

Verbalization is not a rendering of the model, it is the model. There is no picture to caption, no diagram to describe, no vision step that can misread an arrow.

Nothing hides in an attribute

In ER or UML, Person.email silently decides that a person has one email, that it is a property rather than a relationship, and that no rule attaches to it. ORM has no attributes, so those decisions have to be stated — and once stated, they can be read.

Every rule is explicit

Mandatory, uniqueness, frequency, ring, subset, exclusion, value, cardinality — with alethic or deontic modality. An agent never has to decide whether an omission meant optional or nobody thought about it.

Roles name both directions

Person works for Company and Company employs Person are two readings of one fact type. A model asked a question from either side finds the same fact, not a half-modelled inverse it has to guess exists.

Examples travel with the rules

Sample populations are stored in the model and read back through the readings. That is few-shot grounding you did not have to write — and the validator checks the rules against those same examples, so the examples cannot lie either.

It is small

A domain that takes forty tables and six thousand lines of DDL is a few hundred sentences as facts. It fits in a prompt whole, so the agent reasons over the entire domain rather than over the three tables retrieval happened to return.

Human-first is not a slogan about tone

It is about who holds the veto. An AI-native format that only a machine can audit hands authority to the machine. Facts do the opposite: the artifact the agent reads is the same artifact a person can read aloud in a meeting and reject.

  1. The agent proposes. Through factum-mcp it reads the model, changes it, and writes it back — a new fact type, a tightened constraint, a subtype it found implied in the code.
  2. The tool refuses what is broken. apply_model validates before it writes and rejects a model with blocking errors. An agent cannot save an incoherent schema by accident, however confidently it argues for it.
  3. The change comes back as a sentence. Not a JSON diff — - Each Person works for at most one Company. + Each Person works for exactly one Company.
  4. A person decides. That line is in the pull request, posted by the bundled GitHub Action. Approving it takes one reading and no ORM training, which is the only reason the review actually happens.
The loop matters more than any single step. An agent that can propose but not verify produces confident nonsense; a validator with no agent produces nothing. The pairing is what makes the speed safe.

How Factum closes the gap

Every fact-based modelling tool can verbalize. What none of them does is put the result where a machine can reach it — in a text file, in your repository, behind an MCP server, checked by your build.

The agent needs to…In Factum
know what the domain isread_model, verbalize_model
see real examples of a factread_population
check its own changevalidate_model
write the change downapply_model, validated first
get from concepts to a databasegenerate_schema, with notes
explain what it changeddiff_models, in sentences
notice production has moved ondetect_drift against real SQL

None of that needed a chat panel bolted onto a diagram editor. The model already lives in the editor your agent works in; Factum simply stops making the agent guess.

Write the facts down once

Your domain expert gets sentences to approve. Your build gets something to fail on. Your agent gets ground truth instead of a plausible reconstruction. It is the same file.