Comments
Comments are signed snapshot blobs that target a document version, and this page covers their identity, edits and deletion, threads, block and range comments, citations, mentions, visibility and the open question of moderation.

Anyone with a key can comment on any Hypermedia document, from any node, without asking the document's owner. A comment is a small signed blob. It names the document and version it is about, carries a tree of blocks like a document body, and can reply to another comment. This page explains how comments are identified, edited, threaded and found.

The comment blob

A comment is a signed blob of type Comment. Each version of a comment is a whole snapshot. An edit publishes a new blob that replaces the old one. Documents work differently: they are built from a chain of Changes.

key

meaning

signer, ts, sig

the envelope every blob carries: who wrote it and when

space, path

the document it targets; space is omitted when it equals the signer

version

the CIDs of the document heads the author was looking at; empty means "the document at this path"

threadRoot

the CID of the first comment of the thread; present on every reply

replyParent

the CID of the comment this one replies to; omitted when it equals threadRoot

body

a list of comment blocks: a block plus its children, recursively

id

present only on an edit or a deletion: the TSID of the comment being replaced

visibility

"" for public, Private for private

capability

deprecated and ignored; old blobs may carry it

The daemon verifies the signature, then indexes the target as a link, the thread links, every link inside the body, and a full-text row per block. It does not check whether the signer may comment, because no such permission exists.

Identity, edits and deletion

A comment's stable identity is <author>/<tsid>. The author is the signer's principal. The TSID is a timestamped id: 10 bytes, a 48-bit millisecond timestamp followed by the first 4 bytes of the SHA-256 of the blob, encoded base58btc into 14 or 15 characters. The first version of a comment derives its TSID from its own bytes. An edit or a tombstone carries that TSID in its id field, so all versions share one identity while each has its own CID.

Among the blobs that share a TSID, the live version is the one with the greatest timestamp. On a tie, the blob the node stored last wins. A blob with an empty body is a tombstone. The comment is deleted, and listings stop showing it. The history is kept, and ListCommentVersions returns every version.

Because identity includes the signer, looking up a comment by <author>/<tsid>, or listing its versions, matches only blobs signed by that author. A blob from another key that carries the same TSID does not change what that address returns.

There are two ways to link to a comment. hm://<author>/<tsid> is the comment itself, whatever its current version. hm://c/<cid> is one specific version. On a site, a comment appears under its target as https://site/<path>/:comments/<author>/<tsid>. URLs has the full grammar.

Threads and discussions

A comment with no threadRoot starts a discussion. A reply names the discussion's first comment in threadRoot and the comment it answers in replyParent. When those are the same, replyParent is left out. A reply must carry threadRoot, or the daemon rejects it. When a reply arrives before its root or parent, the daemon stashes it and indexes it as soon as the missing comment lands. So out-of-order sync never loses a reply.

Clients group comments by thread. The Seed API's ListDiscussions returns each root with its replies, and the Comments embed view shows a document's discussion inside another document. Readers may show a thread as a tree or flattened by time. Both views read the same three fields.

Which version was commented on

A comment records the document version its author saw, and readers show it under that version. The daemon resolves the comment to the document's genesis Change through that version. So comment counts and the latest-comment pointer survive when a document is moved or republished. The path can change, but the genesis cannot. A comment whose version is empty attaches to whatever document currently lives at the path.

Block and range comments

To comment on one block, or on a selection inside it, a client wraps the comment body in an Embed block whose link is the target with a fragment: hm://<space>/<path>?v=<version>#<blockId> for a block, or #<blockId>[start:end] for a range of its text in Unicode code points. The version is pinned on purpose. A later edit could move the offsets, so the quote always shows the text the author selected. The comment's own text follows as the embed's children.

Because the quote is an ordinary link inside the body, the daemon indexes it like any other link. So a block comment shows up as a citation of that block. The InteractionSummary request reports per-block comment and citation counts that the app uses to mark commented blocks in the margin.

Citations and backlinks

Every hm:// link the daemon meets while indexing becomes a link record from the source blob to the target resource. The link can sit in a document block, an annotation, or a comment body. The record is, tagged with the source block, the fragment and the version. A pinned version marks the link as exact. A link that follows the latest marks its version as a suggested minimum. ListCitations on a target returns these records as citations, ordered by when the citing blob arrived locally. The order ignores the blob's claimed time, so a late-arriving old blob can never hide a newer citation on the next page. Four links from one version count as four citations.

