spec(0062): baseline = clean checkpoint set on entry; only empty state is an empty doc (D13)

Entering coediting sets the baseline to current content automatically;
'Pin Review Baseline to Now' resets it ('everything so far is settled; show
changes from here'). A coedited doc always has a baseline -> removed the
'no/missing baseline' empty state entirely; the only empty state is a
genuinely empty document. Updated INV-7, PUC-1/7, baseline provider, preview
(marks since checkpoint), failure modes, flags, glossary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-28 07:13:22 -07:00
parent 1e54abdd8d
commit 4ccba9ea93
+38 -19
View File
@@ -215,7 +215,8 @@ with a machine coauthor, delivering the whole loop through the editor's own nati
review surfaces.**
The enabling idea: **model the coauthored document as a tiny source control.** The
point the writer last marked "good" (a **pinned baseline**) is the source-control
point the writer last marked "good" (the **baseline checkpoint**, set on entering
coediting and re-pinnable) is the source-control
*original*; the live document is the working tree; the machine's proposed edits are
*pending changes*. Once the relationship is framed as source control, the editor's
own machinery supplies the experience the writer needs — and it is machinery they
@@ -275,11 +276,12 @@ mutating the writer's document without explicit acceptance.
## 4. Product Use Cases
```gherkin
Scenario: PUC-1 — see the diff against the pinned baseline (realizes BUC-1)
Given I run "Pin Review Baseline to Now"
When I (or the machine) later change the document
Then the source-control gutter shows change bars against the baseline
Scenario: PUC-1 — see the diff against the baseline checkpoint (realizes BUC-1)
Given I am coediting a document (entering set the baseline to a clean checkpoint)
When I (or the machine) change the document
Then the source-control gutter shows change bars for what changed since the checkpoint
And "Open Changes" opens the native diff editor (baseline live), inline or side-by-side at my choice
And running "Pin Review Baseline to Now" resets the checkpoint to the current content (the diff goes clean)
```
```gherkin
@@ -331,6 +333,7 @@ Scenario: PUC-7 — enter (and leave) coediting mode (realizes INV-10)
Given an ordinary markdown document
When I run "Coedit this Document with Claude" (command, editor title, or context menu)
Then this document gains the Cowriting source-control entry, the annotation toggle, and machine-edit/comment-response behavior
And the baseline is set to the document's current content (a clean checkpoint)
And my other markdown documents are unaffected
And running "Stop editing with Claude" (context menu) removes those surfaces (the saved sidecar is kept for next time)
```
@@ -355,7 +358,9 @@ panel to wireframe. Described in text (source of truth):
command — in the same command palette **and the editor/explorer context menu**
reverses it. A subtle status-bar item ("✦ Coediting") indicates when the active
document is in coediting mode. Until a document is entered, **none** of the
surfaces below attach to it (INV-10).
surfaces below attach to it (INV-10). **Entering also sets the baseline to the
document's current content** — a clean checkpoint to measure future changes
against (INV-7).
- **Source Control gutter & viewlet.** A dedicated source-control entry,
*"Cowriting,"* coexists with Git. Its quick-diff provider draws the familiar
change bars in the editor gutter against the pinned baseline; its resource group
@@ -422,9 +427,15 @@ coauthoring **displaced** state surfaced in the thread / proposed-change listing
and the progress reducer are pure modules with no `vscode` import, unit-tested in
isolation; controllers are the only `vscode`-aware layer, so surfaces can change
without touching the logic.
- **INV-7 — baseline lives outside the repo:** the pinned baseline is the diff
*original* and is stored in extension global storage keyed by document URI hash,
so it never pollutes the repo and works for any file (including untitled).
- **INV-7 — baseline is the clean checkpoint, kept outside the repo:** the baseline
is the diff *original* — the last point the writer declared "clean." It is **set
automatically when a document enters coediting**, and **reset to the current
content by "Pin Review Baseline to Now"** (the "everything so far is settled; show
me changes from here" gesture). A coedited document therefore *always* has a
baseline — there is **no "missing baseline" state**; the only empty state is a
genuinely empty document. It is stored in extension global storage keyed by
document URI hash, so it never pollutes the repo and works for any file (incl.
untitled), and it is disposable review state, not durable metadata.
- **INV-8 — provenance carries on-behalf-of identity:** every authored span /
message records `provenance` (the human's git identity, or the machine acting
`onBehalfOf` a human), reused across attributions, proposed changes, and threads.
@@ -543,7 +554,10 @@ state (INV-7), not durable coauthoring metadata.
- **Baseline provider** — `TextDocumentContentProvider` for `cowriting-baseline:`;
`provideTextDocumentContent(uri) → baselineText`. `BaselineStore.pin(docUri, text,
reason)` / `get(docUri) → {text, reason} | null` (out-of-repo, INV-7).
reason)` / `get(docUri) → {text, reason} | null` (out-of-repo, INV-7). `pin` is
called **automatically on `enterCoediting`** (reason `entered`) and on the explicit
**"Pin Review Baseline to Now"** (reason `pinned`); a coedited document always has a
baseline, so `get` returns null only for documents that are not being coedited.
- **QuickDiffProvider** — `provideOriginalResource(docUri) → cowriting-baseline:` URI
(drives gutter bars). Registered on the "Cowriting" `SourceControl`.
- **Machine-edit seam** — the single boundary where machine text enters the model:
@@ -586,7 +600,7 @@ state (INV-7), not durable coauthoring metadata.
### 6.5 PerProduct-Use-Case design
#### PUC-1 — see the diff against the pinned baseline
#### PUC-1 — see the diff against the baseline checkpoint
```mermaid
sequenceDiagram
@@ -660,8 +674,8 @@ sequenceDiagram
- **Implementation:** a contributed `markdown-it` plugin runs the pure
`renderAnnotations` transform and a small preview stylesheet using the editor's
theme variables. Toggle via `cowriting.annotations`. No webview. Authorship
coloring + insert/delete marks; a freshly pinned, zero-diff document renders
clean.
coloring + insert/delete marks are shown for changes since the baseline checkpoint;
a freshly entered or freshly pinned, zero-diff document renders clean.
#### PUC-4 / PUC-6 — threads & re-anchoring
@@ -724,7 +738,8 @@ sequenceDiagram
on load/change — fine for human-scale documents; skip non-text/oversized files.
Native diff/preview rendering is the platform's, not ours.
- **Availability & resilience:** no service; the worst case is a displaced anchor
(handled, INV-1) or a missing baseline (degrade to "no diff yet").
(handled, INV-1); a baseline always exists once coediting is entered (INV-7), so
there is no missing-baseline path.
- **Observability:** the OutputChannel stream (PUC-5) is the user-facing turn log;
no telemetry service (a local extension — §9).
- **Accessibility:** inherited from the native surfaces — the diff editor,
@@ -773,13 +788,15 @@ sequenceDiagram
- **Displaced anchor** (INV-1) → shown displaced at last-known `lineHint`, never
moved → auto-re-anchors if the text reappears → no alert (local).
- **Missing baseline** → no QuickDiff original → degrade to "pin a baseline to see
changes"; no diff shown, no error.
- **Empty document** (genuinely no content) → the only true empty state → a gentle
"start writing, or ask Claude to draft something" affordance; not an error. A
coedited document always has a baseline (set on entry, INV-7), so there is **no
"missing baseline" state** to handle.
- **Multi-diff Keep/Undo API unavailable/changed** → fall back to per-hunk CodeLens
Keep/Reject in the diff editor (§6.10); the proposed-change *model* is unchanged.
- **Feature flags / settings:** `cowriting.annotations` (preview annotations on/off),
`cowriting.liveProgress.revealOutput`. The whole capability is additive — off by
absence of a pinned baseline / sidecar.
absence of coediting mode for the document (INV-10).
### 6.10 Migration & compatibility
@@ -925,11 +942,13 @@ a bug reaches us as a tracker issue.
| D10 | Comment trigger | While a document is in coediting mode, **every** new comment summons the machine (no per-comment gate); coediting mode is the control, "Stop editing with Claude" the off switch | 2026-06-27 |
| D11 | Authorship surface (Q5) | Option 1 — the annotated preview is the authorship view; native diff stays author-blind; in-editor decorations (opt 2) and an owned track-changes diff (opt 3) are out of scope | 2026-06-27 |
| 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 | Baseline = the clean checkpoint; set automatically on entering coediting and reset by "Pin Review Baseline to Now"; a coedited doc always has one. The only empty state is a genuinely empty document — no "missing baseline" state (INV-7) | 2026-06-27 |
## 14. Glossary & References
- **Pinned baseline** — the writer-chosen "good" snapshot used as the diff *original*;
stored out-of-repo, disposable (INV-7).
- **Baseline (checkpoint)** — the last point the writer declared "clean," used as the
diff *original*; set automatically when a document enters coediting and reset by
"Pin Review Baseline to Now"; stored out-of-repo, disposable (INV-7).
- **QuickDiffProvider** — the VS Code API that supplies gutter dirty-diff bars from a
virtual *original* document.
- **Multi-diff editor** — VS Code's native multi-change review surface; here the