F2 — Region-anchored threads (VS Code Comments API), git-native persistence #4

Closed
opened 2026-06-10 07:36:14 +00:00 by benstull · 1 comment
Owner

Summary

Region-anchored discussion threads in the editor: a human (and Claude, via
@cline/sdk) can attach a thread to a span of a document using VS Code's
native Comments API, the thread survives the document being edited (the
anchor re-resolves as text moves), and the thread is persisted git-natively
(no server) so it is durable and portable. First concrete coauthoring capability
on the POC skeleton (#2).

Problem / pain

The inner loop has nowhere to discuss a specific region. Claude for VS Code can
take a highlighted region as context but keeps no durable, anchored record;
once the buffer changes, any notion of "this comment was about that span" is
lost. Without anchored, persistent threads there is no substrate for coauthoring
deliberation in the editor.

Who feels it

A writer/engineer coauthoring prose or specs with Claude inside VS Code — one
human + one machine — who wants to leave and revisit region-scoped discussion that
doesn't evaporate on the next keystroke or reload.

Desired outcome / value

The editor gains a real, durable, region-anchored thread surface: select text →
start a thread → it shows in the Comments gutter, re-anchors as the document is
edited
, reloads from disk across sessions, and is stored as a git-native
artifact
. This is the first coauthoring rung and establishes the persistence +
anchoring model
that F3 (attribution) and F4 (propose/accept) reuse.

Acceptance — "done right"

  • A contributed command / gutter action creates a comment thread on the selected
    range
    via the VS Code Comments API; replies can be added.
  • The thread anchor survives edits: inserting/deleting text above or within the
    document keeps the thread on the same logical span (anchor re-resolution), within
    reasonable limits documented in the slice.
  • Threads persist git-natively and reload on reopen: closing and reopening
    the workspace restores threads at their anchors from the on-disk artifact (no
    server).
  • The persistence artifact is a plain, diffable, git-committable file (the
    exact format is the open design question below).
  • Unit tests cover the anchor-update logic and the persistence round-trip
    (serialize → reload → same anchors); E2E coverage of the Comments UI is a
    plan task where feasible in the Extension Development Host.
  • No attribution and no propose/accept yet — those are F3 / F4.

Scope / non-goals

In scope: region-anchored comment threads via the Comments API; anchor
re-resolution across edits; git-native persistence + reload of threads; the data
model for a thread (id, anchor, messages, author).

Out of scope (deferred): live human/Claude attribution of authored spans
(F3); propose/accept diff flow (F4); the final cross-rung persistence
format + round-trip to the Gitea substrate (F5 / #46); multi-file orchestration;
any server.

Assumptions · constraints · dependencies

  • Parent: #1 (the coauthoring Epic). Blocked by: #2 (the POC skeleton —
    done). Relates to: F5 (the shared git-native format) and #46 (Gitea rung).
  • Open design question (the fork): the git-native persistence shape — a
    .threads/ sidecar (JSON/YAML) vs. git notes vs. trailers — and the anchoring
    strategy (line/char offsets vs. content-fingerprint) are genuine design
    decisions that F3–F5 also depend on. Epic #1 defers the full Solution Design
    (git-native model, anchoring, attribution, where Claude runs) to a follow-on
    brainstorming session
    . This Feature either (a) consumes that reviewed Solution
    Design, or (b) makes a provisional format choice inline and flags it for
    revisiting at F5. Resolve which before planning.
  • Native primitive exists: VS Code Comments API (vscode.comments) provides the
    thread UI without bespoke rendering.

Source / signal

Epic #1 (coauthoring-plugin-on-cline) decomposition item F2; architecture
lineage ben.stull/rfc-app#48. Built on the POC skeleton delivered in #2
(session vscode-cowriting-plugin-0002).

Priority (WSJF)

Provisional: Value high (first real coauthoring capability + establishes the
persistence/anchoring model) · Time-criticality medium · Opportunity-
enablement
high (F3/F4 reuse it) ÷ Size medium → P1.

Decomposition (Feature → slice checklist)

  • Resolve the persistence-format + anchoring design (consume a Solution Design,
    or choose a provisional format and document it).
  • Thread data model (id, anchor, messages, author) + a CommentController.
  • Create-thread-on-selection command + reply support via the Comments API.
  • Anchor re-resolution as the document is edited (document-change tracking).
  • Git-native persistence: serialize on change, reload + re-anchor on open.
  • Unit tests (anchor update, persistence round-trip) + E2E where feasible.

Solution notes (optional — NOT a design)

The differentiated bits map onto native primitives: Comments API for the
thread UI, document-change events for anchor maintenance. Keep Claude/@cline/sdk
participation minimal here (a human can thread solo); richer agent participation
rides on F3/F4. The durable format is the one real design call — see the open
question above; don't bake a format silently.

<!-- Set the type/* label: type/feature --> ## Summary **Region-anchored discussion threads** in the editor: a human (and Claude, via `@cline/sdk`) can attach a **thread to a span of a document** using VS Code's native **Comments API**, the thread **survives the document being edited** (the anchor re-resolves as text moves), and the thread is **persisted git-natively** (no server) so it is durable and portable. First concrete coauthoring capability on the POC skeleton (#2). ## Problem / pain The inner loop has nowhere to *discuss* a specific region. Claude for VS Code can take a highlighted region as context but keeps **no durable, anchored record**; once the buffer changes, any notion of "this comment was about *that* span" is lost. Without anchored, persistent threads there is no substrate for coauthoring deliberation in the editor. ## Who feels it A writer/engineer **coauthoring prose or specs with Claude inside VS Code** — one human + one machine — who wants to leave and revisit region-scoped discussion that doesn't evaporate on the next keystroke or reload. ## Desired outcome / value The editor gains a **real, durable, region-anchored thread surface**: select text → start a thread → it shows in the Comments gutter, **re-anchors as the document is edited**, **reloads from disk** across sessions, and is stored as a **git-native artifact**. This is the first coauthoring rung and establishes the **persistence + anchoring model** that F3 (attribution) and F4 (propose/accept) reuse. ## Acceptance — "done right" - A contributed command / gutter action **creates a comment thread on the selected range** via the VS Code **Comments API**; replies can be added. - The thread **anchor survives edits**: inserting/deleting text above or within the document keeps the thread on the same logical span (anchor re-resolution), within reasonable limits documented in the slice. - Threads **persist git-natively** and **reload** on reopen: closing and reopening the workspace restores threads at their anchors from the on-disk artifact (no server). - The persistence artifact is a **plain, diffable, git-committable** file (the exact format is the open design question below). - **Unit tests** cover the anchor-update logic and the persistence round-trip (serialize → reload → same anchors); **E2E** coverage of the Comments UI is a plan task where feasible in the Extension Development Host. - No attribution and no propose/accept yet — those are F3 / F4. ## Scope / non-goals **In scope:** region-anchored comment threads via the Comments API; anchor re-resolution across edits; git-native persistence + reload of threads; the data model for a thread (id, anchor, messages, author). **Out of scope (deferred):** live human/Claude **attribution** of authored spans (F3); **propose/accept** diff flow (F4); the **final** cross-rung persistence format + round-trip to the Gitea substrate (F5 / #46); multi-file orchestration; any server. ## Assumptions · constraints · dependencies - **Parent:** #1 (the coauthoring Epic). **Blocked by:** #2 (the POC skeleton — done). **Relates to:** F5 (the shared git-native format) and #46 (Gitea rung). - **Open design question (the fork):** the git-native persistence shape — a `.threads/` sidecar (JSON/YAML) vs. git notes vs. trailers — and the anchoring strategy (line/char offsets vs. content-fingerprint) are genuine design decisions that F3–F5 also depend on. Epic #1 defers the full **Solution Design** (git-native model, anchoring, attribution, where Claude runs) to a **follow-on brainstorming session**. This Feature either (a) consumes that reviewed Solution Design, or (b) makes a **provisional** format choice inline and flags it for revisiting at F5. Resolve which before planning. - Native primitive exists: VS Code **Comments API** (`vscode.comments`) provides the thread UI without bespoke rendering. ## Source / signal Epic #1 (`coauthoring-plugin-on-cline`) decomposition item **F2**; architecture lineage `ben.stull/rfc-app#48`. Built on the POC skeleton delivered in #2 (session `vscode-cowriting-plugin-0002`). ## Priority (WSJF) Provisional: **Value** high (first real coauthoring capability + establishes the persistence/anchoring model) · **Time-criticality** medium · **Opportunity- enablement** high (F3/F4 reuse it) ÷ **Size** medium → **P1**. ## Decomposition (Feature → slice checklist) - [ ] Resolve the persistence-format + anchoring design (consume a Solution Design, or choose a provisional format and document it). - [ ] Thread data model (id, anchor, messages, author) + a `CommentController`. - [ ] Create-thread-on-selection command + reply support via the Comments API. - [ ] Anchor re-resolution as the document is edited (document-change tracking). - [ ] Git-native persistence: serialize on change, reload + re-anchor on open. - [ ] Unit tests (anchor update, persistence round-trip) + E2E where feasible. ## Solution notes (optional — NOT a design) The differentiated bits map onto native primitives: **Comments API** for the thread UI, document-change events for anchor maintenance. Keep Claude/`@cline/sdk` participation minimal here (a human can thread solo); richer agent participation rides on F3/F4. The durable format is the one real design call — see the open question above; don't bake a format silently.
benstull added the type/featurepriority/P1 labels 2026-06-10 07:36:14 +00:00
Author
Owner

Shipped to main in PR #5 (F2: region-anchored threads on @cline/sdk) — SLICE-1..5 complete (model/store, anchorer, ThreadController, reload/re-anchor/orphan logic, host E2E); unit + E2E suites green. The merge did not auto-close this (the PR referenced it as F2 (#4) without a closing keyword). Closing now.

Shipped to `main` in PR #5 (`F2: region-anchored threads on @cline/sdk`) — SLICE-1..5 complete (model/store, anchorer, ThreadController, reload/re-anchor/orphan logic, host E2E); unit + E2E suites green. The merge did not auto-close this (the PR referenced it as `F2 (#4)` without a closing keyword). Closing now.
Sign in to join this conversation.