The older ListEntityMentions call is deprecated. Use ListCitations.

Mentions

A mention is an inline embed: an Embed annotation over a placeholder character in a block's text, with mentionKind set to account or document and the link pointing at the person or the page. Documents and comments use the same mechanism, described in Blocks. The daemon indexes the mention as a link from the comment to the account. This link drives "mentions of me" and the mention trigger of a Seed Agent. The MentionCandidates request ranks who or what to suggest while you type.

Visibility

A comment carries its own visibility. By convention it copies its target's: clients set Private when commenting on a private document. A private comment is visible in two spaces, the author's and the target's. Over peer sync, the comment goes to peers authenticated as either account, as a WRITER in either space, or as either space's site server. On a public-only node, HTTP serves it only to the target space's owner and root-level writers, so that node may refuse the author. Its visibility passes on to the file blobs it links, such as attached images, and to nothing else. Private documents are still changing. Privacy has the current state.

No moderation yet

Nothing checks authorization on comments. Any key can publish a comment on any document, and a node that syncs the document syncs its comments. So no site owner can silence a reply on their own page. There is also no moderation. A site owner cannot hide or remove someone else's comment today, and comment spam has appeared on public sites. Removing or revoking comments is on the team's launch list and is not built as of September 2026. Until then there are two weak mitigations. A document can hide its activity panel with the showActivity metadata key. The web of trust described in Permissions is the planned long-term filter.

Working with comments

In the Seed app

Open a document's discussion from the comments panel, reply inside a thread, or select text and comment on it to create a range comment. Your own comments show edit and delete actions. The Seed app signs comments with your account key, or with a linked device key on a linked device.

CLI

seed-cli comment list hm://<space>/<path> # every comment on a document seed-cli comment discussions hm://<space>/<path> # grouped into threads seed-cli comment get <author>/<tsid> seed-cli comment create hm://<space>/<path> --body "Nice." --key mykey seed-cli comment create 'hm://<space>/<path>#<blockId>' --file reply.md # a block comment seed-cli comment create hm://<space>/<path> --reply <author>/<tsid> --body "Agreed." seed-cli comment edit <author>/<tsid> --body "Edited." seed-cli comment delete <author>/<tsid> # publishes a tombstone

Bodies are markdown, parsed into blocks with the same dialect documents use. See the CLI guide. A web URL of a comment page works wherever an id is accepted.

SDK

createComment, updateComment and deleteComment in the SDK build the signed blob on the client and return the blobs for client.publish. createComment takes the target id and version, optional replyCommentVersion and rootReplyCommentVersion, an optional quoting target with a block id and code-point range, and a visibility. The signing pattern is the one every blob uses: encode with the signature zeroed, sign, fill, encode. See the SDK guide.

Web API

request

what it returns

Comment

one comment by <author>/<tsid>

ListComments

every comment on a target, with the authors' metadata

ListDiscussions

the same comments grouped into threads, plus discussions on other documents that cite this one

ListCommentsByReference

comments elsewhere that quote or link this document

ListCommentsByAuthor, ListCommentVersions, GetCommentReplyCount

by author, edit history, reply count

ListCitations

every link record pointing at a resource

InteractionSummary

counts of comments, citations, changes and children, per document and per block

Publishing goes through PublishBlobs with a blob the SDK signed. The daemon's gRPC Comments service offers CreateComment, UpdateComment and DeleteComment signed with a key the daemon holds. The Seed API guide catalogues all of it.

Agents

The read verb accepts hm://<doc>/:comments for a whole discussion and hm://<author>/<tsid> for one comment with its thread, and returns a ready reply call. The write verb with options.action: "comment" posts a comment on a target, with replyTo for a reply. comment.update and comment.delete edit and tombstone. Seed Agents fire on document-comment and user-mention triggers, so mentioning an agent in a comment summons it. External agents use the CLI commands above. Building with agents covers keys and attribution.

Where this is going

As of September 2026 the open items are moderation (an owner revoking or hiding comments on their documents), human-friendly comment URLs under the target's namespace, reactions (designed, then put on hold), and notifications that treat an edit as an edit instead of a new comment. Roadmap collects the wider plans.

See also

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

Unsubscribe anytime