Skip to content

Latest commit

 

History

History
112 lines (88 loc) · 4.35 KB

File metadata and controls

112 lines (88 loc) · 4.35 KB

Comment format — sidecar-only content anchors

Comments live inside the Markdown file in one invisible HTML-comment sidecar. There are no inline markers around the selected text. This keeps the document portable, produces no visible output in other CommonMark renderers, and lets ordinary editors and agents preserve or inspect the discussion.

On-disk format

<!--mkdn-comments
{
  "comments" : [
    {
      "body" : "needs a citation",
      "id" : "k7",
      "norm" : 1,
      "prefix" : "The ",
      "quote" : "quick brown fox",
      "start" : 4,
      "end" : 19,
      "suffix" : " jumps."
    }
  ],
  "v" : 1
}
-->

Each entry contains:

  • id and body — the stable comment identity and message.
  • author — optional; absent means the document owner, shown as “You.”
  • replies — an optional thread in conversation order. Each reply has its own id, optional author, and body.
  • quote — the exact selected text in mkdn's normalized rendered-text tape.
  • prefix and suffix — short surrounding context used to disambiguate the quote.
  • start and end — position hints in that same tape.
  • norm — the tape-normalization version used to capture those fields.

The JSON escapes content that could terminate or invalidate the HTML comment, so bodies, replies, and selectors round-trip arbitrary text safely.

Placement

Ordinary documents keep the sidecar at the end of the file. A valid sidecar is recognized only when whitespace and complete HTML comments follow it.

Autobahn backlogs keep the sidecar immediately before the first level-two lane heading. That makes the discussion document metadata instead of part of the last card, so a server or editor can move card blocks without carrying the sidecar along. A legacy trailing Autobahn sidecar is still read and migrates to the protected position the next time comments are changed.

Malformed or mid-document lookalikes are left as ordinary Markdown. Rendering also strips legacy <mkdn-comment .../> tokens written by older mkdn builds, but current builds never create inline tokens.

Anchoring

mkdn renders the document into a normalized text tape shared by comment capture and resolution. A new comment records the selected quote, nearby context, and a position hint from that tape.

On reload, resolution is deliberately conservative:

  1. Find exact quote matches in the normalized rendered text.
  2. Use prefix and suffix context to narrow repeated matches.
  3. Use the saved position only to break a remaining tie.
  4. If the match is still ambiguous or missing, leave the comment detached.

There is no fuzzy matching. A detached comment remains available instead of silently highlighting the wrong text. Because anchors use rendered content, normal Markdown source edits such as changing link syntax can preserve a comment when the visible text remains the same.

Authoring and persistence

A selection must map to a non-empty range in the normalized rendered tape. Synthetic or excluded output that cannot be mapped safely is not commentable. Comments auto-persist independently of the editor's unsaved prose draft.

When a comment, reply, or deletion is written, mkdn reloads the latest file, updates only the sidecar, and preserves the latest Markdown body. In an Autobahn card detail view, the card-local selection is translated into the owning backlog's document-wide tape before its selector is stored.

Agent access — mkdn comments

The CLI is the canonical headless interface:

mkdn comments list <file>
mkdn comments reply <file> <id> <body> --author <name>
mkdn comments wait <file> [--timeout <seconds>]

list prints comments and threads as JSON. reply requires an author so agent messages remain attributable. wait exits as soon as a new comment or reply is written, or returns a nonzero status at its timeout. The app's file watcher notices CLI and editor writes, including atomic replacement saves.

Limitations

  • Resolution is exact and intentionally declines ambiguous matches.
  • A selection must correspond to anchorable rendered text; not every synthetic or cross-block visual selection can be represented safely.
  • A sidecar moved to an unsupported location is left untouched rather than guessed to be metadata.
  • An unclosed code fence at the end of a malformed document can make a sidecar-shaped block positionally indistinguishable from real metadata.