Understanding the substrate

The substrate is a datastore for one person's digital life: messages, mail, calendar events, people, tasks, notes, media. One graph of typed entities behind one API. It is the system of record personal software builds on, instead of every app keeping its own silo.

The problem it answers is fragmentation. Every question that crosses two apps ("what did Alex ask me before this meeting?") is an integration project, because nothing shares identity, nothing shares change notification, and nothing offers a safe way for semi-trusted automation to write.

The design borrows deliberately from Kubernetes, the most battle-tested answer to "many semi-trusted programs cooperating over shared typed state":

Everything on these pages builds one running example: a to-do list.

Substrate and teild

Two words, used precisely. Substrate is the protocol, the service, and the implementation: the typed graph, the API, the primitives these pages describe. teild is the parent, the organization level above it. That split shows up in one visible place: groups are named under the org's domain, tasks.teild.dev, people.teild.dev, while the product and protocol vocabulary, in the docs, the CLI (ssctl), and the service, is "substrate".

Six words

Like Kubernetes, the whole system is rules about a handful of primitives.

TermMeaning
TenantOne person's fully isolated dataset, with its own Postgres schema and its own tokens. The service holds many; the data inside one is strictly single-person.
GroupA DNS-named namespace of entity types owned by one authority: people.teild.dev, tasks.teild.dev. Groups namespace names; they never partition the graph.
Entity typeThe definition of one thing the graph can hold: its properties and its edges. A type belongs to exactly one group, and its full name is <type>.<group> (task.tasks.teild.dev).
EntityOne instance of an entity type, and the only thing there is. Tasks, people, tokens, and type declarations are all entities. Its identity is the full triple (group, type, id).
PropertyA named, typed value slot on an entity: title, dueAt. Declared on the entity type, validated on every write.
EdgeA named, directed relationship from one entity to another, and the only way one entity points at another. Declared on the entity type it points from.

The map

The pages ahead, in reading order:

Next: the data model, the one shape everything reads and writes as.