Why review comments belong on the page, not in a spreadsheet
Every website review starts the same way. Someone sends a link, someone else opens it, and within a minute the feedback begins: a screenshot pasted into a chat, a sentence quoted in an email, a row added to a shared sheet with a column called "Where?". The person who wrote the page then spends the next hour matching each remark to the paragraph it was probably about.
The trouble is not that people give feedback badly. It is that the feedback loses its address the moment it leaves the page. "The second paragraph is unclear" was precise when it was said; by the time the paragraph has been edited twice and the section reordered, nobody can say which paragraph was meant, or whether the remark still applies.
Word processors solved this decades ago. You select a sentence, you leave a note, and the note stays attached to that sentence through every subsequent edit. Nobody proposes reviewing a contract by emailing a list of page numbers. Yet for the live web page, which is what the reader will actually see, the spreadsheet is still the default.
What an anchor has to survive
Attaching a comment to a live page is harder than attaching one to a document because the page is regenerated on every deploy. A naive approach stores a CSS selector, and the first time the template changes, every comment points at the wrong element or at nothing. The anchor has to be derived from the content itself, not from the structure around it.
The approach this widget takes is to fingerprint each commentable element by its tag, its position among siblings of the same tag, and a short hash of its text. A paragraph that is moved keeps its hash and can be found again. A paragraph that is edited loses its hash, and the widget falls back to a fuzzy match on the text it captured when the comment was written. Only when nothing plausible remains does the thread go into an "orphaned" tray, still readable, still closable, just no longer pinned.
A comment that cannot say what it was about is a comment that will be closed without being read. The context snapshot is not a nicety; it is the part that makes the thread actionable after the page has moved on.
That captured text, the context snapshot, is stored with the thread and shown to whoever works it off. It answers "what did the reviewer see?" without a screenshot and without checking out the commit from that afternoon.
Closing the loop without a meeting
A thread has three states. It starts as new. Whoever picks it up moves it to in review so that nobody else duplicates the work. When the fix is deployed it is closed, and the deploy version is stamped on the thread so that a reviewer who sees the change can trust it is the one that was meant.
The part that used to require a person is the walk through the open threads. With the threads exposed over MCP, an agent can do it: list the threads for a page, find each anchor in the source using the snapshot, make the change, reply with one line, and close the thread with the commit it shipped in. What the reviewer gets is a reply on the paragraph they commented on, not a status update in a channel they have muted.
- Reviewers never make an account; a link is enough, and revoking the link ends the round.
- The site owner decides which origins may load the widget, and can switch it off per site.
- Every write is rate limited and every owner action is audited, so a leaked link is an inconvenience, not an incident.
- Nothing about the page has to change except one script tag before the closing body tag.
None of this replaces a proper editorial pass. It replaces the spreadsheet: the column called "Where?", the screenshot that is out of date by the afternoon, and the reply that says "which paragraph did you mean?" If you are reading this with a review code, try it now: hover a paragraph, click the handle, and say what you would change.