Every Stem schema
The index of all seventy Hypermedia schemas Stem publishes, grouped into data types, kind state schemas and RPC methods, with the self-description loop that ties kinds, schemas and the meta-schema together.

Part of Stem. Every type Stem introduces is a Hypermedia schema published as a page of this site, with the schema blob attached as the page's schemaDefinition. This page lists them all. The URL in the first column is the schema's name: other schemas and typed data reference it with that URL, and pin a version with ?v= or an ipfs:// CID.

How to read the groups

Data schemas are the wire and index types: the six signed blobs (Node, Change, Snapshot, Grant, Revocation, Group), the values they are built from (node ids, node references, audiences, subjects, targets), the records the daemon derives (links, facts) and the records privacy bookkeeping keeps (transfers, disclosures, bases), plus scopes and policy rules. Kinds schemas are the state schemas of the core resource kinds; each kind page carries one. RPC schemas are the methods of the sync RPC specification, each a closed struct pinning its key and typing input and output, and the shared read models under rpc/type.

Data

schema

description

data/access-level

The ordered access levels of a grant: sync < read < write < admin. Access composes along a delegation path and is capped at the lowest level on the path.

data/any

Any Stem signed blob: the union of Node, Change, Snapshot, Grant, Revocation and Group, selected by the type tag. The HM24 blobs Ref, Capability, Comment, Profile and Contact are accepted and migrated into these six.

data/audience

An audience is the set of principals a grant speaks about, written as one of five kinds discriminated by kind: everyone, a key, a group, a bearer secret, or the readers of another node.

data/audience/bearer

Anyone who can present a secret: the "anyone with the link" audience. The grant stores only the hash of the secret.

data/audience/everyone

The widest audience: every peer, authenticated or not. A grant to everyone is what makes content public.

data/audience/group

The live members of a group: every principal that holds a live grant on the group at read or above.

data/audience/key

One principal: an account key, or a device or agent key acting for one.

data/audience/readers

Whoever can read another node, evaluated at read time. readers of a space root means "members of the space". Comments use this audience to follow the document they target.

data/basis

Why a peer was allowed to receive a blob. Recorded with every disclosure so revocation and audits can answer "who already has this, and under what authority".

data/change

The library Change, unchanged in layout: Stem only widens deps so that a Change may build on a Snapshot. Identity of a document is still its genesis Change; the Node blob ties that identity to a node id.

data/disclosure

A record that this peer served a blob to another peer, and why. The disclosure ledger is the honest half of revocation: revoking a grant stops future serves, and the ledger says who already holds the bytes.

data/fact

An indexed statement about a resource with its provenance, so a client can tell an author's signed title from a peer's computed comment count.

data/grant

A signed statement that an audience holds an access level over a subject. Grants replace Capabilities and the visibility field: public publishing, private spaces, sharing with one key, share links and group membership are all grants.

data/group

A permanode that establishes a group. Its CID is the group id. The signer is the group's owner and permanent admin. Membership is expressed by grants whose subject is the group.

data/kind

The definition of a resource kind: how its state is represented and validated, whether it is named, whether it has children, how its audience is derived, what it targets, what must be retained, and which fields produce links. The daemon enforces sync and permission semantics by reading this record, so a new kind is a new document, not a protocol change. Kinds are themselves resources of kind kind.

data/link-kind

The nine kinds of link the handler can emit, each with fixed flags for dependency, retention and presentation. New kinds arrive by extending this union.

data/link-rule

Tells the generic handler which field of a kind's state produces which kind of link.

data/link

A derived, typed edge from a blob to a blob or a resource. Links are what the handler emits and what sync, retention, backlinks and audience evaluation read. Exactly one of blob and node is set.

data/name

A relative name a node has inside its parent: one path segment, 1 to 255 characters, no slash, backslash or control characters. Names are chosen by writers and may collide; the resolution rule in Placement decides which node a name shows.

data/node-id

The stable identifier of a node: the CID of the Node blob that created it, written as CIDv1, dag-cbor, SHA-256, base32 lowercase (59 characters starting bafyrei), whatever hash the storing peer uses for its own blob table. The creating Node blob carries no id; every later Node blob for the node carries this value, as a Change carries its genesis. Because the id is a CID, it cannot be forged and the creating blob is always fetchable. An id is never reused. The space root's id is the CID of its deterministic creating blob, so anyone can derive it from the owner's key alone; the bare URL hm://<owner> is an alias for it.

