spec(0062): pin only in snapshot mode (resolve Q8/D14); pre-session changes attributed to writer (INV-8)

- D14: 'Pin Review Baseline to Now' exists only in snapshot mode (no committed
  HEAD); git-tracked files have no manual pin -> commit is the reset; pin
  command when-gated on cowriting.baselineMode==snapshot. Removed open Q8.
- INV-8: changes already present at coediting start (uncommitted vs HEAD,
  incl. edits made outside this experience) are attributed to the writer
  (human) -- session can't know their origin; surfaces prior work as human.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-28 07:21:03 -07:00
parent 61755cafd7
commit 22393f0d63
+19 -10
View File
@@ -284,7 +284,7 @@ Scenario: PUC-1 — see the diff against the baseline checkpoint (realizes BUC-1
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 committing the file (when it's in a git repo) advances the baseline to the new commit (the diff goes clean)
And running "Pin Review Baseline to Now" resets the checkpoint to the current content (works anywhere, incl. ~/Downloads and untitled)
And "Pin Review Baseline to Now" is offered only when the file has no commit to anchor to (outside a repo, untitled, or not-yet-committed), and resets the checkpoint there
```
```gherkin
@@ -337,6 +337,7 @@ Scenario: PUC-7 — enter (and leave) coediting mode (realizes INV-10)
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 established the last commit if the file is in git, otherwise a snapshot of the current content
And any uncommitted changes already in a git-tracked file appear as my (human) changes since the baseline
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)
```
@@ -438,15 +439,22 @@ coauthoring **displaced** state surfaced in the thread / proposed-change listing
anchor to** (outside any repo, untracked/ignored, brand-new, or untitled), the
baseline is a **snapshot** defaulted to the current content on entry and reset by
**"Pin Review Baseline to Now,"** stored in extension global storage keyed by URI
hash (in-memory for untitled). A manual pin is available in **both** homes as a
finer checkpoint (in a git file it sits ahead of `HEAD` until the next commit
supersedes it); a new in-repo file flips from snapshot to `HEAD`-tracking on its
first commit. A coedited document therefore *always* has a baseline — there is
hash (in-memory for untitled). **"Pin Review Baseline to Now" exists only in
snapshot mode** (files with no committed `HEAD` to anchor to) — for git-tracked
files there is no manual pin; the writer **commits** and the baseline follows
`HEAD`. A new in-repo file is in snapshot mode until its first commit, then flips to
`HEAD`-tracking (and the pin command disappears). A coedited document therefore *always* has a baseline — there is
**no "missing baseline" state**; the only empty state is a genuinely empty
document. The baseline is disposable review state, never committed by us.
- **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.
Changes **already present when a coediting session starts** (uncommitted work vs.
`HEAD`, *including* edits made outside this experience — by hand or by a machine
elsewhere) carry no prior provenance record, so they are **attributed to the writer
(human)**: the session cannot know their origin and treats them as the writer's
existing work. (In snapshot mode the baseline is the content at entry, so there is
nothing pre-existing to attribute.)
- **INV-9 — machine turns are observable and cancellable:** a turn streams progress
and honors an `AbortSignal`; the progress reducer is pure.
- **INV-10 — coediting is opt-in per document:** every coauthoring surface (the
@@ -567,10 +575,10 @@ state (INV-7), not durable coauthoring metadata.
`repository.state.onDidChange`); **otherwise → a stored snapshot**
(`BaselineStore.snapshot(docUri, text, reason)` / `get(docUri)`), set on
`enterCoediting` (reason `entered`) and on **"Pin Review Baseline to Now"** (reason
`pinned`). A pin in a git-tracked file records a snapshot that takes precedence over
`HEAD` until the next commit supersedes it (baseline = most-recent settle). This
mirrors the in-repo/out-of-repo `SidecarRouter` (§6.2). A coedited document always
resolves a baseline; non-coedited documents resolve none.
`pinned`). The **pin command is gated to snapshot mode** — hidden/disabled for
`HEAD`-anchored files (`when: cowriting.baselineMode == snapshot`), where committing
is the reset. This mirrors the in-repo/out-of-repo `SidecarRouter` (§6.2). A coedited
document always resolves a baseline; non-coedited documents resolve none.
- **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:
@@ -956,7 +964,8 @@ 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 & 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 + re-pinnable (global storage / in-memory). A manual pin works in both; a coedited doc always has a baseline; the only empty state is a genuinely empty document (INV-7) | 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) | "Pin Review Baseline to Now" 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 |
## 14. Glossary & References