docs / beta
Margin notesbeta
Comment on any local Markdown document the way you'd comment on a pull request — except the comments live in the file itself, as plain HTML comments that stay out of the rendered page. Built for one loop in particular: an agent writes you a document, you read it in PullMark leaving notes as you go, then hand the file back with "address the notes and delete them as you're done." The agents page walks that whole loop, screenshots and all.
Using them in PullMark
Reading this on the Mac where PullMark (0.28.1+) is installed? Jump straight to the margin-notes switch.
- They're on by default — margin notes are a beta experimental feature that ships enabled (since 0.35). The first time you reach for one — the hover bubble, ⌥⌘M, or Edit / Delete on a note someone left you — PullMark introduces the feature: what notes are, a copy button for teaching your agent, and a Turn Off button if it's not for you. The switch lives in Settings → Experimental and gates only the authoring tools; a document that already contains notes shows its bubbles either way (read-only), so a file annotated by a teammate or an agent never renders as silently empty.
- Add a note — hover any block in a local document and click the bubble in the margin (the same gesture as commenting on a PR). Inside a list the bubble targets the item you're pointing at, and inside a table the row — a subtle tint shows exactly what the note will attach to. Select text first and the note opens with the selection quoted — how you point at a sentence instead of a paragraph. ⌥⌘M notes the block you're reading; Edit → File Margin Note… leaves a note about the whole document, at the top.
- Write Markdown — bold, code spans, fenced code, links, lists; ⌘↩ saves. Each save is one edit in the file (undo with File → Revert Last Edit).
- Edit / Delete — hover a note bubble for its actions. Deleting a note is how it gets resolved: no state, no archive — an addressed note is an absent note.
- The chip — Open Files rows show a comment-count chip while a document still carries notes. It's live: as an agent works through the file deleting notes, the count falls and the bubbles disappear in front of you.
- Everywhere else — notes render read-only in browsed GitHub files, never appear in print, PDF/HTML export, or Quick Look, and View → Hide Margin Notes clears the page when you want to read clean.
- Your signature — notes are signed
@your-github-loginby default; change it under the feature's own switch in Settings → Experimental.
The format
A margin note is an HTML comment with a note keyword
and an author tag, placed on its own line after the block it's about:
Requests retry three times with exponential backoff.
<!-- note @josh: Section 2 says five times. Which is it? -->
A note about one list item lives inside the item — indented to the item's content, packed tight, so the list stays whole:
- First point
<!-- note @josh: too vague — name the metric -->
- Second point
Longer notes put the closing marker on its own line; the body is full Markdown, blank lines and fenced code included:
<!-- note @josh:
This contradicts the design doc. Either reconcile them or
drop this section.
```suggestion
Requests retry five times with exponential backoff.
```
-->
The complete grammar:
| Rule | Detail |
|---|---|
| Marker | <!-- note @ begins a note; ordinary
HTML comments (lint directives, TODOs) are left alone. |
| Author | Everything between @ and the
first colon. Spaces allowed; short handles read best. |
| Body | Markdown, from the colon to --> —
same line for short notes, following lines for long ones. |
| Escaping | A literal --> inside a body is
written --\> (the only reserved sequence; PullMark
escapes and unescapes it for you). |
| Placement | On its own line, blank lines around it, directly after the block it annotates. Above the first heading = a note about the whole document. |
| List items | A note about one list item sits inside the item: directly after the item's last line, indented to the item's content (at most 3 spaces — deeper reads as code), with no blank lines around it. The indentation is what ties it to the item. |
| Threads | Adjacent notes under the same block read as a conversation — reply by adding another note below. |
| Reserved | @name (attrs): — the
parenthesized slot is reserved for future use and preserved
verbatim; nothing writes or reads it today. |
| Code blocks | A note-shaped comment inside a fenced code block is code, not a note. |
Because Markdown renderers skip HTML comments, a file with notes in it renders clean on GitHub, in editors, and in any other tool — the notes ride along in the source without cluttering the page. PullMark is the pretty client for a format that works everywhere.
For agents
The handoff is zero-protocol: agents read files, and the notes are
in the file, physically adjacent to the text they're about. Paste
this into your CLAUDE.md / AGENTS.md —
Settings → Experimental has a Copy button with the same
text (or just say it):
## Margin notes
Markdown files may contain review notes as HTML comments:
`<!-- note @name: comment -->` (possibly multi-line, closing
with `-->` on its own line). Each note sits directly after the
passage it's about; a note above the first heading is about the
whole document. `--\>` inside a note means a literal `-->`.
When asked to address notes: work through each one, apply or
answer it, and DELETE the note (with its surrounding blank line)
once addressed. To reply or ask instead, leave your own note in
the same format below the original, signed with your own @name.
Don't add notes to code examples inside fenced blocks.
A note about one list item sits inside that item — directly after
the item's last line, indented to the item's content, with no
blank lines around it. Keep (or delete) the whole indented
comment; its indentation is what ties it to the item.
The convergence loop follows from the format: remaining bubbles
are remaining work, and an empty file is a finished review. If notes
must never reach a pull request, a CI check is one line —
grep -rn '<!-- note @' docs/ && exit 1.
Why it's beta
The mechanics have proven themselves — the format hasn't needed an incompatible change since it shipped, which is why it graduated out of alpha. Per the beta contract, we now make a real effort to keep the grammar and behavior compatible between versions, and the feature is likely to graduate fully. What's still settling is the surface around it: names, affordances, and how far the workflow generalizes beyond the agent-review loop it was designed in. Release notes will say exactly what changed if anything does. Feedback welcome.