data/node-ref

A reference to a resource by its stable identity: a space and a node id, optionally pinned to a version. This is what links, redirects, policies and RPC inputs use instead of paths.

data/node

The one blob that declares a resource: its identity (space and id), its kind, its placement (parent and name), its state (target), its causal position (prev) and how its audience is derived. It replaces the Ref, including Ref tombstones and redirects.

data/node/access

How a node's audience is derived: inherited from the parent, from its own grants only, or from the node it targets.

data/node/target

The four ways a Node blob specifies a resource's state: a set of Change heads, a Snapshot, a tombstone, or a redirect. Discriminated by kind.

data/node/target/heads

The state is a Change graph and these are its heads. The version is the sorted heads joined with ..

data/node/target/redirect

The resource now lives elsewhere. Readers follow to; links written with this node id keep resolving.

data/node/target/snapshot

The state is one Snapshot blob. The version is that CID.

data/node/target/tombstone

The resource is deleted. Its id stays taken, its history stays retrievable by version, and its name becomes free.

data/peer-id

A libp2p peer id in its multibase string form. A peer id names a device connection, never an account.

data/policy-rule

One line of a sync policy: a scope, what to do about it, with whom, and how often.

data/revocation

A signed statement that cuts a grant. Valid when signed by the grant's issuer (retraction), by the key it was granted to (renunciation), or by a principal with admin over the grant's subject. Revocations are late-bound: the graph is re-evaluated, nothing is deleted.

data/scope

What a sync conversation is about: a node, how deep, and which facets. Both peers derive the same blob set for a scope from their own index, filtered to what the requesting peer may read.

data/snapshot

The complete state of a resource in one signed blob, for kinds whose edits replace the whole value: comments, contacts, schemas, kinds, files and policies. A Snapshot may follow Changes, and a Change may depend on a Snapshot.

data/subject

What a grant covers: a node (with or without its subtree) or a group.

data/subject/group

A group as the subject of a grant. A grant on a group at read makes the audience members of the group; at admin it lets them add and remove members.

data/subject/node

A node, and by default every node placed under it, as the subject of a grant.

data/transfer

A record of one batch of blobs received from a peer, under which claimed scope, and what became of each blob. Transfers are the inbound half of privacy bookkeeping.

data/version

An immutable reference to one state of a resource: the sorted head Change CIDs joined with ., or the single Snapshot CID. Identical to the ?v= value in an hm:// URL.

Kinds

schema

description

kinds/comment/value

The Snapshot value of a comment: what it targets, where it sits in its thread, and its blocks. The comment's identity, author, timestamp and audience come from its Node.

kinds/contact/value

The Snapshot value of a contact: one account's public statement about another. Contacts grant nothing; the join flag is how a grantee accepts a role.

kinds/file/value

The Snapshot value of a file resource: gives a UnixFS tree a stable identity, a name, an audience and provenance. Blocks still embed files by ipfs:// URL; a File node is what lets a file be shared or listed on its own.

kinds/kind/value

The Snapshot value of a kind resource is a Kind descriptor. The kind kind is therefore described by itself.

kinds/policy/value

The Snapshot value of a sync policy: the explicit, inspectable list of what this account's peers follow, pin, fetch on demand or ignore. A policy is a resource in the account's own space with audience key of the account, so only the account's devices receive it.

kinds/schema/value

The Snapshot value of a schema resource is a schema: an instance of the meta-schema. This makes schemas resources that resolve like any other node, without a document and a schemaDefinition indirection.

kinds/space/attributes

Attributes of a space root: what the Profile blob and the home document metadata carried in HM24. Open to further document metadata keys.

RPC

schema

description

rpc/access

Explains what access a principal has to a scope and through which grants. The same evaluator that gates every read and write answers this call.

rpc/authenticate

Binds the calling peer connection to an account, so later calls are evaluated with that account's grants. A peer may authenticate as several accounts on one connection.

rpc/connect

Dials a peer explicitly, for hm://connect/… links and site registration.

rpc/fetch

Serves blobs by CID to a peer that may read them, ordered so that authority arrives before the data it authorizes. Replaces Bitswap: every served blob is checked against the caller's access and recorded in the disclosure ledger.

rpc/get-policy

Returns the sync policy in force on this daemon.

rpc/goodbye

