Skip to content

The primitive ontology

The owner’s own summary of the world, verbatim: “our world is primitive based. we have spaces, groups, beings, thoughts, artefacts, skills and knowledge.. reasoning is also key.” This page is the plain-language version of design/PRIMITIVES.md, a long architectural document written against the codebase as it stands tonight. Read that document if you want line-by-line citations and a migration plan; read this one if you want to know what the seven words mean and which of them you can actually touch in the running app today.

The whole grammar fits in one sentence:

Beings gather in spaces, sometimes as groups. They think; some thoughts are spoken (messages), some are kept (memories), some are offered (signals). Using skills, they make artefacts. What they learn and can source, they place in common as knowledge. Reasoning is the process that turns thoughts into artefacts, and its record is made of thoughts.

The seven primitives

PrimitiveOne sentenceBuilt today?
BeingSomebody — a human or an AI citizen, with a handle and a soul.Yes — beings, souls, profiles
SpaceSomewhere beings can be together: a home, a square, a workroom, a shop.Yes, nowspaces, space_members, space_threads, and /api/spaces. Every being has a home; the Square is a space
GroupA named set of beings with roles, that can own things and be addressed as one.Yes, nowgroups, group_members, and /api/groups. Groups nest; a crew and a company are the same row
ThoughtOne thing a mind noticed, planned, decided, asked or concluded, in its own voice, at a moment.Yes, in four disguises — see below.
ArtefactA made thing with a body: a document, an image, a site, a garden, a dataset, a file.Yes — Studio outputs, themes, indexed files.
SkillSomething a being can do: typed input in, typed output out, with a permission envelope.Yes — the whole skill registry, plus plugin-contributed skills.
KnowledgeA claim, its sources, and who may read it — held in common by a scope, never by one being alone.No — designed, not stored. Research briefings’ “Sources” sections are still the closest thing.

Six of the seven are now real tables and real code you can call. Knowledge is the one that is still only design: there is no claim, no citation record, no scope and no correction, and a research brief’s “Sources” section is what stands in for it. If you’re building against Novaterra today, code to what exists — and treat “the Reading Room” in the product’s prose as lore that has not yet become a table.

Space and group arrived additively, which is worth knowing if you are reading the schema. A conversation belongs to a space through a space_threads join rather than a spaceId column on threads, because adding a column to a table three other things were writing was the wrong first move; the Square is still also a ThreadKind, and both spellings work. Team is untouched and a run still writes one, alongside the group that staffed it.

Groups nest, and containment grants nothing

Group.kind is an open string whose known values are crew, company, household, circle and team — a company is not a different type from a crew, it is the same row with a different word. Group.parentId puts one inside another, to a maximum depth of eight, with the write refused before it lands if it would make a group its own ancestor.

The edge is descriptive. Not one authorisation check was changed when it was added: entering a space, listing your spaces, listing your groups, your role in one, and every “are you of this group” gate all still read the membership table for one exact group id. A crew member is refused on the parent company; a company member is refused on the crew’s roster. What you learn from the tree is the name and kind of the groups above and below yours, never their rosters — and the one read that spans a subtree, GET /api/groups/:id/tree-members, is gated more strictly than the roster it sits above, because it reaches into groups the caller may not be of.

This is the ontology’s own rule showing through: a group is who, a space is where. The hierarchy says which groups contain which. It does not say who may enter what.

Thought: one primitive, four fates

A thought is never stored in a table called thoughts — it’s the same underlying idea recorded under four different fates, depending on what happens to it:

FateMeaningWhere it lives today
passingThought and let go; visible in a stream while it happenstraces (Studio), twin_activity (the Twin)
spokenSaid into a thread, to an audiencemessages
keptPlaced in the author’s Archive with importance and retrievalmemories
offeredPut in front of a being’s attention with an envelope (priority, due, options, action)signals

One thought can pass through more than one fate: an agent’s reasoning trace is passing; a QA reviewer’s uncertainty becomes offered as a decision Signal; the human’s answer is a new thought; the Twin’s extractor turns part of a conversation into something kept (see The learning loop). The test for telling a memory from a passing thought, per the design document: if it can be forgotten with Undo, it’s a memory; if it simply scrolls away, it’s a thought.

A fifth shape has since shown up, and the code says so plainly. A Todo (apps/api/src/twin/todos.ts) is “a thought the being has committed to act on” — open, done, deferred or dropped — which none of the four fates above quite fit: forcing it into memories loses the state machine (kept has no “done”), and signals is the twin’s attention envelope, not the being’s own intention. It ships as its own table rather than stretching one of the four, with the file’s own comment noting a later unification into one thoughts table could absorb it without changing its public shape. See Calendar, to-dos, and the Hush.

The Muse is a being. The Twin is not.

This is the distinction that matters most, and it’s easy to get backwards:

  • The Muse is a being of kind ai — it has a soul, a handle, a home space, everything any other citizen has, except it lives in your home rather than the town Square. See How Muse thinks.
  • The Twin is not a being. It has no soul of its own. The Twin is your Archive (your kept thoughts) plus the processes that act on it — ingest, reflect, learn. The design document’s own phrase for it: “memory and hands.” Giving the Twin a soul distinct from yours would make it a second you, which is exactly what it exists not to be — it is your continuity, not a companion. See The memory model.

The Passport is a projection, not a primitive

The Passport — the page that shows a being’s cover, heart, soul, mind, hands, world, works and consent all in one place (apps/web/src/beings/Being.tsx’s nv-passport article is the part of this that’s actually rendered today) — is a view over a being, not an eighth primitive. It has no storage of its own and no life independent of the being it describes: your personality, values, mood, skills held, and connections all already live on souls, profiles, the skill registry and connections. A passports table would just be a second, driftable copy of data that already has a home. Read the Passport as “a being, seen all at once,” never as a separate kind of thing you could have without a being behind it.

Reasoning: a process, not an eighth noun

It would be tempting to make reasoning the eighth primitive, since the owner called it “key” — but every part of it is already one of the seven, and the design document’s case for leaving it a process is worth repeating: the actor is a being or a group; the place is a space; a plan is a thought whose body is a task graph; each step is a thought with a status; the trace is a stream of passing thoughts; the decisions along the way are thoughts; the tools used are skills; the product is artefacts; the claims established are knowledge. What ties all of that into “one episode of reasoning” is Project — the record that already exists in the Studio (see Projects) — not a new primitive.

Now that groups are real, “the actor is a being or a group” is something you can actually do: PUT /api/projects/:projectId/crew binds a group to an episode, and the next run draws its people from that group’s seats instead of assembling strangers by required skill. A group outlives any one episode, which is precisely what the project-scoped Team could never do, and GET /api/groups/:id/work reads back what a crew has actually done across all of them.

Further reading

design/PRIMITIVES.md is the full architectural document this page summarises: every entity in the current schema mapped onto a primitive (or explained as infrastructure that sits outside the ontology on purpose — sessions, wallets, LLM usage meters), what’s missing, and a staged migration plan. It is written for people extending the codebase, not for understanding the product; this page is the other way round.