Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7.3 KiB
status
| status |
|---|
| draft |
Feasibility Spike Plan — Coediting Markdown with a Machine (native surfaces)
| Companion to | coauthoring-native-surfaces.md (Solution Design) — §7.1 rung 2 |
| Type | Throwaway discovery prototype (handbook §5.3) — code is disposable |
| Goal | Prove the API-dependent design assumptions on the real VS Code surfaces, cheaply, before the full build — so post-ship iteration is polish, not design |
| Non-goal | Production code, real Claude/SDK wiring (except E4), persistence durability, polish, breadth |
| Status | draft — in progress: E1/E3/E5 done, E2/E4 remain |
Status (2026-07-01, session 0063)
Three of the five experiments are built and passed in vscode-cowriting-prototype:
- E1 — PASS with pivot. VS Code does not render extension CodeLens inside
a diff editor; per-hunk CodeLens works in a normal editor, and tweak-then-Keep
attributes machine words vs. writer edits correctly. Folded back into the
Solution Design as D18 (the review surface is the live buffer itself,
in-buffer pending changes — see
coauthoring-native-surfaces.mdv0.2.0). - E3 — PASS. The
markdown-itcontribution renders author-colored marks + deletions in the built-in preview, theme-aware, with a working toggle. - E5 — PASS. Title-bar + status-bar entry points read as obvious without the Source Control pane.
- E2 (baseline router: QuickDiff vs git
HEAD+ snapshot) and E4 (comment → reply → offer → proposal) are not built yet — now the riskiest unvalidated assumptions and the spike's remaining work.
Why this exists
Static mockups validated the look and state coverage; they prove nothing
about whether VS Code's native surfaces actually behave as the spec assumes. Twice
already, an unexamined assumption would have forced a redesign (the diff can't
recolor per author; the Comments API can't render in the preview). The remaining
high-risk assumptions can only be settled by building on the real API. This spike
does exactly that and nothing more: each experiment returns a PASS / PASS-with-
fallback / FAIL, and any FAIL becomes a spec delta folded back into
coauthoring-native-surfaces.md before a plan is written.
Shape & guardrails
- One throwaway VS Code extension (
vscode-cowriting-prototype), run in the Extension Development Host. Delete it when the spike ends — none of this code graduates. - The machine is stubbed for E1–E3, E5 (a function returning canned
before/afteredits) so we test VS Code feasibility and feel, not the SDK. E4 may use a minimal real call only if cheap. - Time-box: ~2–3 focused days. If an experiment can't be made to PASS or PASS-with-fallback inside its slice, that is itself the finding — record it and move on.
- No persistence/durability work, no anchoring ladder, no cross-rung format — those are not API-risk; defer to the build.
Experiments (riskiest first)
E1 — Editable proposed side + Keep/Undo (highest risk)
- Assumption (INV-12, Q2, Q7): the machine's proposal can be reviewed in a multi-diff / diff editor whose proposed side is writable, the writer can tweak it before keeping, and per-change Keep/Undo works.
- Build: open a diff between a read-only baseline (
cowriting-baseline:virtual doc) and a writable proposal doc (untitled/in-memory) seeded with a canned edit; attach Keep/Reject actions (try the multi-diff overlay; fall back to per-hunk CodeLens). Edit the proposal side; on Keep, apply to the "live" doc and attribute machine-vs-tweak by diffing final ↔ canned ↔ baseline. - PASS: proposed side is editable; Keep applies the tweaked text; attribution splits correctly; live doc untouched until Keep.
- Decides: Q2 (stable ceiling vs CodeLens fallback), Q7 (Keep/Undo after free cross-hunk edits). If FAIL: the accept/reject surface design changes — know now.
E2 — Baseline router (git HEAD + snapshot)
- Assumption (INV-7): a
QuickDiffProvideragainst acowriting-baseline:doc shows gutter bars + "Open Changes"; the original resolves from gitHEADwhen tracked and from a snapshot otherwise; the diff goes clean on commit / Mark-Reviewed. - Build: register the provider; for a repo file read
HEADvia the Git extension API and recompute onrepository.state.onDidChange; for a~/Downloads/ untitled file use a stored/in-memory snapshot. Commit (git) and "Mark Changes as Reviewed" (snapshot) → confirm the diff clears. - PASS: both modes render the expected diff; both resets clear it; works for an untitled doc.
E3 — Preview authorship via markdown-it
- Assumption (PUC-3, D11): a contributed
markdown.markdownItPlugins/extendMarkdownItplugin injects per-span authorship colors + deletions into the built-in Markdown preview, toggled by a setting/command, with no custom webview. - Build: contribute the plugin; feed canned attributions/changes; render
green/blue + strikethrough; toggle
cowriting.annotationson/off. - PASS: marks render inside the native preview; toggle works; deletions show; scroll-sync intact. If FAIL: authorship-surface design changes.
E4 — Comment → reply → offer → proposal loop
- Assumption (PUC-8, D10): a Comments-API thread on a coedited doc can fire a turn,
post a machine reply
Comment, and convert an accepted offer into a pending proposal (E1's surface). Also: a preview selection → native thread on source via the markdown-it token.map(D15). - Build: create a thread on selection (and from a preview selection mapped to source); on add, run a stubbed-or-minimal turn; post a reply comment with an "Make this edit" action that opens an E1 proposal.
- PASS: reply appears in-thread; offer→proposal works; preview-initiated thread lands on the correct source range. (Feel/latency notes captured.)
E5 — Discoverability (title bar + status bar)
- Assumption (INV-13): the editor title-bar actions (
editor/titlemenus) and aStatusBarItem(✦ Coediting · N changes, click → review) are visible and obvious without the Source Control pane; everything gates oncowriting.isCoediting. - Build: contribute the menus + status-bar item gated on the context key; enter/exit coediting flips them.
- PASS: a first-time (non-git) user can find "review changes" without opening Source Control. (Cheapest experiment — fold into the others.)
Output
A short findings report (PASS / PASS-with-fallback / FAIL per experiment, with the
feel notes for E1/E4) and, for any non-PASS, a concrete spec delta applied to
coauthoring-native-surfaces.md — explicitly resolving open questions Q2, Q4, Q7.
Then the code is deleted and delivery moves to rung 3 (vertical slice).
Mapping to the design
| Experiment | Validates | Closes |
|---|---|---|
| E1 | INV-12 · editable proposals + Keep/Undo | Q2, Q7 |
| E2 | INV-7 · baseline router (HEAD + snapshot) | — |
| E3 | PUC-3 / D11 · preview authorship | — |
| E4 | PUC-8 / D10 / D15 · comment loop + preview-initiated thread | — |
| E5 | INV-13 · title-bar / status-bar discovery | — |
| (any FAIL needing a non-native surface) | INV-3 escape hatch | Q4 |