spec(0062): comment from the preview (native thread on source) + whole-document comment (D15)

Verified the Comments API can't render in the markdown preview (webview).
So: preview *initiates* a comment (selection -> source range via markdown-it
token source map) and shows a deep-linking marker, but the thread renders
natively in the gutter/Comments panel; no bespoke in-webview comment UI
(keeps INV-3). Whole-document comment anchors at line 0 -> full-document
context for the machine. Updated PUC-4/8, UX, ThreadController contract,
decisions; D15.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-28 07:40:35 -07:00
parent 1d27b74a2b
commit 92df8c551f
+24 -5
View File
@@ -309,9 +309,11 @@ Scenario: PUC-3 — read the annotated rendered preview (realizes BUC-3)
```gherkin
Scenario: PUC-4 — region thread (realizes BUC-3a)
Given I select a passage and add a coauthoring thread
Given I select a passage in the editor or in the rendered preview and add a coauthoring thread
And I can also attach a comment to the whole document (anchored at its top) for a global remark
When I edit around it or reopen the document
Then the thread re-anchors; if it cannot be confidently placed it is shown displaced, never silently moved
And a thread started from the preview is created natively on the source (the preview shows a 💬 marker that deep-links to it)
```
```gherkin
@@ -345,8 +347,9 @@ Scenario: PUC-7 — enter (and leave) coediting mode (realizes INV-10)
```gherkin
Scenario: PUC-8 — comment summons a machine reply + offer to edit (realizes BUC-5)
Given I am coediting this document
When I add a comment on a passage (native Comments gutter)
When I add a comment on a passage (editor or preview selection) or on the whole document
Then a machine turn runs (with live progress, PUC-5) and replies in the thread
And a passage comment gives the machine that passage as context; a whole-document comment gives it the full document
And it offers to make the change; accepting opens its edit as a pending proposed change (PUC-2)
And on a document I am not coediting, adding a comment summons nothing
```
@@ -381,7 +384,13 @@ panel to wireframe. Described in text (source of truth):
- **Comments gutter.** Region threads via the native Comments API (create on
selection, reply, resolve). On a coedited document, the machine replies in-thread
and offers an edit (BUC-5 / PUC-8); the offer, when accepted, becomes a pending
proposed change reviewed in the multi-diff.
proposed change reviewed in the multi-diff. A comment can be **started from the
rendered preview** (select text there → "Comment on this"): the selection is mapped
back to the source range and a **native** thread is created — the preview shows a
💬 marker that deep-links to it, but the thread itself renders in the gutter /
Comments panel, never inside the webview (the Comments API can't render into a
webview — §6.7). A **whole-document** comment (anchored at the top) carries the
entire document as context.
- **Notification + OutputChannel.** Live machine progress, with a Cancel action.
### 5.1 Design tooling decision
@@ -617,7 +626,12 @@ state (INV-7), not durable coauthoring metadata.
the thread** and, when the remark implies a change, **offer an edit**; an accepted
offer routes through the machine-edit seam to a **pending** proposed change
(INV-5) — the comment never edits the document directly. The reply is posted as a
machine `Comment` carrying `onBehalfOf` provenance (INV-8).
machine `Comment` carrying `onBehalfOf` provenance (INV-8). Threads can be created
from an **editor selection**, a **preview selection** (mapped to the source range
via the `markdown-it` token source map — the preview shows a deep-linking 💬 marker
but cannot host the thread; the Comments API renders only in the gutter + Comments
panel), or on the **whole document** (anchored at line 0, full-document context).
All threads are native — the preview never hosts comment UI (INV-3).
### 6.5 PerProduct-Use-Case design
@@ -740,7 +754,10 @@ sequenceDiagram
offer never edits the document directly, only proposes (INV-5). **While the
document is in coediting mode, every new comment fires a turn (D10)** — the opt-in
mode is the control, so there is no per-comment gate; "Stop editing with Claude"
is the off switch.
is the off switch. A comment may originate at an **editor selection**, a **preview
selection** (mapped to the source range via the `markdown-it` token source map), or
the **whole document** (top-anchored); the machine receives the passage — or the
full document — as context accordingly.
#### PUC-5 — live machine progress
@@ -783,6 +800,7 @@ sequenceDiagram
| Coediting activation | opt-in per document via "Coedit this Document with Claude"; every surface gated on the active coediting set (INV-10) | always-on for all markdown; opt-in per workspace/folder | Per-document opt-in is the only grain that avoids hijacking Comments/SCM/preview for the writer's other files while keeping single-file precision |
| Authorship in the diff | the native diff is **author-blind** (what changed); authorship is shown in the preview, optionally a decoration track-changes editor (INV-11) | recolor machine changes inside the native diff editor | **Not possible:** `diffEditor.*` colors are global theme tokens with no per-author scoping; `inlineEdit.*`/chat tokens differentiate accept-state not author; decorations over the diff pane composite over green/red and are unreliable (vanish on tab-switch). Verified against the VS Code API (§13-Q5) |
| Comment → machine response | on a coedited doc, a comment fires a turn that replies + offers an edit → pending proposal | comment is inert (human-only threads) | Turns the familiar review-comment gesture into a coediting action without a new surface; the opt-in gate (INV-10) keeps it from firing on other docs |
| Comments & the preview | comments are **native** (source gutter + Comments panel); the preview can *initiate* a comment (selection → source range via the `markdown-it` source map) and show a deep-linking 💬 marker, but cannot **host** the thread (it's a webview — verified) | render a bespoke comment widget inside the preview webview | Keeps comments on the native surface (no INV-3 exception, keeps the Comments panel + gutter); the writer can still comment on what they're reading and add whole-document comments (top-anchored) |
| Scope | design-only north star (no packaging/migration commitment) | commit a packaging + delivery sequence now | Keeps the architecture decision separate from the delivery decision (§2, §7.1) |
### 6.8 Testing strategy
@@ -966,6 +984,7 @@ a bug reaches us as a tracker issue.
| D12 | Editable proposals | The review's proposed side is writable; the writer tweaks before Keep; machine words vs. writer tweaks are attributed at Keep (INV-12); live doc untouched until Keep (INV-5) | 2026-06-27 |
| D13 | Baseline semantics & source | Baseline = the last settled version. Its **source follows the file's home**: git `HEAD` where tracked (auto-resets on commit, storage-free), else a snapshot set on entry (global storage / in-memory). A coedited doc always has a baseline; the only empty state is a genuinely empty document (INV-7) | 2026-06-27 |
| D14 | Pin is the non-git fallback only (resolves Q8) | "Mark Changes as Reviewed" exists **only in snapshot mode** (no committed `HEAD`); git-tracked files have no manual pin — the writer **commits** and the baseline follows `HEAD`. The pin command is `when`-gated on `cowriting.baselineMode == snapshot` | 2026-06-27 |
| D15 | Comments & the preview | Native comment threads can't render in the preview (it's a webview — verified). The preview *initiates* a comment (selection → source range via the `markdown-it` source map) and shows deep-linking 💬 markers; a whole-document comment anchors at the top. Threads stay native (gutter + Comments panel); no bespoke in-webview comment UI | 2026-06-27 |
## 14. Glossary & References