Comments and threads
Comments in VegaStack are anchored to a precise span of rendered text. Threads collect replies; resolution closes a discussion.
Anchors
When a reviewer selects text in the editor or in a public page view, VegaStack captures the selected text together with a small slice of surrounding context (prefix + suffix). The server also stores best-effort character offsets into the markdown body for the workspace editor selection path; the public-page bridge stores only the text fingerprint because rendered DOM offsets aren't stable.
Anchors are re-resolved every time the doc changes. The editor maps existing decoration positions through the ProseMirror transform cheaply on each keystroke, and runs a full text-fingerprint re-resolve in the idle callback. If neither the offset nor the unique-context match works, the thread renders as drifted in the comments sheet rather than disappearing.
One thread list per page
Comment threads are page-scoped — a single list per page, shared by the workspace editor and the public page view. There is no per-audience partition. Members see and write threads in the editor and comments sheet; guests see and write the same threads in the public page view when the page's effective public level is comment. A guest comment and a member comment land in the same thread list; author identity (member, guest, or agent) is carried on each comment, not on a separate thread type.
Visibility note. Because threads are unified per page, anything posted on a page that is publicly shared at the
commentlevel is visible to anyone who can view that page — including anonymous visitors — and member comments show the member's display name. Don't put internal-only discussion on a comment-public page. Guests are limited to reading and commenting (reply/resolve); deleting or otherwise editing threads remains member-only.
Threads
A thread is the root comment plus its replies, ordered by creation time. Replies inherit the anchor of the root.
Formatting
Comment bodies are markdown. The composer is a live WYSIWYG editor — type markdown syntax (**bold**, `code`, # heading, - list, > quote) and it styles inline as you type; there is no preview toggle. A compact toolbar (bold, italic, inline code, link, list) and the usual shortcuts (⌘B / ⌘I / ⌘K) are available, and ⌘+Enter sends.
The supported subset is inline emphasis, inline + fenced code, links, bullet/numbered/task lists, blockquotes, and headings (downscaled to fit the card). Raw HTML, tables, and images are intentionally not rendered. Bodies are stored as markdown and rendered to sanitized HTML at display time — the same for comments written by people and by agents over MCP, so agent replies render with full formatting.
Editing
The author of a reply can edit it in place (hover the reply, click the pencil). Edits keep the same markdown round-trip and mark the reply as edited. Agent and guest replies are not editable through this path.
Link to a comment
Each thread's actions include Copy link to comment (next to the resolve checkmark, revealed on hover). The link carries ?comment=<threadId>; opening it expands and scrolls to that thread on the page.
States
- Open — needs attention.
- Resolved — closed; collapsed by default in the comments rail.
- Awaiting — open and visible to a watching agent through
wait_for_review.
Mutations
create_commentopens a new thread (or appends a reply ifthread_idis passed).update_threadflips state (resolve/reopen/complete) and optionally moves the anchor.delete_threadremoves a thread the actor authored, or that an admin authored.
Live indicator
The comments slide-over shows a numeric badge that increments whenever a review_event fires for the current page. The badge resets when the slide-over opens.
Markdown export with comments
The page action bar's "Export Markdown with comments" option emits a Markdown file with inline footnote references placed immediately after each open thread's anchored text. Footnote definitions are appended at the end of the document. Threads whose anchors no longer match a unique location in the source land in an "Unanchored comments" section so nothing is silently dropped. The on-disk source is never mutated by export — the rewritten markdown is download-only.
Agent etiquette
Agents writing through MCP should resolve threads they were waiting on once their change has been applied. The audit log records the actor, so reviewers can see when an agent closed a discussion versus when a human did.