Links
The nine kinds of typed link a Stem daemon derives from blobs, what each one means for dependency, authority, placement, presentation and reference, which are built in and which come from a Kind's link rules, and how sync, retention, backlinks and audience evaluation read them.

Part of Stem. This page defines links: the typed edges the handler emits from a blob to another blob or to a resource. Links are derived, never stored in blobs; what is stored is the CID or URL the link was read from. Everything downstream of indexing reads links: what to fetch first, what to keep, what to show as a backlink, which blobs a node's readers may see.

The record

A link has a source blob, a kind, and exactly one of a target blob (by CID) or a target resource (by node reference, optionally at a version). It may carry an anchor, the block or field in the source where it was found, and a fragment, the block or range in the target it points at.

The earlier Stem page asked whether everything can be a named link with a weight made of flags. The answer Stem gives is yes with the flags fixed per kind: a link's kind determines its flags, so peers that agree on the kinds agree on the flags, and no weight needs to travel. Weights remain a runtime convenience a daemon may compute for its scheduler and collector.

The nine kinds

Kind

Source

Target

Dependency

Authority

Placement

Presentation

Reference

Retained with source

dep

Change, Node (heads)

Change, Snapshot

yes





yes

prev

Node, Snapshot

Node, Snapshot

yes





yes

proof

Node, Grant

Grant, Group


yes




yes

parent

Node

node



yes




schema

Node (kind), Snapshot (schema)

node




yes



file

Change, Snapshot

file blob




yes


yes

embed

Change, Snapshot

node (at version)




yes



link

Change, Snapshot

node (at version)





yes


mention

Change, Snapshot

node, account





yes


target

Snapshot (comment, contact)

node (at version), account





yes


The columns mean:

    Dependency. The target must be applied before the source has meaning. The fold follows dep and prev; a Change whose dep target is missing is stashed.

    Authority. The target is evidence of the source's right to exist. Fetch serves proof targets before their sources, and the authority graph is built from them.

    Placement. The target is where the source sits in the tree. parent links are what make a move one blob: children hold a parent link to an id, not to a name.

    Presentation. The target is needed to render or validate the source fully. A reader following a scope with the files facet fetches file targets; the schema target is fetched to validate and to show typed attributes; embed targets are fetched for a full-fidelity rendering but a missing embed is a broken embed, not a broken document.

    Reference. The target is mentioned. Citations and backlinks are the reverse direction of link, mention, embed and target.

    Retained with source. A peer that keeps the source under its policy must keep the target: dependencies, proofs and files. Embeds, links and mentions are not retained; a peer that follows a document does not thereby follow everything it cites.

The earlier page's five flags map onto these columns: state dependency is dep and prev; retention is the last column; presentation dependency is schema, file and embed; ordinary dependency is link and mention; authority evidence is proof. Parent documents, which the board left open, are parent links from child to parent, and the reverse direction (children) is a derived fact on the parent, not a link.

Built in or declared

Five kinds are structural and the handler emits them from the fields every blob of that type has: dep from Change deps and Node target.heads; prev from Node prev and Snapshot prev; proof from Node proof and Grant proof; parent from Node parent; schema from Node kind and Snapshot schema. No kind can switch them off.

Four kinds are content links and the handler finds them where the Kind descriptor's link rules say to look: a JSON Pointer into the state value, and the kind to emit for hm:// and ipfs:// references found there. The document kind's rules name the block tree: an Embed block or inline embed produces embed, a Link block or link annotation produces link, an inline embed whose text is the object replacement character produces mention, an Image, File or Video block produces file. The comment kind's rules name /target for target and /body for the same block rules as documents. The contact kind's rules name /subject for target. A third-party kind declares its own.

This is how a new kind arrives without a protocol change: its descriptor says where its references are, and the handler, sync, retention and backlinks work for it on the first day.

Hyperedges

The board asked whether the runtime needs hyperedges, because a comment or an embed points at a resource at a version, and a version can be several heads. Stem answers with the record shape: a link to a resource carries a node reference whose version field is the sorted head CIDs joined with ., which is one string. The link is binary (source blob to node reference) and the version is a property of the edge. Nothing needs reifying.

Labels beyond CIDs

Whether one physical blob may carry several labels (CID, a Git object id, a Nostr event id) is left open. Stem's reading stands: a label would be a fact about a blob emitted by a handler that recognised the foreign id, and the store would index labels so that a link written in a foreign namespace resolves to the local blob. No core kind needs it, and it is tracked in Open questions.

Who reads links

    Sync. A scope set is the closure of the scope's nodes over dep, prev, proof, file and (for the comments facet) the reverse of target. Fetch orders its answer by walking proof first, then parent, then dep and prev from the roots down, then file. See The sync protocol.

    Retention. A pinned or followed node pins the closure of its retained kinds. A collector may drop anything outside every retained closure.

    Blob access. The same structural closure (dep, prev, file, the Node blob) is what maps a blob to a node for readers. Content links never carry access, as Privacy explains.

    Backlinks. Citations on a node are the link, embed, mention and target links whose target is that node, filtered to sources the reader may read, with the anchor and fragment telling the reader where. This is today's citations table generalised to every kind.

    Notifications. mention and target links whose target is an account or a node the account owns are what a notification is derived from. See Agents and notifications.

Today (HM24)

Today

Stem

blob_links with free-form type strings (change/dep, ref/head, doc/Embed, comment/target, dagpb/chunk and more)

nine fixed kinds, each with fixed flags

resource_links for hm:// URLs found in content, with pinned flag and anchor

the same record, as link, embed, mention, target with a node reference

Which blob types' links propagate visibility is a rules table of three rows

which kinds carry access is a fixed property of the kind

Link extraction is hand-coded per blob type

content link extraction is declared by the Kind's link rules

The shipping tables are described in Database structure.

Open questions

    Open: whether embed should be retained with its source when the embedding document is pinned (so that a pinned page renders offline), as a policy option rather than a flag.

    Open: labels beyond CIDs, above.

See also

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

Unsubscribe anytime