Ends the authenticated bindings and watches on this connection. Closing the connection has the same effect.

rpc/list-disclosures

Reads the disclosure ledger: which blobs this peer has served to which peers and on what basis.

rpc/list-peers

Peer-table exchange. Unchanged from HM24 except for the schema; it carries addresses only, never account bindings.

rpc/list-spaces

Lists the spaces a peer can provide, filtered to what the caller may read. Unauthenticated callers see public spaces only.

rpc/list-transfers

Reads the transfer log: what this peer received, from whom, under which claimed scope, and what became of it.

rpc/method

The union of every Stem sync method, peer-to-peer and local, each variant pinning its method key and typing its input and output.

rpc/offer

Tells a peer that blobs exist for a scope and offers them. The receiver accepts only if its policy wants the scope and the caller can show authority for it, then fetches what it lacks from the caller and validates every blob into the claimed scope. Replaces AnnounceBlobs; there is no longer a push of arbitrary blobs.

rpc/publish

The local ingest call for clients, the CLI and the SDK. It is the same pipeline every transfer goes through: validate, authorize against the claimed scope, index, then offer to the scope's authority peers according to policy.

rpc/reconcile

One round of range-based set reconciliation over a scope. The server derives the scope set from its index, removes every blob the caller may not read, and answers the caller's ranges. Fingerprints are folded over the filtered set, so an unauthorized caller learns nothing about hidden blobs. The server is stateless between rounds.

rpc/set-policy

Replaces the account's sync policy by publishing a new Snapshot of its policy resource. Because the policy is a resource with audience key of the account, the account's other devices receive it through ordinary sync.

rpc/sync-status

Reports the state of syncing for a scope without starting a run.

rpc/sync

Asks the local daemon to bring a scope up to date now, from the space's authority peers and any peers named by policy. Replaces DiscoverEntity and Subscribe: calling it also marks the scope hot for a short while. Standing interest is expressed in the sync policy, not here.

rpc/type/access-report

An explanation of why a principal has, or lacks, access to a scope.

rpc/type/blob-envelope

A blob on the wire: its CID and its bytes. The receiver recomputes the hash and refuses a mismatch.

rpc/type/notification

One live update on a watched scope.

rpc/type/page

Pagination input.

rpc/type/range

One range of a range-based set reconciliation message. Items are (ts, cid) ordered by timestamp then CID bytes; an item's hash is SHA-256 of its CID bytes.

rpc/type/rejection

Why a blob was refused.

rpc/type/sync-status

Progress and outcome of syncing one scope.

rpc/watch

Subscribes the caller to live updates on a scope for the life of the connection. The server streams one notification per indexing commit that adds readable blobs to the scope set. This is the publish-subscribe path that lets comments arrive in seconds without polling.

Self-description

The system describes itself in a loop with four steps, and each step is checked by a validator rather than assumed.

    Every schema on this page is a value that the library meta-schema accepts. The meta-schema is itself one of its own instances (Self-description), so there is one type known without lookup and everything else is reached from it.

    data/kind is the schema of a Kind descriptor: the record that says how a resource kind behaves.

    kinds/kind/value is the state schema of the kind named kind. It is an include of data/kind, so a kind resource's Snapshot value is a descriptor.

    The descriptor of the kind kind names kinds/kind/value as its own state schema. The kind that defines kinds is a resource of itself.

The same closure holds for schemas: kinds/schema/value is an include of the meta-schema, so a schema resource is a node whose value is a schema, and the schemas on this page could each be published as one.

How to validate

Validate a schema file against the meta-schema, or a published value against its schema, with the Seed CLI:

cd /tmp npx -y @seed-hypermedia/cli@0.2.14 schema validate node.schema.json npx -y @seed-hypermedia/cli@0.2.14 schema get hm://z6MkiAKDcRSzQ4zPZfnJcS5HYx5MwgN6MU9foHihJGrhqNBj/stem/data/node --resolve npx -y @seed-hypermedia/cli@0.2.14 document validate hm://z6MkiAKDcRSzQ4zPZfnJcS5HYx5MwgN6MU9foHihJGrhqNBj/stem/kinds/comment

schema validate is strict and exits non-zero on the first violation, printing each as $.path: message. The reference validator in the Seed repository (node scripts/hypermedia/validate.mjs) applies the same rules to the library. Validation of documents in editors stays advisory: a warning, never a blocked write (Typed documents).

See also

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime